mach4.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /* $Header$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /*
  7. * Motorola 68020 syntax rules
  8. */
  9. operation
  10. : { instrp = instr;
  11. dot_offset = 0;
  12. }
  13. instruction
  14. { emit_instr();
  15. }
  16. ;
  17. instruction
  18. : bcdx DREG ',' DREG
  19. { T_EMIT2($1 | $2 | $4<<9,0,0,0);}
  20. | bcdx '-' '(' AREG ')' ',' '-' '(' AREG ')'
  21. { T_EMIT2($1 | $4 | $9<<9 | 010,0,0,0);}
  22. | ADD sizedef ea_ea
  23. { add($1, $2);}
  24. | AND sizenon ea_ea
  25. { and($1, $2);}
  26. | SHIFT sizedef ea_ea
  27. { shift_op($1, $2);}
  28. | SHIFT sizedef ea /* This syntax is also allowed */
  29. { checksize($2, 2);
  30. T_EMIT2(($1 & 0177700) | mrg_2,0,0,0);
  31. ea_2(SIZE_W, MEM|ALT);
  32. }
  33. | BR expr
  34. { branch($1, $2);}
  35. | DBR DREG ',' expr
  36. { T_EMIT2($1 | $2,0,0,0);
  37. $4.val -= (DOTVAL+dot_offset);
  38. fit(fitw($4.val));
  39. T_EMIT2(loww($4.val), $4.typ,
  40. RELPC|RELO2, relonami);
  41. }
  42. | BITOP ea_ea
  43. { bitop($1);}
  44. | BITFIELD ea off_width
  45. { bitfield($1, $3);}
  46. | BF_TO_D ea off_width ',' DREG
  47. { bitfield($1, $3 | $5<<12);}
  48. | BFINS DREG ',' ea off_width
  49. { bitfield($1, $5 | $2<<12);}
  50. | DIVMUL sizedef ea ',' DREG
  51. { checksize($2, 2|4);
  52. if ($2 == SIZE_W) {
  53. T_EMIT2((0140300^($1<<8))|mrg_2|$5<<9,
  54. 0, 0, 0);
  55. ea_2(SIZE_W, DTA);
  56. }
  57. else { /* 32 bit dividend or product */
  58. T_EMIT2((046000 | ($1 & ~1)) | mrg_2,
  59. 0, 0, 0);
  60. T_EMIT2(($1&1)<<11 | $5<<12 | $5,
  61. 0, 0, 0);
  62. ea_2(SIZE_L, DTA);
  63. }
  64. }
  65. | DIVMUL sizedef ea ',' DREG ':' DREG
  66. { /* 64 bit dividend or product */
  67. checksize($2, 4);
  68. T_EMIT2((046000 | ($1 & ~1)) | mrg_2, 0, 0, 0);
  69. T_EMIT2(($1&1)<<11 | $7<<12 | $5 | 02000,0,0,0);
  70. ea_2(SIZE_L, DTA);
  71. }
  72. | DIVL sizedef ea ',' DREG ':' DREG
  73. { /* 32 bit long division with remainder */
  74. checksize($2, 4);
  75. T_EMIT2(($1 & ~1) | mrg_2, 0, 0, 0);
  76. T_EMIT2(($1 & 1)<<11 | $7<<12 | $5, 0, 0, 0);
  77. ea_2(SIZE_L, DTA);
  78. }
  79. | LEA ea ',' AREG
  80. { T_EMIT2(040700 | mrg_2 | $4<<9,0,0,0);
  81. ea_2(SIZE_L, CTR);
  82. }
  83. | op_ea ea
  84. { if (mrg_2==074)
  85. serror("bad adressing category");
  86. T_EMIT2(($1&0177700) | mrg_2,0,0,0);
  87. ea_2($1&0300, $1&017);
  88. }
  89. | OP_NOOP
  90. { T_EMIT2($1,0,0,0);}
  91. | OP_EXT SIZE DREG
  92. { checksize($2, ($1 & 0400) ? 4 : (2|4));
  93. T_EMIT2($1 | $2+0100 | $3,0,0,0);
  94. }
  95. | OP_RANGE sizedef ea ',' reg
  96. { T_EMIT2(0300 | ($2<<3) | mrg_2,0,0,0);
  97. T_EMIT2($1 | ($5<<12),0,0,0);
  98. ea_2($2, CTR);
  99. }
  100. | TRAPCC SIZE imm
  101. { checksize($2, 2|4);
  102. T_EMIT2($1 | ($2>>6)+1,0,0,0);
  103. ea_2($2, 0);
  104. }
  105. | TRAPCC { T_EMIT2($1 | 4,0,0,0);}
  106. | PACK '-' '(' AREG ')' ',' '-' '(' AREG ')' ',' imm
  107. { T_EMIT2($1 | 1 | $4 | $9<<9, 0, 0, 0);
  108. ea_2(SIZE_W, 0);
  109. }
  110. | PACK DREG ',' DREG ',' imm
  111. { T_EMIT2($1 | $2 | $4<<9, 0, 0, 0);
  112. ea_2(SIZE_W, 0);
  113. }
  114. | CMP sizedef ea_ea
  115. { cmp($2);}
  116. | CHK sizedef ea ',' DREG
  117. { checksize($2, 2|4);
  118. T_EMIT2(040000 | mrg_2 | $5<<9 |
  119. ($2==SIZE_W ? 0600 : 0400),
  120. 0, 0, 0);
  121. ea_2($2, DTA);
  122. }
  123. | MOVE sizenon ea_ea
  124. { move($2);}
  125. | MOVEP sizedef ea_ea
  126. { movep($2);}
  127. | MOVEM sizedef regs ',' notimmreg
  128. { movem(0, $2, $3);}
  129. | MOVEM sizedef notimmreg ',' regs
  130. { movem(1, $2, $5);}
  131. | MOVES sizedef ea_ea
  132. { if (mrg_1 <= 017) {
  133. T_EMIT2(007000 | $2 | mrg_2,0,0,0);
  134. T_EMIT2(mrg_1 << 12 | 04000,0,0,0);
  135. ea_2($2,ALT|MEM);
  136. } else if (mrg_2 <= 017) {
  137. T_EMIT2(007000 | $2 | mrg_1,0,0,0);
  138. T_EMIT2(mrg_2 << 12,0,0,0);
  139. ea_1($2,ALT|MEM);
  140. } else
  141. badoperand();
  142. }
  143. | MOVEC creg ',' reg
  144. { T_EMIT2(047172,0,0,0);
  145. T_EMIT2($2 | $4<<12,0,0,0);
  146. }
  147. | MOVEC reg ',' creg
  148. { T_EMIT2(047173,0,0,0);
  149. T_EMIT2($4 | $2<<12,0,0,0);
  150. }
  151. | EXG reg ',' reg
  152. { if (($2 & 010) == 0)
  153. T_EMIT2(
  154. (0140500|$4|$2<<9)
  155. +
  156. (($4&010)<<3)
  157. ,0,0,0);
  158. else
  159. T_EMIT2(
  160. (0140600|$2|($4&07)<<9)
  161. -
  162. (($4&010)<<3)
  163. ,0,0,0);
  164. }
  165. | SWAP DREG
  166. { T_EMIT2(044100 | $2,0,0,0);}
  167. | STOP imm
  168. { T_EMIT2(047162, 0, 0, 0);
  169. ea_2(SIZE_W, 0);
  170. }
  171. | LINK sizenon AREG ',' imm
  172. { link($2, $3);}
  173. | UNLK AREG
  174. { T_EMIT2(047130 | $2,0,0,0);}
  175. | TRAP '#' absexp
  176. { fit(fit4($3));
  177. T_EMIT2(047100|low4($3),0,0,0);
  178. }
  179. | RTD imm
  180. { T_EMIT2(047164,0,0,0);
  181. ea_2(SIZE_W, 0);
  182. }
  183. | BKPT '#' absexp
  184. { fit(($3 & ~07) == 0);
  185. T_EMIT2(044110 | low3($3),0,0,0);
  186. }
  187. | CALLM '#' absexp ',' ea
  188. { fit(fitb($3));
  189. T_EMIT2(03300 | mrg_2,0,0,0);
  190. T_EMIT2($3,0,0,0);
  191. ea_2(SIZE_L, CTR);
  192. }
  193. | RTM reg
  194. { T_EMIT2(03300 | $2, 0, 0, 0);}
  195. | CAS sizedef DREG ',' DREG ',' ea
  196. { T_EMIT2(04300 | (($2+0100)<<3) | mrg_2,0,0,0);
  197. T_EMIT2($5 | ($3<<6),0,0,0);
  198. ea_2($2, MEM|ALT);
  199. }
  200. | CAS2 sizedef DREG ':' DREG ',' DREG ':' DREG ','
  201. '(' reg ')' ':' '(' reg ')'
  202. { checksize($2 , 2|4);
  203. T_EMIT2(04374 | (($2+0100)<<3),0,0,0);
  204. T_EMIT2($3 | ($7<<6) | ($12<<12),0,0,0);
  205. T_EMIT2($5 | ($9<<6) | ($16<<12),0,0,0);
  206. }
  207. | /* Coprocessor instructions; syntax may be changed (please).
  208. * No coprocessor defined extension words are emitted.
  209. */
  210. CP CPBCC cp_cond expr
  211. { cpbcc($2 | $1 | $3, $4);
  212. }
  213. | CP CPDBCC cp_cond DREG ',' expr
  214. { T_EMIT2($2 | $1 | $4,0,0,0);
  215. $6.val -= (DOTVAL+dot_offset);
  216. fit(fitw($6.val));
  217. T_EMIT2(loww($6.val), $6.typ,
  218. RELPC|RELO2, relonami);
  219. }
  220. | CP CPGEN
  221. { T_EMIT2($2 | $1,0,0,0);
  222. /* NO COMMAND WORD IS EMITTED;
  223. * THIS INSTRUCTIONS IS (STILL) ONE BIG RIDDLE.
  224. * NO EFFECTIVE ADDRESS IS CALCULATED (SYNTAX ?)
  225. */
  226. }
  227. | CP CPRESTORE ea
  228. { T_EMIT2($2 | $1 | mrg_2,0,0,0);
  229. ea_2(SIZE_W, (mrg_2 & 070)==030 ? 0 : CTR);
  230. }
  231. | CP CPSAVE ea
  232. { T_EMIT2($2 | $1 | mrg_2,0,0,0);
  233. ea_2(SIZE_W,(mrg_2 & 070)==020 ? 0 : CTR|ALT);
  234. }
  235. | CP CPSCC cp_cond ea
  236. { T_EMIT2($2 | $1 | mrg_2,0,0,0);
  237. T_EMIT2($3,0,0,0);
  238. ea_2(SIZE_B,DTA|ALT);
  239. }
  240. | CP CPTRAPCC cp_cond SIZE imm
  241. { checksize($4,2|4);
  242. T_EMIT2($2 | $1 | ($4>>6)+1,0,0,0);
  243. T_EMIT2($3,0,0,0);
  244. ea_2($4, 0);
  245. }
  246. | CP TRAPCC cp_cond
  247. { T_EMIT2($2 | $1 | 4,0,0,0);
  248. T_EMIT2($3,0,0,0);
  249. }
  250. ;
  251. cp_cond : '.' absexp
  252. { fit(fit6($2));
  253. $$ = low6($2);
  254. }
  255. ;
  256. bcdx : ABCD
  257. | ADDX sizedef
  258. { $$ = $1 | $2;}
  259. ;
  260. creg : CREG
  261. | SPEC { if ($1 != 075)
  262. badoperand();
  263. $$ = 04000;
  264. }
  265. ;
  266. off_width /* note: these should be curly brackets, but that would
  267. * leave us without brackets for expressions.
  268. */
  269. : '[' abs31 ':' abs31 ']'
  270. { $$ = ($2<<6) | $4;
  271. }
  272. ;
  273. abs31 : DREG { $$ = 040 | $1;}
  274. | absexp { fit(fit5($1));
  275. $$ = low5($1);
  276. }
  277. ;
  278. op_ea : OP_EA
  279. | SZ_EA sizedef
  280. { $$ = $1 | $2;}
  281. ;
  282. regs : rrange
  283. | regs '/' rrange
  284. { $$ = $1 | $3;}
  285. ;
  286. rrange : reg
  287. { $$ = 1<<$1;}
  288. | reg '-' reg
  289. { if ($1 > $3)
  290. badoperand();
  291. for ($$ = 0; $1 <= $3; $1++)
  292. $$ |= (1<<$1);
  293. }
  294. ;
  295. ea : DREG
  296. { mrg_2 = $1;}
  297. | AREG
  298. { mrg_2 = 010 | $1;}
  299. | SPEC
  300. { mrg_2 = $1;}
  301. | { mrg_2 = 0; ffew_2 = 0400; /* initialization */}
  302. notimmreg
  303. | imm
  304. ;
  305. notimmreg
  306. : '(' AREG ')'
  307. { mrg_2 = 020 | $2;}
  308. | '(' AREG ')' '+'
  309. { mrg_2 = 030 | $2;}
  310. | '-' '(' AREG ')'
  311. { mrg_2 = 040 | $3;}
  312. | '(' expr ')' sizenon
  313. { bd_2 = $2; ea7071($4);
  314. RELOMOVE(bd_rel2, relonami);
  315. }
  316. | '(' bd_areg_index ')'
  317. { if ((mrg_2 & INDEX) == 0)
  318. ffew_2 |= 0100; /* suppress index */
  319. if ( !(mrg_2 & PC_MODE) &&
  320. (ffew_2 & 0300) == 0100 &&
  321. bd_2.typ==S_ABS && fitw(bd_2.val)
  322. )
  323. mrg_2 = (loww(bd_2.val)?050:020) | $2;
  324. else {
  325. mrg_2 = (mrg_2&PC_MODE)?073:(060 | $2);
  326. ffew_2 |= 060; /* long displacement */
  327. }
  328. }
  329. | '(' '[' bd_areg_index ']' index_od ')'
  330. { switch(mrg_2 & INDEX) {
  331. case 0:
  332. ffew_2 |= 0163; /* suppress index */
  333. break;
  334. case DBL_INDEX:
  335. serror("bad indexing");
  336. case PRE_INDEX:
  337. ffew_2 |= 063; break;
  338. case POST_INDEX:
  339. ffew_2 |= 067; break;
  340. }
  341. mrg_2 = (mrg_2 & PC_MODE) ? 073 : (060 | $3);
  342. }
  343. ;
  344. imm : '#' expr
  345. { mrg_2 = 074; bd_2 = $2;
  346. RELOMOVE(bd_rel2, relonami);
  347. }
  348. ;
  349. bd_areg_index
  350. : /* empty */
  351. { $$ = 0; ffew_2 |= 0200;
  352. /* base-reg suppressed */
  353. bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
  354. /* zero displacement */
  355. }
  356. | expr { $$ = 0; ffew_2 |= 0300;
  357. bd_2 = $1;
  358. RELOMOVE(bd_rel2, relonami);
  359. }
  360. | areg_index
  361. { bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
  362. }
  363. | expr ',' areg_index
  364. { $$ = $3; bd_2 = $1;
  365. RELOMOVE(bd_rel2, relonami);
  366. }
  367. ;
  368. areg_index
  369. : areg
  370. | index { $$ = 0;
  371. ffew_2 |= 0200; /* base-reg suppressed */
  372. mrg_2 |= PRE_INDEX;
  373. }
  374. | areg ',' index
  375. { mrg_2 |= PRE_INDEX;
  376. }
  377. ;
  378. areg : AREG
  379. | PC { mrg_2 |= PC_MODE;}
  380. | ZPC { mrg_2 |= PC_MODE;
  381. ffew_2 |= 0200; /* base-reg suppressed */
  382. }
  383. ;
  384. index : reg sizedef scale
  385. { checksize($2, 2|4);
  386. ffew_2 |= $1<<12 | ($2&0200)<<4 | $3;
  387. }
  388. ;
  389. scale : /* empty */
  390. { $$ = 0;}
  391. | '*' absexp
  392. { $$ = checkscale($2);}
  393. ;
  394. index_od: /* empty */
  395. { od_2.typ = S_ABS; od_2.val = (valu_t)0;}
  396. | ',' index
  397. { od_2.typ = S_ABS; od_2.val = (valu_t)0;
  398. mrg_2 |= POST_INDEX;
  399. }
  400. | ',' expr
  401. { od_2 = $2;
  402. RELOMOVE(od_rel2, relonami);
  403. }
  404. | ',' index ',' expr
  405. { od_2 = $4;
  406. mrg_2 |= POST_INDEX;
  407. RELOMOVE(od_rel2, relonami);
  408. }
  409. ;
  410. reg : DREG
  411. | AREG
  412. { $$ = $1 | 010;}
  413. ;
  414. sizedef : /* empty */
  415. { $$ = SIZE_DEF;}
  416. | SIZE
  417. ;
  418. sizenon : /* empty */
  419. { $$ = SIZE_NON;}
  420. | SIZE
  421. ;
  422. ea_ea : ea ','
  423. { mrg_1 = mrg_2;
  424. bd_1 = bd_2;
  425. od_1 = od_2;
  426. ffew_1 = ffew_2;
  427. RELOMOVE(bd_rel1, bd_rel2);
  428. RELOMOVE(od_rel1, od_rel2);
  429. }
  430. ea
  431. ;