na.y 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /* NCR53c8xx assembler */
  2. %{
  3. #include <u.h>
  4. #include <libc.h>
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include "na.h"
  8. #define COND_WAIT (1L << 16)
  9. #define COND_TRUE (1L << 19)
  10. #define COND_INTFLY (1L << 20)
  11. #define COND_CARRY (1L << 21)
  12. #define COND_REL (1L << 23)
  13. #define COND_PHASE (1L << 17)
  14. #define COND_DATA (1L << 18)
  15. #define IO_REL (1L << 26)
  16. #define MOVE_MODE (1L << 27)
  17. int yylex(void);
  18. int yyparse(void);
  19. void assemble(void);
  20. void yyerror(char *, ...);
  21. void yywarn(char *, ...);
  22. void p2error(int line, char *);
  23. struct addr {
  24. int type; /* 0 - direct, 1 - indirect 2 - table indirect */
  25. unsigned long offset;
  26. };
  27. typedef enum Type { Const, Addr, Table, Extern, Reg, Unknown, Error } Type;
  28. struct sym {
  29. char *name;
  30. int set;
  31. Type t;
  32. long value;
  33. struct sym *next;
  34. };
  35. struct sym *findsym(char *name);
  36. struct sym *symlist;
  37. void newsym(struct sym *s, Type t, long v);
  38. struct binary {
  39. char len;
  40. unsigned long data[3];
  41. unsigned char patch[3];
  42. };
  43. #define MAXCPPOPTS 30
  44. #define MAX_PATCHES 1000
  45. struct na_patch patch[MAX_PATCHES];
  46. int patches;
  47. struct binary out;
  48. struct expval {
  49. Type t;
  50. long value;
  51. };
  52. struct expval eval(struct expval a, struct expval b, char op);
  53. int patchtype(Type t);
  54. void fixup(void);
  55. unsigned dot;
  56. unsigned externs;
  57. int errors, warnings;
  58. struct sym *externp[100];
  59. void regmove(unsigned char src_reg, unsigned char op,
  60. unsigned char dst_reg, struct expval *imm);
  61. void preprocess(char *in, FILE *out);
  62. int mk24bitssigned(long *l);
  63. long mkreladdr(long value, int len);
  64. long chkreladdr(int d, struct expval *e, int len, long relrv);
  65. int pass2;
  66. FILE *in_f;
  67. int yyline = 0;
  68. char yyfilename[200];
  69. char line[500];
  70. char *cppopts[MAXCPPOPTS];
  71. int ncppopts;
  72. int wflag;
  73. %}
  74. %union {
  75. long n;
  76. struct sym *s;
  77. struct expval e;
  78. }
  79. %token NUM MOVE WHEN SYMBOL SELECT WAIT DISCONNECT RESELECT SET CLEAR
  80. %token DATA_OUT DATA_IN COMMAND STATUS RESERVED_OUT RESERVED_IN MESSAGE_OUT
  81. %token MESSAGE_IN WITH ATN FAIL CARRY TARGET ACK COMMENT TO
  82. %token SCNTL0 SCNTL1 SCNTL2 SCNTL3 SCID SXFER SDID GPREG
  83. %token SFBR SOCL SSID SBCL DSTAT SSTAT0 SSTAT1 SSTAT2
  84. %token ISTAT CTEST0 CTEST1 CTEST2 CTEST3 TEMP DFIFO CTEST4 CTEST5 CTEST6
  85. %token DBC DCMD DNAD DSP DSPS DMODE DIEN DWT DCNTL ADDER
  86. %token SIEN0 SIEN1 SIST0 SIST1 SLPAR MACNTL GPCNTL STIME0 STIME1 RESPID
  87. %token STEST0 STEST1 STEST2 STEST3 SIDL SODL SBDL
  88. %token SHL SHR AND OR XOR ADD ADDC
  89. %token JUMP CALL RETURN INT INTFLY NOT ABSOLUTE MASK IF REL PTR
  90. %token TABLE FROM MEMORY NOP EXTERN
  91. %token SCRATCHA0 SCRATCHA1 SCRATCHA2 SCRATCHA3
  92. %token SCRATCHB0 SCRATCHB1 SCRATCHB2 SCRATCHB3
  93. %token SCRATCHC0 SCRATCHC1 SCRATCHC2 SCRATCHC3
  94. %token DSA0 DSA1 DSA2 DSA3
  95. %token DEFW
  96. %left '-' '+'
  97. %left '*' '/'
  98. %left NEG /* negation--unary minus */
  99. %right '^' /* exponentiation */
  100. %type <n> NUM phase .atn set_list set_bit regA reg
  101. %type <n> set_cmd .cond condsfbr condphase
  102. %type <n> jump_or_call .ptr
  103. %type <s> SYMBOL
  104. %type <e> exp byteexp regexp
  105. /* Grammar follows */
  106. %%
  107. input: /* empty string */
  108. | input line
  109. ;
  110. line: .label .opcode .comment '\n'
  111. {
  112. if (pass2) {
  113. int x;
  114. for (x = 0; x < out.len; x++) {
  115. printf("/* %.4x */ 0x%.8lxL,",
  116. dot, out.data[x]);
  117. if (x == 0) {
  118. printf(" /*\t");
  119. fwrite(line,
  120. strlen(line) - 1, 1, stdout);
  121. printf(" */");
  122. }
  123. printf("\n");
  124. if (out.patch[x]) {
  125. patch[patches].lwoff = dot / 4;
  126. patch[patches].type = out.patch[x];
  127. patches++;
  128. }
  129. dot += 4;
  130. }
  131. }
  132. else
  133. dot += 4 * out.len;
  134. }
  135. | ABSOLUTE SYMBOL '=' exp .comment '\n'
  136. {
  137. setsym($2, $4.t, $4.value);
  138. if (pass2) {
  139. printf("\t\t\t/*\t");
  140. fwrite(line, strlen(line) - 1, 1, stdout);
  141. printf(" */\n");
  142. }
  143. }
  144. | SYMBOL '=' exp .comment '\n'
  145. {
  146. setsym($1, $3.t, $3.value);
  147. if (pass2) {
  148. printf("\t\t\t/*\t");
  149. fwrite(line, strlen(line) - 1, 1, stdout);
  150. printf(" */\n");
  151. }
  152. }
  153. | EXTERN SYMBOL {
  154. if (pass2) {
  155. printf("\t\t\t/*\t");
  156. fwrite(line, strlen(line) - 1, 1, stdout);
  157. printf(" */\n");
  158. }
  159. else {
  160. if (!pass2)
  161. externp[externs] = $2;
  162. setsym($2, Extern, externs++);
  163. }
  164. }
  165. ;
  166. .comment: COMMENT
  167. | /* nothing */
  168. ;
  169. .label: SYMBOL ':' {
  170. if ($1->t != Unknown)
  171. {
  172. if (!pass2)
  173. yyerror("multiply defined symbol");
  174. }
  175. else {
  176. $1->t = Addr;
  177. $1->value = dot;
  178. }
  179. }
  180. | /* nothing */
  181. ;
  182. set_cmd: SET { $$ = 3; }
  183. | CLEAR { $$ = 4; }
  184. ;
  185. set_bit: CARRY { $$ = 0x400; }
  186. | TARGET { $$ = 0x200; }
  187. | ACK { $$ = 0x40; }
  188. | ATN { $$ = 0x8; }
  189. ;
  190. set_list: set_list ',' set_bit { $$ = $1 | $3; }
  191. | set_list AND set_bit { $$ = $1 | $3; }
  192. | set_bit { $$ = $1; }
  193. ;
  194. opcode: set_cmd set_list {
  195. out.len = 2;
  196. out.data[0] = (1L << 30) | ((long)$1 << 27) | $2;
  197. out.data[1] = 0;
  198. out.patch[0] = out.patch[1] = 0;
  199. }
  200. | DISCONNECT
  201. {
  202. out.len = 2;
  203. out.data[0] = 0x48020000L;
  204. out.data[1] = 0;
  205. out.patch[0] = out.patch[1] = 0;
  206. }
  207. | INT exp .cond {
  208. out.len = 2;
  209. out.data[0] = $3 | 0x98000000L;
  210. out.data[1] = $2.value;
  211. out.patch[0] = out.patch[1] = 0;
  212. }
  213. | INTFLY exp .cond {
  214. out.len = 2;
  215. out.data[0] = $3 | 0x98000000L | COND_INTFLY;
  216. out.data[1] = $2.value;
  217. out.patch[0] = out.patch[1] = 0;
  218. }
  219. | jump_or_call exp .cond {
  220. out.len = 2;
  221. out.data[0] = $1 | $3 | chkreladdr(1, &$2, 2, COND_REL);
  222. out.patch[0] = 0;
  223. }
  224. | jump_or_call REL '(' exp ')' .cond {
  225. out.len = 2;
  226. out.data[0] = $1 | $6 | COND_REL;
  227. out.data[1] = mkreladdr($4.value, 2);
  228. out.patch[0] = out.patch[1] = 0;
  229. }
  230. | MOVE exp ',' .ptr regexp ',' with_or_when phase {
  231. out.len = 2;
  232. out.data[0] = ($8 << 24) | $2.value | ($4 << 29) | MOVE_MODE;
  233. out.data[1] = $5.value;
  234. out.patch[0] = 0;
  235. out.patch[1] = patchtype($5.t);
  236. }
  237. | MOVE FROM exp ',' with_or_when phase {
  238. out.len = 2;
  239. out.data[0] = ($6 << 24) | (1L << 28) | MOVE_MODE;
  240. out.data[1] = $3.value;
  241. out.patch[0] = 0;
  242. out.patch[1] = patchtype($3.t);
  243. }
  244. | MOVE MEMORY exp ',' regexp ',' regexp {
  245. out.len = 3;
  246. out.data[0] = 0xc0000000L | $3.value;
  247. out.data[1] = $5.value;
  248. out.data[2] = $7.value;
  249. out.patch[0] = 0;
  250. out.patch[1] = patchtype($5.t);
  251. out.patch[2] = patchtype($7.t);
  252. }
  253. | MOVE regA TO regA { regmove($2, 2, $4, 0); } /* do reg to sfbr moves using or 0 */
  254. | MOVE exp TO regA { regmove($4, 0, $4, &$2); }
  255. | MOVE regA '|' exp TO regA { regmove($2, 2, $6, &$4); }
  256. | MOVE regA '&' exp TO regA { regmove($2, 4, $6, &$4); }
  257. | MOVE regA '+' exp TO regA { regmove($2, 6, $6, &$4); }
  258. | MOVE regA '-' exp TO regA { regmove($2, 6, $6, &$4); }
  259. | MOVE regA '+' exp TO regA WITH CARRY {
  260. regmove($2, 7, $6, &$4);
  261. }
  262. | MOVE regA '-' exp TO regA WITH CARRY {
  263. $4.value = -$4.value;
  264. regmove($2, 7, $6, &$4);
  265. }
  266. | MOVE regA SHL TO regA { regmove($2, 1, $5, 0); }
  267. | MOVE regA SHR TO regA { regmove($2, 5, $5, 0); }
  268. | MOVE regA XOR exp TO regA { regmove($2, 3, $6, &$4); }
  269. | NOP {
  270. out.len = 2;
  271. out.data[0] = 0x80000000L;
  272. out.data[1] = 0;
  273. out.patch[0] = out.patch[1] = 0;
  274. }
  275. | RESELECT exp ',' exp {
  276. out.len = 2;
  277. out.data[0] = 0x40000000L | ((long)$2.value << 16) | (1L << 9) | chkreladdr(1, &$4, 2, IO_REL);
  278. out.patch[0] = 0;
  279. }
  280. | RESELECT exp ',' REL '(' exp ')' {
  281. out.len = 2;
  282. out.data[0] = 0x40000000L | IO_REL
  283. | ((long)$2.value << 16) | (1L << 9);
  284. out.data[1] = mkreladdr($6.value, 2);
  285. out.patch[0] = out.patch[1] = 0;
  286. }
  287. | RESELECT FROM exp ',' exp {
  288. out.len = 2;
  289. out.data[0] = 0x40000000L | (1L << 25) | $3.value | chkreladdr(1, &$5, 2, IO_REL);
  290. out.patch[0] = 5;
  291. }
  292. | RESELECT FROM exp ',' REL '(' exp ')' {
  293. out.len = 2;
  294. out.data[0] = 0x40000000L | (1L << 25) | IO_REL | $3.value;
  295. out.patch[0] = 5;
  296. out.data[1] = mkreladdr($7.value, 2);
  297. out.patch[1] = 0;
  298. }
  299. | RETURN .cond {
  300. out.len = 2;
  301. out.data[0] = 0x90000000L | $2;
  302. out.data[1] = 0;
  303. out.patch[0] = out.patch[1] = 0;
  304. }
  305. | SELECT .atn exp ',' exp {
  306. out.len = 2;
  307. out.data[0] =
  308. 0x40000000L | ((long)$3.value << 16) | (1L << 9) | $2 | chkreladdr(1, &$5, 2, IO_REL);
  309. out.patch[0] = 0;
  310. }
  311. | SELECT .atn exp ',' REL '(' exp ')' {
  312. out.len = 2;
  313. out.data[0] = 0x40000000L | (1L << 26)
  314. | ((long)$3.value << 16) | (1L << 9) | $2;
  315. out.data[1] = mkreladdr($7.value, 2);
  316. out.patch[0] = out.patch[1] = 0;
  317. }
  318. | SELECT .atn FROM exp ',' exp {
  319. out.len = 2;
  320. out.data[0] = 0x40000000L | (1L << 25) | $4.value | $2 | chkreladdr(1, &$6, 2, IO_REL);
  321. out.patch[0] = 5;
  322. }
  323. | SELECT .atn FROM exp ',' REL '(' exp ')' {
  324. out.len = 2;
  325. out.data[0] = 0x40000000L | (1L << 25) | IO_REL | $4.value | $2;
  326. out.patch[0] = 5;
  327. out.data[1] = mkreladdr($8.value, 2);
  328. out.patch[1] = 0;
  329. }
  330. | WAIT DISCONNECT {
  331. out.len = 2;
  332. out.data[0] = 0x48000000L;
  333. out.data[1] = 0;
  334. out.patch[0] = out.patch[1] = 0;
  335. }
  336. | WAIT RESELECT exp {
  337. out.len = 2;
  338. out.data[0] = 0x50000000L | chkreladdr(1, &$3, 2, IO_REL);
  339. out.patch[0] = 0;
  340. }
  341. | WAIT RESELECT REL '(' exp ')' {
  342. out.len = 2;
  343. out.data[0] = 0x50000000L | (1L << 26);
  344. out.data[1] = mkreladdr($5.value, 2);
  345. out.patch[0] = out.patch[1] = 0;
  346. }
  347. | WAIT SELECT exp {
  348. out.len = 2;
  349. out.data[0] = 0x40000000L | (1L << 9) | chkreladdr(1, &$3, 2, IO_REL);
  350. out.patch[0] = 0;
  351. }
  352. | WAIT SELECT REL '(' exp ')' {
  353. out.len = 2;
  354. out.data[0] = 0x40000000L | (1L << 26) | (1L << 9);
  355. out.data[1] = mkreladdr($5.value, 2);
  356. out.patch[0] = out.patch[1] = 0;
  357. }
  358. | DEFW exp {
  359. out.len = 1;
  360. out.data[0] = $2.value;
  361. out.patch[0] = patchtype($2.t);
  362. }
  363. ;
  364. .ptr: PTR { $$ = 1; }
  365. | { $$ = 0; }
  366. ;
  367. with_or_when: WITH
  368. | WHEN
  369. ;
  370. jump_or_call: JUMP { $$ = 0x80000000L; }
  371. | CALL { $$ = 0x88000000L; }
  372. ;
  373. condsfbr: byteexp { $$ = $1.value | COND_DATA; }
  374. | byteexp AND MASK byteexp { $$ = ($4.value << 8) | $1.value | COND_DATA; }
  375. ;
  376. condphase: phase { $$ = ($1 << 24) | COND_PHASE; }
  377. .cond: ',' IF ATN { $$ = COND_TRUE; }
  378. | ',' IF condphase { $$ = $3 | COND_TRUE; }
  379. | ',' IF CARRY { $$ = COND_CARRY | COND_TRUE; }
  380. | ',' IF condsfbr { $$ = $3 | COND_TRUE; }
  381. | ',' IF ATN AND condsfbr { $$ = $5 | COND_TRUE; }
  382. | ',' IF condphase AND condsfbr { $$ = $3 | $5 | COND_TRUE; }
  383. | ',' WHEN condphase { $$ = $3 | COND_WAIT | COND_TRUE; }
  384. | ',' WHEN CARRY { $$ = COND_CARRY | COND_WAIT | COND_TRUE; }
  385. | ',' WHEN condsfbr { $$ = $3 | COND_WAIT | COND_TRUE; }
  386. | ',' WHEN condphase AND condsfbr { $$ = $3 | $5 | COND_WAIT | COND_TRUE; }
  387. | ',' IF NOT ATN { $$ = 0; }
  388. | ',' IF NOT condphase { $$ = $4; }
  389. | ',' IF NOT CARRY { $$ = COND_CARRY; }
  390. | ',' IF NOT condsfbr { $$ = $4; }
  391. | ',' IF NOT ATN OR condsfbr { $$ = $6; }
  392. | ',' IF NOT condphase OR condsfbr { $$ = $4 | $6; }
  393. | ',' WHEN NOT condphase { $$ = $4 | COND_WAIT; }
  394. | ',' WHEN NOT CARRY { $$ = COND_CARRY | COND_WAIT; }
  395. | ',' WHEN NOT condsfbr { $$ = $4 | COND_WAIT; }
  396. | ',' WHEN NOT condphase OR condsfbr { $$ = $4 | $6 | COND_WAIT; }
  397. | { $$ = COND_TRUE; }
  398. ;
  399. .opcode: opcode
  400. | { out.len = 0; }
  401. ;
  402. regA: reg
  403. | SFBR { $$ = 8; }
  404. ;
  405. reg: SCNTL0 { $$ = 0; }
  406. | SCNTL1 { $$ = 1; }
  407. | SCNTL2 { $$ = 2; }
  408. | SCNTL3 { $$ = 3; }
  409. | SCID { $$ = 4; }
  410. | SXFER { $$ = 5; }
  411. | SDID { $$ = 6; }
  412. | GPREG { $$ = 7; }
  413. | SOCL { $$ = 9; }
  414. | SSID { $$ = 0xa; }
  415. | SBCL { $$ = 0xb; }
  416. | DSTAT { $$ = 0xc; }
  417. | SSTAT0 { $$ = 0xd; }
  418. | SSTAT1 { $$ = 0xe; }
  419. | SSTAT2 { $$ = 0xf; }
  420. | DSA0 { $$ = 0x10; }
  421. | DSA1 { $$ = 0x11; }
  422. | DSA2 { $$ = 0x12; }
  423. | DSA3 { $$ = 0x13; }
  424. | ISTAT { $$ = 0x14; }
  425. | CTEST0 { $$ = 0x18; }
  426. | CTEST1 { $$ = 0x19; }
  427. | CTEST2 { $$ = 0x1a; }
  428. | CTEST3 { $$ = 0x1b; }
  429. | TEMP { $$ = 0x1c; }
  430. | DFIFO { $$ = 0x20; }
  431. | CTEST4 { $$ = 0x21; }
  432. | CTEST5 { $$ = 0x22; }
  433. | CTEST6 { $$ = 0x23; }
  434. | DBC { $$ = 0x24; }
  435. | DCMD { $$ = 0x27; }
  436. | DNAD { $$ = 0x28; }
  437. | DSP { $$ = 0x2c; }
  438. | DSPS { $$ = 0x30; }
  439. | SCRATCHA0 { $$ = 0x34; }
  440. | SCRATCHA1 { $$ = 0x35; }
  441. | SCRATCHA2 { $$ = 0x36; }
  442. | SCRATCHA3 { $$ = 0x37; }
  443. | DMODE { $$ = 0x38; }
  444. | DIEN { $$ = 0x39; }
  445. | DWT { $$ = 0x3a; }
  446. | DCNTL { $$ = 0x3b; }
  447. | ADDER { $$ = 0x3c; }
  448. | SIEN0 { $$ = 0x40; }
  449. | SIEN1 { $$ = 0x41; }
  450. | SIST0 { $$ = 0x42; }
  451. | SIST1 { $$ = 0x43; }
  452. | SLPAR { $$ = 0x44; }
  453. | MACNTL { $$ = 0x46; }
  454. | GPCNTL { $$ = 0x47; }
  455. | STIME0 { $$ = 0x48; }
  456. | STIME1 { $$ = 0x49; }
  457. | RESPID { $$ = 0x4a; }
  458. | STEST0 { $$ = 0x4c; }
  459. | STEST1 { $$ = 0x4d; }
  460. | STEST2 { $$ = 0x4e; }
  461. | STEST3 { $$ = 0x4f; }
  462. | SIDL { $$ = 0x50; }
  463. | SODL { $$ = 0x54; }
  464. | SBDL { $$ = 0x58; }
  465. | SCRATCHB0 { $$ = 0x5c; }
  466. | SCRATCHB1 { $$ = 0x5d; }
  467. | SCRATCHB2 { $$ = 0x5e; }
  468. | SCRATCHB3 { $$ = 0x5f; }
  469. | SCRATCHC0 { $$ = 0x60; }
  470. | SCRATCHC1 { $$ = 0x61; }
  471. | SCRATCHC2 { $$ = 0x62; }
  472. | SCRATCHC3 { $$ = 0x63; }
  473. ;
  474. .atn: ATN { $$ = (1 << 24); }
  475. | /* nothing */ { $$ = 0; }
  476. ;
  477. phase: DATA_OUT { $$ = 0; }
  478. | DATA_IN { $$ = 1; }
  479. | COMMAND { $$ = 2; }
  480. | STATUS { $$ = 3; }
  481. | RESERVED_OUT { $$ = 4; }
  482. | RESERVED_IN { $$ = 5; }
  483. | MESSAGE_OUT { $$ = 6; }
  484. | MESSAGE_IN { $$ = 7; }
  485. ;
  486. byteexp: exp
  487. {
  488. if (pass2 && ($1.value < 0 || $1.value > 255)) {
  489. if (wflag)
  490. yywarn("conversion causes truncation");
  491. $$.value = $1.value & 0xff;
  492. }
  493. else
  494. $$.value = $1.value;
  495. }
  496. ;
  497. regexp: exp
  498. | regA { $$.t = Reg; $$.value = $1; }
  499. ;
  500. exp: NUM { $$.t = Const; $$.value = $1; }
  501. | SYMBOL {
  502. $$.t = $1->t; $$.value = $1->value;
  503. if (pass2 && $1->t == Unknown)
  504. {
  505. yyerror("Undefined symbol %s", $1->name);
  506. $1->t = Error;
  507. $1->value = 0;
  508. $$.t = Error;
  509. $$.value = 0;
  510. }
  511. }
  512. | exp '+' exp { $$ = eval($1, $3, '+'); }
  513. | exp '-' exp { $$ = eval($1, $3, '-'); }
  514. | exp '*' exp { $$ = eval($1, $3, '*'); }
  515. | exp '/' exp { $$ = eval($1, $3, '/'); }
  516. | '-' exp %prec NEG { $$ = eval($2, $2, '_'); }
  517. | '(' exp ')' { $$ = $2; }
  518. | '~' exp %prec NEG { $$ = eval($2, $2, '~'); }
  519. ;
  520. %%
  521. struct {
  522. char *name;
  523. int tok;
  524. } toktab[] =
  525. {
  526. { "when", WHEN },
  527. { "data_out", DATA_OUT },
  528. { "data_in", DATA_IN },
  529. { "msg_out", MESSAGE_OUT },
  530. { "msg_in", MESSAGE_IN },
  531. { "cmd", COMMAND },
  532. { "command", COMMAND },
  533. { "status", STATUS },
  534. { "move", MOVE },
  535. { "select", SELECT },
  536. { "reselect", RESELECT },
  537. { "disconnect", DISCONNECT },
  538. { "wait", WAIT },
  539. { "set", SET },
  540. { "clear", CLEAR },
  541. { "with", WITH },
  542. { "atn", ATN },
  543. { "fail", FAIL },
  544. { "carry", CARRY },
  545. { "target", TARGET },
  546. { "ack", ACK },
  547. { "scntl0", SCNTL0 },
  548. { "scntl1", SCNTL1 },
  549. { "scntl2", SCNTL2 },
  550. { "scntl3", SCNTL3 },
  551. { "scid", SCID },
  552. { "sxfer", SXFER },
  553. { "sdid", SDID },
  554. { "gpreg", GPREG },
  555. { "sfbr", SFBR },
  556. { "socl", SOCL },
  557. { "ssid", SSID },
  558. { "sbcl", SBCL },
  559. { "dstat", DSTAT },
  560. { "sstat0", SSTAT0 },
  561. { "sstat1", SSTAT1 },
  562. { "sstat2", SSTAT2 },
  563. { "dsa", DSA0 },
  564. { "dsa0", DSA0 },
  565. { "dsa1", DSA1 },
  566. { "dsa2", DSA2 },
  567. { "dsa3", DSA3 },
  568. { "istat", ISTAT },
  569. { "ctest0", CTEST0 },
  570. { "ctest1", CTEST1 },
  571. { "ctest2", CTEST2 },
  572. { "ctest3", CTEST3 },
  573. { "temp", TEMP },
  574. { "dfifo", DFIFO },
  575. { "ctest4", CTEST4 },
  576. { "ctest5", CTEST5 },
  577. { "ctest6", CTEST6 },
  578. { "dbc", DBC },
  579. { "dcmd", DCMD },
  580. { "dnad", DNAD },
  581. { "dsp", DSP },
  582. { "dsps", DSPS },
  583. { "scratcha", SCRATCHA0 },
  584. { "scratcha0", SCRATCHA0 },
  585. { "scratcha1", SCRATCHA1 },
  586. { "scratcha2", SCRATCHA2 },
  587. { "scratcha3", SCRATCHA3 },
  588. { "dmode", DMODE },
  589. { "dien", DIEN },
  590. { "dwt", DWT },
  591. { "dcntl", DCNTL },
  592. { "adder", ADDER },
  593. { "sien0", SIEN0 },
  594. { "sien1", SIEN1 },
  595. { "sist0", SIST0 },
  596. { "sist1", SIST1 },
  597. { "slpar", SLPAR },
  598. { "macntl", MACNTL },
  599. { "gpcntl", GPCNTL },
  600. { "stime0", STIME0 },
  601. { "stime1", STIME1 },
  602. { "respid", RESPID },
  603. { "stest0", STEST0 },
  604. { "stest1", STEST1 },
  605. { "stest2", STEST2 },
  606. { "stest3", STEST3 },
  607. { "sidl", SIDL },
  608. { "sodl", SODL },
  609. { "sbdl", SBDL },
  610. { "scratchb", SCRATCHB0 },
  611. { "scratchb0", SCRATCHB0 },
  612. { "scratchb1", SCRATCHB1 },
  613. { "scratchb2", SCRATCHB2 },
  614. { "scratchb3", SCRATCHB3 },
  615. { "scratchc", SCRATCHC0 },
  616. { "scratchc0", SCRATCHC0 },
  617. { "scratchc1", SCRATCHC1 },
  618. { "scratchc2", SCRATCHC2 },
  619. { "scratchc3", SCRATCHC3 },
  620. { "add", ADD },
  621. { "addc", ADDC },
  622. { "and", AND },
  623. { "or", OR },
  624. { "xor", XOR },
  625. { "shl", SHL },
  626. { "shr", SHR },
  627. { "jump", JUMP },
  628. { "call", CALL },
  629. { "return", RETURN },
  630. { "int", INT },
  631. { "intfly", INTFLY },
  632. { "not", NOT },
  633. { "absolute", ABSOLUTE },
  634. { "mask", MASK },
  635. { "if", IF },
  636. { "rel", REL },
  637. { "ptr", PTR },
  638. { "table", TABLE },
  639. { "from", FROM },
  640. { "memory", MEMORY },
  641. { "to", TO },
  642. { "nop", NOP },
  643. { "extern", EXTERN },
  644. { "defw", DEFW },
  645. };
  646. #define TOKS (sizeof(toktab)/sizeof(toktab[0]))
  647. int lc;
  648. int ll;
  649. void
  650. yyrewind(void)
  651. {
  652. rewind(in_f);
  653. ll = lc = 0;
  654. yyline = 0;
  655. dot = 0;
  656. }
  657. int
  658. yygetc(void)
  659. {
  660. if (lc == ll)
  661. {
  662. next:
  663. if (fgets(line, 500, in_f) == 0)
  664. return EOF;
  665. /* do nasty check for #line directives */
  666. if (strncmp(line, "#line", 5) == 0) {
  667. /* #line n "filename" */
  668. sscanf(line, "#line %d \"%[^\"]", &yyline, yyfilename);
  669. yyline--;
  670. goto next;
  671. }
  672. yyline++;
  673. ll = strlen(line);
  674. lc = 0;
  675. }
  676. return line[lc++];
  677. }
  678. void
  679. yyungetc(void)
  680. {
  681. if (lc <= 0)
  682. exits("ungetc");
  683. lc--;
  684. }
  685. int
  686. yylex(void)
  687. {
  688. char token[100];
  689. int tl = 0;
  690. int c;
  691. while ((c = yygetc()) != EOF && (c == ' ' || c == '\t'))
  692. ;
  693. if (c == EOF)
  694. return 0;
  695. if (isalpha(c) || c == '_')
  696. {
  697. int x;
  698. do {
  699. token[tl++] = c;
  700. } while ((c = yygetc()) != EOF && (isalnum(c) || c == '_'));
  701. if (c == EOF)
  702. return 0;
  703. yyungetc();
  704. token[tl] = 0;
  705. for (x = 0; x < TOKS; x++)
  706. if (strcmp(toktab[x].name, token) == 0)
  707. return toktab[x].tok;
  708. /* must be a symbol */
  709. yylval.s = findsym(token);
  710. return SYMBOL;
  711. }
  712. else if (isdigit(c))
  713. {
  714. /* accept 0x<digits> or 0b<digits> 0<digits> or <digits> */
  715. int prefix = c == '0';
  716. unsigned long n = c - '0';
  717. int base = 10;
  718. for (;;)
  719. {
  720. c = yygetc();
  721. if (c == EOF)
  722. return 0;
  723. if (prefix)
  724. {
  725. prefix = 0;
  726. if (c == 'x') {
  727. base = 16;
  728. continue;
  729. }
  730. else if (c == 'b')
  731. {
  732. base = 2;
  733. continue;
  734. }
  735. else
  736. base = 8;
  737. }
  738. if (isdigit(c))
  739. c -= '0';
  740. else if (isalpha(c) && base > 10)
  741. {
  742. if (isupper(c))
  743. c = tolower(c);
  744. c = c - 'a' + 10;
  745. }
  746. else {
  747. yyungetc();
  748. yylval.n = n;
  749. return NUM;
  750. }
  751. if (c >= base)
  752. yyerror("illegal format number");
  753. n = n * base + c;
  754. }
  755. }
  756. else if (c == ';') {
  757. /* skip to end of line */
  758. while ((c = yygetc()) != EOF && c != '\n')
  759. ;
  760. if (c != EOF)
  761. yyungetc();
  762. return COMMENT;
  763. }
  764. return c;
  765. }
  766. void
  767. yyerror(char *s, ...)
  768. {
  769. va_list ap;
  770. va_start(ap, s);
  771. fprintf(stderr, "%s: %d: ", yyfilename, yyline);
  772. vfprintf(stderr, s, ap);
  773. if (putc('\n', stderr) < 0)
  774. exits("io");
  775. errors++;
  776. va_end(ap);
  777. }
  778. void
  779. yywarn(char *s, ...)
  780. {
  781. va_list ap;
  782. va_start(ap, s);
  783. fprintf(stderr, "%s: %d: warning: ", yyfilename, yyline);
  784. vfprintf(stderr, s, ap);
  785. if (putc('\n', stderr) < 0)
  786. exits("io");
  787. warnings++;
  788. va_end(ap);
  789. }
  790. void
  791. p2error(int line, char *s)
  792. {
  793. USED(line);
  794. printf("/*\t%s */\n", s);
  795. }
  796. void
  797. main(int argc, char *argv[])
  798. {
  799. int a;
  800. for (a = 1; a < argc; a++)
  801. {
  802. if (argv[a][0] == '-')
  803. switch (argv[a][1]) {
  804. case 'D':
  805. /* #defines for cpp */
  806. if (ncppopts >= MAXCPPOPTS) {
  807. fprintf(stderr, "too many cpp options\n");
  808. exits("options");
  809. }
  810. cppopts[ncppopts++] = argv[a];
  811. break;
  812. default:
  813. fprintf(stderr, "unrecognised option %s\n",
  814. argv[a]);
  815. exits("options");
  816. }
  817. else
  818. break;
  819. }
  820. if (a != argc - 1)
  821. {
  822. fprintf(stderr, "usage: na [options] file\n");
  823. exits("options");
  824. }
  825. if (access(argv[a], 4) < 0) {
  826. fprintf(stderr, "can't read %s\n", argv[a]);
  827. exits("");
  828. }
  829. in_f = tmpfile();
  830. preprocess(argv[a], in_f);
  831. rewind(in_f);
  832. strcpy(yyfilename, argv[a]);
  833. yyparse();
  834. if (errors)
  835. exits("pass1");
  836. pass2 = 1;
  837. printf("unsigned long na_script[] = {\n");
  838. yyrewind();
  839. yyparse();
  840. printf("};\n");
  841. printf("\n");
  842. printf("#define NA_SCRIPT_SIZE %d\n", dot / 4);
  843. printf("\n");
  844. fixup();
  845. /*
  846. assemble();
  847. */
  848. exits(errors ? "pass2" : "");
  849. }
  850. void
  851. preprocess(char *in, FILE *out)
  852. {
  853. Waitmsg *w;
  854. char **argv;
  855. if (fork() == 0) {
  856. /* child */
  857. dup(fileno(out), 1);
  858. argv = (char **)malloc(sizeof(char *) * (ncppopts + 5));
  859. argv[0] = "cpp";
  860. memcpy(&argv[1], cppopts, sizeof(char *) * ncppopts);
  861. argv[ncppopts + 1] = "-+";
  862. argv[ncppopts + 2] = "-N";
  863. argv[ncppopts + 3] = in;
  864. argv[ncppopts + 4] = 0;
  865. exec("/bin/cpp", argv);
  866. fprintf(stderr, "failed to exec cpp (%R)\n");
  867. exits("exec");
  868. }
  869. w = wait();
  870. free(w);
  871. }
  872. struct sym *
  873. findsym(char *name)
  874. {
  875. struct sym *s;
  876. for (s = symlist; s; s = s->next)
  877. if (strcmp(name, s->name) == 0)
  878. return s;
  879. s = (struct sym *)malloc(sizeof(*s));
  880. s->name = strdup(name);
  881. s->t = Unknown;
  882. s->set = 0;
  883. s->next = symlist;
  884. symlist = s;
  885. return s;
  886. }
  887. void
  888. setsym(struct sym *s, Type t, long v)
  889. {
  890. if (pass2) {
  891. if (t == Unknown || t == Error)
  892. yyerror("can't resolve symbol");
  893. else {
  894. s->t = t;
  895. s->value = v;
  896. }
  897. }
  898. else {
  899. if (s->set)
  900. yyerror("multiply defined symbol");
  901. s->set = 1;
  902. s->t = t;
  903. s->value = v;
  904. }
  905. }
  906. int
  907. mk24bitssigned(long *l)
  908. {
  909. if (*l < 0) {
  910. if ((*l & 0xff800000L) != 0xff800000L) {
  911. *l = 0;
  912. return 0;
  913. }
  914. else
  915. *l = (*l) & 0xffffffL;
  916. }
  917. else if (*l > 0xffffffL) {
  918. *l = 0;
  919. return 0;
  920. }
  921. return 1;
  922. }
  923. static Type addresult[5][5] = {
  924. /* Const Addr Table Extern Reg */
  925. /* Const */ Const, Addr, Table, Error, Reg,
  926. /* Addr */ Addr, Error, Error, Error, Error,
  927. /* Table */ Table, Error, Error, Error, Error,
  928. /* Extern */ Error, Error, Error, Error, Error,
  929. /* Reg */ Reg, Error, Error, Error, Error,
  930. };
  931. static Type subresult[5][5] = {
  932. /* Const Addr Table Extern Reg */
  933. /* Const */ Const, Error, Error, Error, Error,
  934. /* Addr */ Addr, Const, Error, Error, Error,
  935. /* Table */ Table, Error, Const, Error, Error,
  936. /* Extern */ Error, Error, Error, Const, Error,
  937. /* Reg */ Error, Error, Error, Error, Error,
  938. };
  939. static Type muldivresult[5][5] = {
  940. /* Const Addr Table Extern */
  941. /* Const */ Const, Error, Error, Error, Error,
  942. /* Addr */ Error, Error, Error, Error, Error,
  943. /* Table */ Error, Error, Error, Error, Error,
  944. /* Extern */ Error, Error, Error, Error, Error,
  945. /* Reg */ Error, Error, Error, Error, Error,
  946. };
  947. static Type negresult[] = {
  948. /* Const */ Const,
  949. /* Addr */ Error,
  950. /* Table */ Error,
  951. /* Extern */ Error,
  952. /* Reg */ Error,
  953. };
  954. int
  955. patchtype(Type t)
  956. {
  957. switch (t) {
  958. case Addr:
  959. return 1;
  960. case Reg:
  961. return 2;
  962. case Extern:
  963. return 4;
  964. default:
  965. return 0;
  966. }
  967. }
  968. struct expval
  969. eval(struct expval a, struct expval b, char op)
  970. {
  971. struct expval c;
  972. if (a.t == Unknown || b.t == Unknown) {
  973. c.t = Unknown;
  974. c.value = 0;
  975. }
  976. else if (a.t == Error || b.t == Error) {
  977. c.t = Error;
  978. c.value = 0;
  979. }
  980. else {
  981. switch (op) {
  982. case '+':
  983. c.t = addresult[a.t][b.t];
  984. break;
  985. case '-':
  986. c.t = subresult[a.t][b.t];
  987. break;
  988. case '*':
  989. case '/':
  990. c.t = muldivresult[a.t][b.t];
  991. break;
  992. case '_':
  993. case '~':
  994. c.t = negresult[a.t];
  995. break;
  996. default:
  997. c.t = Error;
  998. break;
  999. }
  1000. if (c.t == Error) {
  1001. if (pass2)
  1002. yyerror("type clash in evaluation");
  1003. c.value = 0;
  1004. }
  1005. else {
  1006. switch (op) {
  1007. case '+':
  1008. c.value = a.value + b.value;
  1009. break;
  1010. case '-':
  1011. c.value = a.value - b.value;
  1012. break;
  1013. case '*':
  1014. c.value = a.value * b.value;
  1015. break;
  1016. case '/':
  1017. c.value = a.value / b.value;
  1018. break;
  1019. case '_':
  1020. c.value = -a.value;
  1021. break;
  1022. case '~':
  1023. c.value = ~a.value;
  1024. break;
  1025. }
  1026. }
  1027. }
  1028. return c;
  1029. }
  1030. void
  1031. regmove(unsigned char src_reg, unsigned char op,
  1032. unsigned char dst_reg, struct expval *imm)
  1033. {
  1034. unsigned char func, reg;
  1035. int immdata;
  1036. out.len = 2;
  1037. if (src_reg == 8) {
  1038. func = 5;
  1039. reg = dst_reg;
  1040. }
  1041. else if (dst_reg == 8) {
  1042. func = 6;
  1043. reg = src_reg;
  1044. }
  1045. else {
  1046. if (pass2 && src_reg != dst_reg)
  1047. yyerror("Registers must be the same");
  1048. func = 7;
  1049. reg = src_reg;
  1050. }
  1051. immdata = imm ? (imm->value & 0xff) : 0;
  1052. out.data[0] = 0x40000000L
  1053. | ((long)func << 27)
  1054. | ((long)op << 24)
  1055. | ((long)reg << 16)
  1056. | ((long)(immdata) << 8);
  1057. out.data[1] = 0;
  1058. out.patch[0] = (imm && imm->t == Extern) ? 3 : 0;
  1059. out.patch[1] = 0;
  1060. }
  1061. long
  1062. mkreladdr(long addr, int len)
  1063. {
  1064. long rel;
  1065. rel = addr - (dot + 4 * len);
  1066. mk24bitssigned(&rel);
  1067. return rel;
  1068. }
  1069. long
  1070. chkreladdr(int d, struct expval *e, int len, long relrv)
  1071. {
  1072. if (e->t == Addr) {
  1073. out.data[d] = mkreladdr(e->value, len);
  1074. out.patch[d] = 0;
  1075. return relrv;
  1076. } else {
  1077. out.data[d] = e->value;
  1078. out.patch[d] = patchtype(e->t);
  1079. return 0;
  1080. }
  1081. }
  1082. void
  1083. fixup(void)
  1084. {
  1085. struct sym *s;
  1086. int p;
  1087. printf("struct na_patch na_patches[] = {\n");
  1088. for (p = 0; p < patches; p++) {
  1089. printf("\t{ 0x%.4x, %d }, /* %.8lx */\n",
  1090. patch[p].lwoff, patch[p].type, patch[p].lwoff * 4L);
  1091. }
  1092. if (patches == 0) {
  1093. printf("\t{ 0, 0 },\n");
  1094. }
  1095. printf("};\n");
  1096. printf("#define NA_PATCHES %d\n", patches);
  1097. printf("\n");
  1098. if (externs) {
  1099. printf("enum na_external {\n");
  1100. for (p = 0; p < externs; p++) {
  1101. printf("\tX_%s,\n", externp[p]->name);
  1102. }
  1103. printf("};\n");
  1104. }
  1105. /* dump all labels (symbols of type Addr) as E_<Name> */
  1106. for (s = symlist; s; s = s->next)
  1107. if (s->t == Addr)
  1108. break;
  1109. if (s) {
  1110. printf("\nenum {\n");
  1111. while (s) {
  1112. if (s->t == Addr)
  1113. printf("\tE_%s = %ld,\n", s->name, s->value);
  1114. s = s->next;
  1115. }
  1116. printf("};\n");
  1117. }
  1118. /* dump all Consts as #define A_<Name> value */
  1119. for (s = symlist; s; s = s->next)
  1120. if (s->t == Const)
  1121. printf("#define A_%s %ld\n", s->name, s->value);
  1122. }