na.y 25 KB

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