mach4.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /* $Id$ */
  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. /* Please do not add more terminal symbols. As it is, 127 terminal symbols
  10. are used, and this is the limit for some "yacc" implementations,
  11. notably the Ultrix one.
  12. */
  13. operation
  14. : { instrp = instr;
  15. dot_offset = 0;
  16. curr_instr = curr_token;
  17. }
  18. instruction
  19. { emit_instr();
  20. }
  21. ;
  22. instruction
  23. : bcdx DREG ',' DREG
  24. { emit2($1 | $2 | $4<<9);}
  25. | bcdx '-' '(' AREG ')' ',' '-' '(' AREG ')'
  26. { emit2($1 | $4 | $9<<9 | 010);}
  27. | ADD sizedef ea_ea
  28. { add($1, $2);}
  29. | AND sizenon ea_ea
  30. { and($1, $2);}
  31. | SHIFT sizedef ea_ea
  32. { shift_op($1, $2);}
  33. | SHIFT sizedef ea /* This syntax is also allowed */
  34. { checksize($2, 2);
  35. T_EMIT2(($1 & 0177700) | mrg_2,0,0,0);
  36. ea_2(SIZE_W, MEM|ALT);
  37. }
  38. | BR expr
  39. { branch($1, $2);}
  40. | DBR DREG ',' expr
  41. { T_EMIT2($1 | $2,0,0,0);
  42. $4.val -= (DOTVAL+dot_offset);
  43. fit(fitw($4.val));
  44. T_EMIT2(loww($4.val), $4.typ,
  45. RELPC|RELO2, relonami);
  46. }
  47. | BITOP ea_ea
  48. { bitop($1);}
  49. | BITFIELD ea off_width
  50. { bitfield($1, $3);}
  51. | BF_TO_D ea off_width ',' DREG
  52. { bitfield($1, $3 | $5<<12);}
  53. | BFINS DREG ',' ea off_width
  54. { bitfield($1, $5 | $2<<12);}
  55. | DIVMUL sizedef ea ',' DREG
  56. { checksize($2, 2|4);
  57. if ($2 == SIZE_W) {
  58. T_EMIT2((0140300^($1<<8))|mrg_2|$5<<9,
  59. 0, 0, 0);
  60. ea_2(SIZE_W, DTA);
  61. }
  62. else { /* 32 bit dividend or product */
  63. T_EMIT2((046000 | ($1 & ~1)) | mrg_2,
  64. 0, 0, 0);
  65. T_EMIT2(($1&1)<<11 | $5<<12 | $5,
  66. 0, 0, 0);
  67. ea_2(SIZE_L, DTA);
  68. }
  69. }
  70. | DIVMUL sizedef ea ',' DREG ':' DREG
  71. { /* 64 bit dividend or product */
  72. checksize($2, 4);
  73. T_EMIT2((046000 | ($1 & ~1)) | mrg_2, 0, 0, 0);
  74. T_EMIT2(($1&1)<<11 | $7<<12 | $5 | 02000 ,0,0,0);
  75. ea_2(SIZE_L, DTA);
  76. }
  77. | DIVL sizedef ea ',' DREG ':' DREG
  78. { /* 32 bit long division with remainder */
  79. checksize($2, 4);
  80. T_EMIT2(($1 & ~1) | mrg_2, 0, 0, 0);
  81. T_EMIT2(($1 & 1)<<11 | $7<<12 | $5 , 0, 0, 0);
  82. ea_2(SIZE_L, DTA);
  83. }
  84. | LEA ea ',' AREG
  85. { T_EMIT2(040700 | mrg_2 | $4<<9,0,0,0);
  86. ea_2(SIZE_L, CTR);
  87. }
  88. | op_ea ea
  89. { if (mrg_2==074)
  90. serror("bad adressing category");
  91. T_EMIT2(($1&0177700) | mrg_2,0,0,0);
  92. ea_2($1&0300, $1&017);
  93. }
  94. | OP_NOOP
  95. { emit2($1);}
  96. | OP_EXT SIZE DREG
  97. { checksize($2, ($1 & 0400) ? 4 : (2|4));
  98. emit2($1 | $2+0100 | $3);
  99. }
  100. | OP_RANGE sizedef ea ',' reg
  101. { T_EMIT2(0300 | ($2<<3) | mrg_2,0,0,0);
  102. T_EMIT2($1 | ($5<<12),0,0,0);
  103. ea_2($2, CTR);
  104. }
  105. | TRAPCC SIZE imm
  106. { checksize($2, 2|4);
  107. T_EMIT2($1 | ($2>>6)+1,0,0,0);
  108. ea_2($2, 0);
  109. }
  110. | TRAPCC { emit2($1 | 4);}
  111. | PACK '-' '(' AREG ')' ',' '-' '(' AREG ')' ',' imm
  112. { T_EMIT2($1 | 8 | $4 | $9<<9, 0, 0, 0);
  113. ea_2(SIZE_W, 0);
  114. }
  115. | PACK DREG ',' DREG ',' imm
  116. { T_EMIT2($1 | $2 | $4<<9, 0, 0, 0);
  117. ea_2(SIZE_W, 0);
  118. }
  119. | CMP sizedef ea_ea
  120. { cmp($2);}
  121. | CHK sizedef ea ',' DREG
  122. { checksize($2, 2|4);
  123. T_EMIT2(040000 | mrg_2 | $5<<9 |
  124. ($2==SIZE_W ? 0600 : 0400),
  125. 0, 0, 0);
  126. ea_2($2, DTA);
  127. }
  128. | MOVE sizenon ea_ea
  129. { move($2);}
  130. | MOVEM sizedef regs ',' notimmreg
  131. { movem(0, $2, $3);}
  132. | MOVEM sizedef notimmreg ',' regs
  133. { movem(1, $2, $5);}
  134. | MOVESP sizedef
  135. { curr_size = $1; }
  136. ea_ea
  137. { if ($1 == 0) {
  138. /* movep */
  139. movep($2);
  140. } else if (mrg_1 <= 017) {
  141. T_EMIT2(007000 | $2 | mrg_2,0,0,0);
  142. T_EMIT2(mrg_1 << 12 | 04000,0,0,0);
  143. ea_2($2,ALT|MEM);
  144. } else if (mrg_2 <= 017) {
  145. T_EMIT2(007000 | $2 | mrg_1,0,0,0);
  146. T_EMIT2(mrg_2 << 12,0,0,0);
  147. ea_1($2,ALT|MEM);
  148. } else
  149. badoperand();
  150. }
  151. | MOVEC creg ',' reg
  152. { T_EMIT2(047172,0,0,0);
  153. T_EMIT2($2 | $4<<12,0,0,0);
  154. }
  155. | MOVEC reg ',' creg
  156. { T_EMIT2(047173,0,0,0);
  157. T_EMIT2($4 | $2<<12,0,0,0);
  158. }
  159. | EXG reg ',' reg
  160. { if (($2 & 010) == 0)
  161. emit2(
  162. (0140500|$4|$2<<9)
  163. +
  164. (($4&010)<<3)
  165. );
  166. else
  167. emit2(
  168. (0140610|$2|($4&07)<<9)
  169. -
  170. (($4&010)<<3)
  171. );
  172. }
  173. | SWAP DREG
  174. { emit2(044100 | $2);}
  175. | OP_IMM imm
  176. { T_EMIT2($1, 0, 0, 0);
  177. ea_2(SIZE_W, 0);
  178. }
  179. | LINK sizenon AREG ',' imm
  180. { link_instr($2, $3);}
  181. | UNLK AREG
  182. { emit2(047130 | $2);}
  183. | TRAP '#' absexp
  184. { fit(fit4($3));
  185. emit2(047100|low4($3));
  186. }
  187. | BKPT '#' absexp
  188. { fit(($3 & ~07) == 0);
  189. emit2(044110 | low3($3));
  190. }
  191. | CALLM '#' absexp ',' ea
  192. { fit(fitb($3));
  193. T_EMIT2(03300 | mrg_2,0,0,0);
  194. T_EMIT2((short) $3,0,0,0);
  195. ea_2(SIZE_L, CTR);
  196. }
  197. | RTM reg
  198. { emit2(03300 | $2);}
  199. | CAS sizedef DREG ',' DREG ',' ea
  200. { T_EMIT2(04300 | (($2+0100)<<3) | mrg_2,0,0,0);
  201. T_EMIT2($3 | ($5<<6),0,0,0);
  202. ea_2($2, MEM|ALT);
  203. }
  204. | CAS2 sizedef DREG ':' DREG ',' DREG ':' DREG ','
  205. '(' reg ')' ':' '(' reg ')'
  206. { checksize($2 , 2|4);
  207. emit2(04374 | (($2+0100)<<3));
  208. emit2($3 | ($7<<6) | ($12<<12));
  209. emit2($5 | ($9<<6) | ($16<<12));
  210. }
  211. | fp_op
  212. | mm_op
  213. ;
  214. bcdx : ABCD
  215. | ADDX sizedef
  216. { $$ = $1 | $2;}
  217. ;
  218. creg : CREG
  219. | SPEC { if ($1 != 075)
  220. badoperand();
  221. $$ = 04000;
  222. }
  223. ;
  224. off_width /* note: these should be curly brackets, but that would
  225. * leave us without brackets for expressions.
  226. */
  227. : '[' abs31 ':' abs31 ']'
  228. { $$ = ($2<<6) | $4;
  229. }
  230. ;
  231. abs31 : DREG { $$ = 040 | $1;}
  232. | absexp { fit(fit5($1));
  233. $$ = low5($1);
  234. }
  235. ;
  236. op_ea : OP_EA
  237. | SZ_EA sizedef
  238. { $$ = $1 | $2;}
  239. ;
  240. regs : rrange
  241. | regs '/' rrange
  242. { $$ = $1 | $3;}
  243. ;
  244. rrange : reg
  245. { $$ = 1<<$1;}
  246. | reg '-' reg
  247. { if ($1 > $3)
  248. badoperand();
  249. for ($$ = 0; $1 <= $3; $1++)
  250. $$ |= (1<<$1);
  251. }
  252. ;
  253. ea : DREG
  254. { mrg_2 = $1;}
  255. | AREG
  256. { mrg_2 = 010 | $1;}
  257. | SPEC
  258. { mrg_2 = $1;}
  259. | notimmreg
  260. | imm
  261. ;
  262. notimmreg
  263. :
  264. { mrg_2 = 0; ffew_2 = 0400; /* initialization */}
  265. notimmreg1
  266. ;
  267. notimmreg1
  268. : '(' AREG ')'
  269. { mrg_2 = 020 | $2;}
  270. | '(' AREG ')' '+'
  271. { mrg_2 = 030 | $2;}
  272. | '-' '(' AREG ')'
  273. { mrg_2 = 040 | $3;}
  274. | '(' expr ')' sizenon
  275. { bd_2 = $2; ea7071($4);
  276. RELOMOVE(bd_rel2, relonami);
  277. }
  278. | '(' bd_areg_index ')'
  279. { if ((mrg_2 & INDEX) == 0)
  280. ffew_2 |= 0100; /* suppress index */
  281. if ( !(mrg_2 & PC_MODE) &&
  282. (ffew_2 & 0300) == 0100 &&
  283. bd_2.typ==S_ABS && fitw(bd_2.val)
  284. )
  285. mrg_2 = (loww(bd_2.val)?050:020) | $2;
  286. else {
  287. mrg_2 = (mrg_2&PC_MODE)?073:(060 | $2);
  288. ffew_2 |= 060; /* long displacement */
  289. }
  290. }
  291. | '(' '[' bd_areg_index ']' index_od ')'
  292. { switch(mrg_2 & INDEX) {
  293. case 0:
  294. ffew_2 |= 0163; /* suppress index */
  295. break;
  296. case DBL_INDEX:
  297. serror("bad indexing");
  298. case PRE_INDEX:
  299. ffew_2 |= 063; break;
  300. case POST_INDEX:
  301. ffew_2 |= 067; break;
  302. }
  303. mrg_2 = (mrg_2 & PC_MODE) ? 073 : (060 | $3);
  304. }
  305. ;
  306. imm : '#' expr
  307. { mrg_2 = 074; bd_2 = $2;
  308. RELOMOVE(bd_rel2, relonami);
  309. }
  310. ;
  311. bd_areg_index
  312. : /* empty */
  313. { $$ = 0; ffew_2 |= 0200;
  314. /* base-reg suppressed */
  315. bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
  316. /* zero displacement */
  317. }
  318. | expr { $$ = 0; ffew_2 |= 0200;
  319. bd_2 = $1;
  320. RELOMOVE(bd_rel2, relonami);
  321. }
  322. | areg_index
  323. { bd_2.typ = S_ABS; bd_2.val = (valu_t)0;
  324. }
  325. | expr ',' areg_index
  326. { $$ = $3; bd_2 = $1;
  327. RELOMOVE(bd_rel2, relonami);
  328. }
  329. ;
  330. areg_index
  331. : areg
  332. | index { $$ = 0;
  333. ffew_2 |= 0200; /* base-reg suppressed */
  334. mrg_2 |= PRE_INDEX;
  335. }
  336. | areg ',' index
  337. { mrg_2 |= PRE_INDEX;
  338. }
  339. ;
  340. areg : AREG
  341. | PC { mrg_2 |= PC_MODE;
  342. ffew_2 |= $1; /* base-reg suppressed for zpc */
  343. $$ = 0;
  344. }
  345. ;
  346. index : reg sizedef scale
  347. { checksize($2, 2|4);
  348. ffew_2 |= $1<<12 | ($2&0200)<<4 | $3;
  349. }
  350. ;
  351. scale : /* empty */
  352. { $$ = 0;}
  353. | '*' absexp
  354. { $$ = checkscale($2);}
  355. ;
  356. index_od: /* empty */
  357. { od_2.typ = S_ABS; od_2.val = (valu_t)0;}
  358. | ',' index
  359. { od_2.typ = S_ABS; od_2.val = (valu_t)0;
  360. mrg_2 |= POST_INDEX;
  361. }
  362. | ',' expr
  363. { od_2 = $2;
  364. RELOMOVE(od_rel2, relonami);
  365. }
  366. | ',' index ',' expr
  367. { od_2 = $4;
  368. mrg_2 |= POST_INDEX;
  369. RELOMOVE(od_rel2, relonami);
  370. }
  371. ;
  372. reg : DREG
  373. | AREG
  374. { $$ = $1 | 010;}
  375. ;
  376. sizedef : /* empty */
  377. { $$ = SIZE_DEF; curr_size = SIZE_DEF; }
  378. | SIZE { curr_size = $1; $$ = $1; }
  379. ;
  380. sizenon : /* empty */
  381. { $$ = SIZE_NON;}
  382. | SIZE
  383. ;
  384. ea_ea : ea ','
  385. { mrg_1 = mrg_2;
  386. bd_1 = bd_2;
  387. od_1 = od_2;
  388. ffew_1 = ffew_2;
  389. RELOMOVE(bd_rel1, bd_rel2);
  390. RELOMOVE(od_rel1, od_rel2);
  391. }
  392. ea
  393. ;
  394. fp_op : CP
  395. { co_id = $1; }
  396. fp_op1
  397. | { co_id = DEF_FP; }
  398. fp_op1
  399. ;
  400. fp_op1 : FMOVE fsize ea ',' FPCR
  401. { check_fsize($2, FSIZE_L);
  402. if ((mrg_2&070) == 010 && $5 != 001)
  403. badoperand();
  404. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  405. T_EMIT2((0100000|($5<<10)),0,0,0);
  406. ea_2(SIZE_L, 0);
  407. }
  408. | FMOVE fsize FPCR ',' ea
  409. { check_fsize($2, FSIZE_L);
  410. if ((mrg_2&070) == 010 && $3 == 001)
  411. badoperand();
  412. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  413. T_EMIT2((0120000|($3<<10)),0,0,0);
  414. ea_2(SIZE_L, ALT);
  415. }
  416. | FMOVE fsize FPREG ',' FPREG
  417. { emit2(0170000|co_id);
  418. emit2(($3<<10)|($5<<7));
  419. }
  420. | FMOVE fsize ea ',' FPREG
  421. { ch_sz_dreg($2, mrg_2&070);
  422. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  423. T_EMIT2((0040000|($2<<10)|($5<<7)),0,0,0);
  424. ea_2(SIZE_L, DTA);
  425. }
  426. | FMOVE fsize FPREG ',' ea
  427. { ch_sz_dreg($2, mrg_2&070);
  428. if ($2 == FSIZE_P)
  429. serror("packed decimal needs k-factor");
  430. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  431. T_EMIT2((0060000|($2<<10)|($3<<7)),0,0,0);
  432. ea_2(SIZE_L, DTA|ALT);
  433. }
  434. | FMOVE fsize FPREG ',' ea '{' '#' absexp '}'
  435. { check_fsize($2, FSIZE_P);
  436. fit(sfit7($8));
  437. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  438. T_EMIT2((0066000|($3<<7)|low7($8)),0,0,0);
  439. ea_2(SIZE_L, MEM|DTA|ALT);
  440. }
  441. | FMOVE fsize FPREG ',' ea '{' DREG '}'
  442. { check_fsize($2, FSIZE_P);
  443. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  444. T_EMIT2((0076000|($3<<7)|($7<<4)),0,0,0);
  445. ea_2(SIZE_L, MEM|DTA|ALT);
  446. }
  447. | FMOVECR fsize '#' absexp ',' FPREG
  448. { fit(fit7($4));
  449. check_fsize($2, FSIZE_X);
  450. emit2(0170000|co_id);
  451. emit2(056000|($6<<7)|low7($4));
  452. }
  453. | FMOVEM FSIZE fregs ',' notimmreg
  454. { check_fsize($2, FSIZE_X);
  455. if ((mrg_2&070) == 030)
  456. serror("bad addressing category");
  457. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  458. T_EMIT2(0160000 |
  459. (((mrg_2&070)==040 || ($3&04000)) ?
  460. $3 :
  461. (010000|reverse($3,8))),
  462. 0,0,0);
  463. ea_2(SIZE_L, MEM|ALT);
  464. }
  465. | FMOVEM FSIZE notimmreg ',' fregs
  466. { check_fsize($2, FSIZE_X);
  467. if ((mrg_2&070) == 040)
  468. serror("bad addressing category");
  469. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  470. T_EMIT2((0150000|(($5&04000)?$5:reverse($5,8))),0,0,0);
  471. ea_2(SIZE_L, MEM);
  472. }
  473. | FMOVEM SIZE fcregs ',' ea
  474. { checksize($2, 4);
  475. if ((mrg_2&070) == 1 && $3!= 02000)
  476. serror("bad addressing category");
  477. if ((mrg_2 & 070) == 0 &&
  478. $3 != 02000 && $3 != 04000 && $3 != 010000)
  479. serror("bad addressing category");
  480. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  481. T_EMIT2((0120000|$3),0,0,0);
  482. ea_2(SIZE_L, ALT);
  483. }
  484. | FMOVEM SIZE ea ',' fcregs
  485. { checksize($2, 4);
  486. if ((mrg_2&070) == 1 && $5!= 02000)
  487. serror("bad addressing category");
  488. if ((mrg_2 & 070) == 0 &&
  489. $5 != 02000 && $5 != 04000 && $5 != 010000)
  490. serror("bad addressing category");
  491. T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  492. T_EMIT2((0100000|$5),0,0,0);
  493. ea_2(SIZE_L, 0);
  494. }
  495. | FDYADIC fsize ea ',' FPREG
  496. { T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  497. T_EMIT2((0040000|($2<<10)|($5<<7)|$1),0,0,0);
  498. ch_sz_dreg($2, mrg_2&070);
  499. ea_2(SIZE_L, DTA);
  500. }
  501. | FDYADIC fsize FPREG ',' FPREG
  502. { check_fsize($2, FSIZE_X);
  503. emit2(0170000|co_id);
  504. emit2(($3<<10)|($5<<7)|$1);
  505. }
  506. | FMONADIC fsize ea ',' FPREG
  507. { T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  508. T_EMIT2((0040000|($2<<10)|($5<<7)|$1),0,0,0);
  509. ch_sz_dreg($2, mrg_2&070);
  510. ea_2(SIZE_L, DTA);
  511. }
  512. | FMONADIC fsize FPREG ',' FPREG
  513. { check_fsize($2, FSIZE_X);
  514. emit2(0170000|co_id);
  515. emit2(($3<<10)|($5<<7)|$1);
  516. }
  517. | FMONADIC fsize FPREG
  518. { check_fsize($2, FSIZE_X);
  519. emit2(0170000|co_id);
  520. emit2(($3<<10)|($3<<7)|$1);
  521. }
  522. | FSINCOS fsize ea ',' FPREG ':' FPREG
  523. { T_EMIT2(0170000|co_id|mrg_2,0,0,0);
  524. T_EMIT2(0040000|($2<<10)|($7<<7)|$1|$5,0,0,0);
  525. ea_2(SIZE_L, DTA);
  526. }
  527. | FSINCOS fsize FPREG ',' FPREG ':' FPREG
  528. { check_fsize($2, FSIZE_X);
  529. emit2(0170000|co_id);
  530. emit2(($3<<10)|($7<<7)|$1|$5);
  531. }
  532. | FBCC expr
  533. { fbranch($1, $2);}
  534. | FDBCC DREG ',' expr
  535. { T_EMIT2(0170110|co_id|$2,0,0,0);
  536. T_EMIT2($1,0,0,0);
  537. $4.val -= (DOTVAL+dot_offset);
  538. fit(fitw($4.val));
  539. T_EMIT2(loww($4.val), $4.typ,
  540. RELPC|RELO2,relonami);
  541. }
  542. | FNOP
  543. { emit2(0170200|co_id);
  544. emit2(0);
  545. }
  546. | FSCC ea
  547. { T_EMIT2(0170100|co_id|mrg_2,0,0,0);
  548. T_EMIT2($1,0,0,0);
  549. ea_2(SIZE_B, DTA|ALT);
  550. }
  551. | FTST fsize ea
  552. { T_EMIT2((0170000|co_id|mrg_2),0,0,0);
  553. T_EMIT2((0040072|($2<<10)),0,0,0);
  554. ch_sz_dreg($2, mrg_2&070);
  555. ea_2(SIZE_L, DTA);
  556. }
  557. | FTST fsize FPREG
  558. { check_fsize($2, FSIZE_X);
  559. emit2(0170000|co_id);
  560. emit2(($3<<10)|072);
  561. }
  562. | FSAVRES ea
  563. { if ((mrg_2&070) == ($1&070))
  564. badoperand();
  565. T_EMIT2((0170000|co_id|($1&0700)|mrg_2),0,0,0);
  566. ea_2(0, $1&07);
  567. }
  568. | FTRAPCC
  569. { emit2(0170174|co_id);
  570. emit2($1);
  571. }
  572. | FTRAPCC SIZE imm
  573. { checksize($2, 2|4);
  574. T_EMIT2((0170170|co_id|($2==SIZE_L?03:02)),
  575. 0,0,0);
  576. T_EMIT2($1,0,0,0);
  577. ea_2($2,0);
  578. }
  579. ;
  580. fregs : DREG
  581. { $$ = 04000 | $1 << 4; }
  582. | frlist
  583. ;
  584. frlist : frrange
  585. | frlist '/' frrange
  586. { $$ = $1 | $3;}
  587. ;
  588. frrange : FPREG
  589. { $$ = 1 << $1; }
  590. | FPREG '-' FPREG
  591. { if ($1 > $3)
  592. badoperand();
  593. for ($$ = 0; $1 <= $3; $1++)
  594. $$ |= (1 << $1);
  595. }
  596. ;
  597. fcregs : FPCR
  598. { $$ = $1 << 10; }
  599. | fcregs '/' FPCR
  600. { $$ = $1 | ($3 << 10); }
  601. ;
  602. fsize : /* empty */
  603. { $$ = FSIZE_X; }
  604. | SIZE
  605. { if ($1 == SIZE_L)
  606. $$ = FSIZE_L;
  607. else if ($1 == SIZE_W)
  608. $$ = FSIZE_W;
  609. else $$ = FSIZE_B;
  610. }
  611. | FSIZE
  612. ;
  613. mm_op : CP
  614. { co_id = $1; }
  615. mm_op1
  616. | { co_id = DEF_MM; }
  617. mm_op1
  618. ;
  619. mm_op1 : /* Coprocessor instructions; syntax may be changed (please).
  620. * No coprocessor defined extension words are emitted.
  621. */
  622. CPBCC cp_cond expr
  623. { cpbcc($1 | co_id | $2, $3);
  624. }
  625. | CPDBCC cp_cond DREG ',' expr
  626. { T_EMIT2($1 | co_id | $3,0,0,0);
  627. $5.val -= (DOTVAL+dot_offset);
  628. fit(fitw($5.val));
  629. T_EMIT2(loww($5.val), $5.typ,
  630. RELPC|RELO2, relonami);
  631. }
  632. | CPGEN
  633. { T_EMIT2($1 | co_id,0,0,0);
  634. /* NO COMMAND WORD IS EMITTED;
  635. * THIS INSTRUCTIONS IS (STILL) ONE BIG RIDDLE.
  636. * NO EFFECTIVE ADDRESS IS CALCULATED (SYNTAX ?)
  637. */
  638. }
  639. | CPSAVREST ea
  640. { T_EMIT2($1 | co_id | mrg_2,0,0,0);
  641. if ($1 & 0100) {
  642. /* restore */
  643. ea_2(SIZE_W, (mrg_2 & 070)==030 ? 0 : CTR);
  644. }
  645. else ea_2(SIZE_W,(mrg_2 & 070)==020 ? 0 : CTR|ALT);
  646. }
  647. | CPSCC cp_cond ea
  648. { T_EMIT2($1 | co_id | mrg_2,0,0,0);
  649. T_EMIT2($2,0,0,0);
  650. ea_2(SIZE_B,DTA|ALT);
  651. }
  652. | CPTRAPCC cp_cond SIZE imm
  653. { checksize($3,2|4);
  654. T_EMIT2($1 | co_id | ($3>>6)+1,0,0,0);
  655. T_EMIT2($2,0,0,0);
  656. ea_2($3, 0);
  657. }
  658. | CPTRAPCC cp_cond
  659. { emit2($1 | co_id | 4);
  660. emit2($2);
  661. }
  662. /* M68030 MMU instructions */
  663. | PFLUSHA
  664. { emit2(0170000);
  665. emit2($1);
  666. }
  667. | PFLUSH fc ',' mask
  668. { emit2(0170000);
  669. emit2($1|010000|($4<<5)|$2);
  670. }
  671. | PFLUSH fc ',' mask ',' ea
  672. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  673. T_EMIT2($1|014000|($4<<5)|$2, 0, 0, 0);
  674. ea_2(SIZE_L, DTA|CTR);
  675. }
  676. | PTEST fc ',' ea ',' mask
  677. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  678. T_EMIT2($1|($6<<10)|$2, 0, 0, 0);
  679. ea_2(SIZE_L, DTA|CTR);
  680. }
  681. | PTEST fc ',' ea ',' mask ',' AREG
  682. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  683. T_EMIT2($1|($6<<10)|$2|0400|($8<<5), 0, 0, 0);
  684. ea_2(SIZE_L, DTA|CTR);
  685. }
  686. | PLOAD fc ',' ea
  687. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  688. T_EMIT2($1|$2, 0, 0, 0);
  689. ea_2(SIZE_L, DTA|CTR);
  690. }
  691. | PMOVE MREG ',' ea
  692. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  693. T_EMIT2($1|$2|01000, 0, 0, 0);
  694. ea_2(SIZE_L, DTA|CTR);
  695. }
  696. | PMOVE ea ',' MREG
  697. { T_EMIT2(0170000|mrg_2, 0, 0, 0);
  698. T_EMIT2($1|$4, 0, 0, 0);
  699. ea_2(SIZE_L, DTA|CTR);
  700. }
  701. ;
  702. mask : '#' absexp
  703. { fit(fit3($2));
  704. $$ = low3($2);
  705. }
  706. ;
  707. fc : '#' absexp
  708. { fit(fit3($2));
  709. $$ = (020|low3($2));
  710. }
  711. | DREG
  712. { $$ = (010|$1); }
  713. | CREG
  714. { if ($1 > 1) serror("illegal control register");
  715. $$ = ($1&01);
  716. }
  717. ;
  718. cp_cond : DOT absexp
  719. { fit(fit6($2));
  720. $$ = low6($2);
  721. }
  722. ;