na.y 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201
  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. if (exec("/bin/cpp", argv) < 0) {
  866. fprintf(stderr, "failed to exec cpp (%R)\n");
  867. exits("exec");
  868. }
  869. exits("");
  870. }
  871. w = wait();
  872. free(w);
  873. }
  874. struct sym *
  875. findsym(char *name)
  876. {
  877. struct sym *s;
  878. for (s = symlist; s; s = s->next)
  879. if (strcmp(name, s->name) == 0)
  880. return s;
  881. s = (struct sym *)malloc(sizeof(*s));
  882. s->name = strdup(name);
  883. s->t = Unknown;
  884. s->set = 0;
  885. s->next = symlist;
  886. symlist = s;
  887. return s;
  888. }
  889. void
  890. setsym(struct sym *s, Type t, long v)
  891. {
  892. if (pass2) {
  893. if (t == Unknown || t == Error)
  894. yyerror("can't resolve symbol");
  895. else {
  896. s->t = t;
  897. s->value = v;
  898. }
  899. }
  900. else {
  901. if (s->set)
  902. yyerror("multiply defined symbol");
  903. s->set = 1;
  904. s->t = t;
  905. s->value = v;
  906. }
  907. }
  908. int
  909. mk24bitssigned(long *l)
  910. {
  911. if (*l < 0) {
  912. if ((*l & 0xff800000L) != 0xff800000L) {
  913. *l = 0;
  914. return 0;
  915. }
  916. else
  917. *l = (*l) & 0xffffffL;
  918. }
  919. else if (*l > 0xffffffL) {
  920. *l = 0;
  921. return 0;
  922. }
  923. return 1;
  924. }
  925. static Type addresult[5][5] = {
  926. /* Const Addr Table Extern Reg */
  927. /* Const */ Const, Addr, Table, Error, Reg,
  928. /* Addr */ Addr, Error, Error, Error, Error,
  929. /* Table */ Table, Error, Error, Error, Error,
  930. /* Extern */ Error, Error, Error, Error, Error,
  931. /* Reg */ Reg, Error, Error, Error, Error,
  932. };
  933. static Type subresult[5][5] = {
  934. /* Const Addr Table Extern Reg */
  935. /* Const */ Const, Error, Error, Error, Error,
  936. /* Addr */ Addr, Const, Error, Error, Error,
  937. /* Table */ Table, Error, Const, Error, Error,
  938. /* Extern */ Error, Error, Error, Const, Error,
  939. /* Reg */ Error, Error, Error, Error, Error,
  940. };
  941. static Type muldivresult[5][5] = {
  942. /* Const Addr Table Extern */
  943. /* Const */ Const, Error, Error, Error, Error,
  944. /* Addr */ Error, Error, Error, Error, Error,
  945. /* Table */ Error, Error, Error, Error, Error,
  946. /* Extern */ Error, Error, Error, Error, Error,
  947. /* Reg */ Error, Error, Error, Error, Error,
  948. };
  949. static Type negresult[] = {
  950. /* Const */ Const,
  951. /* Addr */ Error,
  952. /* Table */ Error,
  953. /* Extern */ Error,
  954. /* Reg */ Error,
  955. };
  956. int
  957. patchtype(Type t)
  958. {
  959. switch (t) {
  960. case Addr:
  961. return 1;
  962. case Reg:
  963. return 2;
  964. case Extern:
  965. return 4;
  966. default:
  967. return 0;
  968. }
  969. }
  970. struct expval
  971. eval(struct expval a, struct expval b, char op)
  972. {
  973. struct expval c;
  974. if (a.t == Unknown || b.t == Unknown) {
  975. c.t = Unknown;
  976. c.value = 0;
  977. }
  978. else if (a.t == Error || b.t == Error) {
  979. c.t = Error;
  980. c.value = 0;
  981. }
  982. else {
  983. switch (op) {
  984. case '+':
  985. c.t = addresult[a.t][b.t];
  986. break;
  987. case '-':
  988. c.t = subresult[a.t][b.t];
  989. break;
  990. case '*':
  991. case '/':
  992. c.t = muldivresult[a.t][b.t];
  993. break;
  994. case '_':
  995. case '~':
  996. c.t = negresult[a.t];
  997. break;
  998. default:
  999. c.t = Error;
  1000. break;
  1001. }
  1002. if (c.t == Error) {
  1003. if (pass2)
  1004. yyerror("type clash in evaluation");
  1005. c.value = 0;
  1006. }
  1007. else {
  1008. switch (op) {
  1009. case '+':
  1010. c.value = a.value + b.value;
  1011. break;
  1012. case '-':
  1013. c.value = a.value - b.value;
  1014. break;
  1015. case '*':
  1016. c.value = a.value * b.value;
  1017. break;
  1018. case '/':
  1019. c.value = a.value / b.value;
  1020. break;
  1021. case '_':
  1022. c.value = -a.value;
  1023. break;
  1024. case '~':
  1025. c.value = ~a.value;
  1026. break;
  1027. }
  1028. }
  1029. }
  1030. return c;
  1031. }
  1032. void
  1033. regmove(unsigned char src_reg, unsigned char op,
  1034. unsigned char dst_reg, struct expval *imm)
  1035. {
  1036. unsigned char func, reg;
  1037. int immdata;
  1038. out.len = 2;
  1039. if (src_reg == 8) {
  1040. func = 5;
  1041. reg = dst_reg;
  1042. }
  1043. else if (dst_reg == 8) {
  1044. func = 6;
  1045. reg = src_reg;
  1046. }
  1047. else {
  1048. if (pass2 && src_reg != dst_reg)
  1049. yyerror("Registers must be the same");
  1050. func = 7;
  1051. reg = src_reg;
  1052. }
  1053. immdata = imm ? (imm->value & 0xff) : 0;
  1054. out.data[0] = 0x40000000L
  1055. | ((long)func << 27)
  1056. | ((long)op << 24)
  1057. | ((long)reg << 16)
  1058. | ((long)(immdata) << 8);
  1059. out.data[1] = 0;
  1060. out.patch[0] = (imm && imm->t == Extern) ? 3 : 0;
  1061. out.patch[1] = 0;
  1062. }
  1063. long
  1064. mkreladdr(long addr, int len)
  1065. {
  1066. long rel;
  1067. rel = addr - (dot + 4 * len);
  1068. mk24bitssigned(&rel);
  1069. return rel;
  1070. }
  1071. long
  1072. chkreladdr(int d, struct expval *e, int len, long relrv)
  1073. {
  1074. if (e->t == Addr) {
  1075. out.data[d] = mkreladdr(e->value, len);
  1076. out.patch[d] = 0;
  1077. return relrv;
  1078. } else {
  1079. out.data[d] = e->value;
  1080. out.patch[d] = patchtype(e->t);
  1081. return 0;
  1082. }
  1083. }
  1084. void
  1085. fixup(void)
  1086. {
  1087. struct sym *s;
  1088. int p;
  1089. printf("struct na_patch na_patches[] = {\n");
  1090. for (p = 0; p < patches; p++) {
  1091. printf("\t{ 0x%.4x, %d }, /* %.8lx */\n",
  1092. patch[p].lwoff, patch[p].type, patch[p].lwoff * 4L);
  1093. }
  1094. if (patches == 0) {
  1095. printf("\t{ 0, 0 },\n");
  1096. }
  1097. printf("};\n");
  1098. printf("#define NA_PATCHES %d\n", patches);
  1099. printf("\n");
  1100. if (externs) {
  1101. printf("enum na_external {\n");
  1102. for (p = 0; p < externs; p++) {
  1103. printf("\tX_%s,\n", externp[p]->name);
  1104. }
  1105. printf("};\n");
  1106. }
  1107. /* dump all labels (symbols of type Addr) as E_<Name> */
  1108. for (s = symlist; s; s = s->next)
  1109. if (s->t == Addr)
  1110. break;
  1111. if (s) {
  1112. printf("\nenum {\n");
  1113. while (s) {
  1114. if (s->t == Addr)
  1115. printf("\tE_%s = %ld,\n", s->name, s->value);
  1116. s = s->next;
  1117. }
  1118. printf("};\n");
  1119. }
  1120. /* dump all Consts as #define A_<Name> value */
  1121. for (s = symlist; s; s = s->next)
  1122. if (s->t == Const)
  1123. printf("#define A_%s %ld\n", s->name, s->value);
  1124. }