mach4.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  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. /* @(#)mach4.c 1.11 */
  7. /*
  8. * Motorola 68000/68010 syntax rules
  9. */
  10. operation
  11. : { curr_instr = curr_token; }
  12. _operation
  13. ;
  14. _operation
  15. : bcdx DREG ',' DREG
  16. { emit2($1 | $2 | $4<<9);}
  17. | bcdx '-' '(' AREG ')' ',' '-' '(' AREG ')'
  18. { emit2($1 | $4 | $9<<9 | 010);}
  19. | ADD sizedef ea_ea
  20. { add($1, $2);}
  21. | AND sizenon ea_ea
  22. { and($1, $2);}
  23. | SHIFT sizedef ea_ea
  24. { shift_op($1, $2);}
  25. | BR expr
  26. { branch($1, $2);}
  27. | DBR DREG ',' expr
  28. { $4.val -= (DOTVAL+2);
  29. Xfit(fitw($4.val));
  30. emit2($1 | $2);
  31. #ifdef RELOCATION
  32. newrelo($4.typ, RELPC|RELO2|RELBR|RELWR);
  33. #endif
  34. emit2(loww($4.val));
  35. }
  36. | BITOP ea_ea
  37. { bitop($1);}
  38. | OP_EA_D sizedef ea ',' DREG
  39. { if ($2 != SIZE_W) {
  40. serror("illegal size");
  41. }
  42. emit2($1 | mrg_2 | $5<<9);
  43. ea_2(SIZE_W, DTA);
  44. }
  45. | LEA ea ',' AREG
  46. { emit2(040700 | mrg_2 | $4<<9);
  47. ea_2(SIZE_L, CTR);
  48. }
  49. | op_ea ea
  50. { emit2(($1&0177700) | mrg_2);
  51. ea_2($1&0300, $1&017);
  52. }
  53. | OP_NOOP
  54. { emit2($1);}
  55. | CMP sizedef ea_ea
  56. { cmp($2);}
  57. | MOVE sizenon ea_ea
  58. { move($2);}
  59. | MOVEP sizedef ea_ea
  60. { movep($2);}
  61. | MOVEM sizedef regs ',' notimmreg
  62. { movem(0, $2, $3);}
  63. | MOVEM sizedef notimmreg ',' regs
  64. { movem(1, $2, $5);}
  65. | MOVES sizedef ea_ea
  66. { test68010();
  67. if (mrg_1 <= 017) {
  68. emit2(007000 | $2 | mrg_2);
  69. emit2(mrg_1 << 12 | 04000);
  70. ea_2($2,ALT|MEM);
  71. } else if (mrg_2 <= 017) {
  72. emit2(007000 | $2 | mrg_1);
  73. emit2(mrg_2 << 12);
  74. ea_1($2,ALT|MEM);
  75. } else
  76. badoperand();
  77. }
  78. | MOVEC creg ',' reg
  79. { test68010();
  80. emit2(047172); emit2($2 | $4<<12);
  81. }
  82. | MOVEC reg ',' creg
  83. { test68010();
  84. emit2(047173); emit2($4 | $2<<12);
  85. }
  86. | EXG reg ',' reg
  87. { if (($2 & 010) == 0)
  88. emit2(
  89. (0140500|$4|$2<<9)
  90. +
  91. (($4&010)<<3)
  92. );
  93. else
  94. emit2(
  95. (0140610|$2|($4&07)<<9)
  96. -
  97. (($4&010)<<3)
  98. );
  99. }
  100. | OP_EXT sizedef DREG
  101. { checksize($2, 2|4); emit2(044000 | $2+0100 | $3);}
  102. | SWAP DREG
  103. { emit2(044100 | $2);}
  104. | STOP imm
  105. { emit2($1); ea_2(SIZE_W, 0);}
  106. | LINK AREG ',' imm
  107. { emit2(047120 | $2); ea_2(SIZE_W, 0);}
  108. | UNLK AREG
  109. { emit2(047130 | $2);}
  110. | TRAP '#' absexp
  111. { Xfit(fit4($3)); emit2(047100|low4($3));}
  112. | RTD imm
  113. { test68010();
  114. emit2(047164);
  115. ea_2(SIZE_W, 0);
  116. }
  117. | MODEL
  118. { model = $1;}
  119. | fp_op
  120. ;
  121. bcdx : ABCD
  122. | ADDX sizedef
  123. { $$ = $1 | $2;}
  124. ;
  125. creg : CREG
  126. | SPEC { if ($1 != 075) badoperand(); $$ = 04000;}
  127. ;
  128. op_ea : OP_EA
  129. | SZ_EA sizedef
  130. { $$ = $1 | $2;}
  131. ;
  132. regs : rrange
  133. | regs '/' rrange
  134. { $$ = $1 | $3;}
  135. ;
  136. rrange : reg
  137. { $$ = 1<<$1;}
  138. | reg '-' reg
  139. { if ($1 > $3)
  140. badoperand();
  141. for ($$ = 0; $1 <= $3; $1++)
  142. $$ |= (1<<$1);
  143. }
  144. ;
  145. ea : DREG
  146. { mrg_2 = $1;}
  147. | AREG
  148. { mrg_2 = 010 | $1;}
  149. | SPEC
  150. { mrg_2 = $1;}
  151. | notimmreg
  152. | imm
  153. ;
  154. notimmreg
  155. : '(' AREG ')'
  156. { mrg_2 = 020 | $2;}
  157. | '(' AREG ')' '+'
  158. { mrg_2 = 030 | $2;}
  159. | '-' '(' AREG ')'
  160. { mrg_2 = 040 | $3;}
  161. | expr sizenon
  162. { exp_2 = $1; ea707172($2);
  163. RELOMOVE(rel_2, relonami);
  164. }
  165. | expr '(' reg sizenon ')'
  166. { exp_2 = $1; ea5x73($3, $4);
  167. RELOMOVE(rel_2, relonami);
  168. }
  169. | expr '(' AREG ',' reg sizedef ')'
  170. { exp_2 = $1; ea6x($3, $5, $6);
  171. RELOMOVE(rel_2, relonami);
  172. }
  173. | expr '(' PC ')'
  174. { exp_2 = $1; ea72();
  175. RELOMOVE(rel_2, relonami);
  176. }
  177. | expr '(' PC ',' reg sizedef ')'
  178. { exp_2 = $1; ea73($5, $6);
  179. RELOMOVE(rel_2, relonami);
  180. }
  181. ;
  182. imm : '#' expr
  183. { mrg_2 = 074; exp_2 = $2;
  184. RELOMOVE(rel_2, relonami);
  185. }
  186. ;
  187. reg : DREG
  188. | AREG
  189. { $$ = $1 | 010;}
  190. ;
  191. sizedef : /* empty */
  192. { $$ = SIZE_DEF;}
  193. | SIZE
  194. ;
  195. sizenon : /* empty */
  196. { $$ = SIZE_NON;}
  197. | SIZE
  198. ;
  199. ea_ea : ea ','
  200. { mrg_1 = mrg_2; exp_1 = exp_2;
  201. RELOMOVE(rel_1, rel_2);
  202. }
  203. ea
  204. ;
  205. fp_op : CP
  206. { co_id = $1; }
  207. fp_op1
  208. | { co_id = DEF_FP; }
  209. fp_op1
  210. ;
  211. fp_op1 : FMOVE fsize ea ',' FPCR
  212. { check_fsize($2, FSIZE_L);
  213. if ((mrg_2&070) == 010 && $5 != 001)
  214. badoperand();
  215. emit2((0170000|co_id|mrg_2));
  216. emit2((0100000|($5<<10)));
  217. ea_2(SIZE_L, 0);
  218. }
  219. | FMOVE fsize FPCR ',' ea
  220. { check_fsize($2, FSIZE_L);
  221. if ((mrg_2&070) == 010 && $3 == 001)
  222. badoperand();
  223. emit2((0170000|co_id|mrg_2));
  224. emit2((0120000|($3<<10)));
  225. ea_2(SIZE_L, ALT);
  226. }
  227. | FMOVE fsize FPREG ',' FPREG
  228. { emit2(0170000|co_id);
  229. emit2(($3<<10)|($5<<7));
  230. }
  231. | FMOVE fsize ea ',' FPREG
  232. { ch_sz_dreg($2, mrg_2&070);
  233. emit2((0170000|co_id|mrg_2));
  234. emit2((0040000|($2<<10)|($5<<7)));
  235. ea_2(SIZE_L, DTA);
  236. }
  237. | FMOVE fsize FPREG ',' ea
  238. { ch_sz_dreg($2, mrg_2&070);
  239. if ($2 == FSIZE_P)
  240. serror("packed decimal needs k-factor");
  241. emit2((0170000|co_id|mrg_2));
  242. emit2((0060000|($2<<10)|($3<<7)));
  243. ea_2(SIZE_L, DTA|ALT);
  244. }
  245. | FMOVE fsize FPREG ',' ea '{' '#' absexp '}'
  246. { check_fsize($2, FSIZE_P);
  247. fit(sfit7($8));
  248. emit2((0170000|co_id|mrg_2));
  249. emit2((0066000|($3<<7)|low7($8)));
  250. ea_2(SIZE_L, MEM|DTA|ALT);
  251. }
  252. | FMOVE fsize FPREG ',' ea '{' DREG '}'
  253. { check_fsize($2, FSIZE_P);
  254. emit2((0170000|co_id|mrg_2));
  255. emit2((0076000|($3<<7)|($7<<4)));
  256. ea_2(SIZE_L, MEM|DTA|ALT);
  257. }
  258. | FMOVECR fsize '#' absexp ',' FPREG
  259. { fit(fit7($4));
  260. check_fsize($2, FSIZE_X);
  261. emit2(0170000|co_id);
  262. emit2(056000|($6<<7)|low7($4));
  263. }
  264. | FMOVEM FSIZE fregs ',' notimmreg
  265. { check_fsize($2, FSIZE_X);
  266. if ((mrg_2&070) == 030)
  267. serror("bad addressing category");
  268. emit2((0170000|co_id|mrg_2));
  269. emit2(0160000 |
  270. (((mrg_2&070)==040 || ($3&04000)) ?
  271. $3 :
  272. (010000|reverse($3,8))));
  273. ea_2(SIZE_L, MEM|ALT);
  274. }
  275. | FMOVEM FSIZE notimmreg ',' fregs
  276. { check_fsize($2, FSIZE_X);
  277. if ((mrg_2&070) == 040)
  278. serror("bad addressing category");
  279. emit2((0170000|co_id|mrg_2));
  280. emit2((0150000|(($5&04000)?$5:reverse($5,8))));
  281. ea_2(SIZE_L, MEM);
  282. }
  283. | FMOVEM SIZE fcregs ',' ea
  284. { checksize($2, 4);
  285. if ((mrg_2&070) == 1 && $3!= 02000)
  286. serror("bad addressing category");
  287. if ((mrg_2 & 070) == 0 &&
  288. $3 != 02000 && $3 != 04000 && $3 != 010000)
  289. serror("bad addressing category");
  290. emit2((0170000|co_id|mrg_2));
  291. emit2((0120000|$3));
  292. ea_2(SIZE_L, ALT);
  293. }
  294. | FMOVEM SIZE ea ',' fcregs
  295. { checksize($2, 4);
  296. if ((mrg_2&070) == 1 && $5!= 02000)
  297. serror("bad addressing category");
  298. if ((mrg_2 & 070) == 0 &&
  299. $5 != 02000 && $5 != 04000 && $5 != 010000)
  300. serror("bad addressing category");
  301. emit2((0170000|co_id|mrg_2));
  302. emit2((0100000|$5));
  303. ea_2(SIZE_L, 0);
  304. }
  305. | FDYADIC fsize ea ',' FPREG
  306. { emit2((0170000|co_id|mrg_2));
  307. emit2((0040000|($2<<10)|($5<<7)|$1));
  308. ch_sz_dreg($2, mrg_2&070);
  309. ea_2(SIZE_L, DTA);
  310. }
  311. | FDYADIC fsize FPREG ',' FPREG
  312. { check_fsize($2, FSIZE_X);
  313. emit2(0170000|co_id);
  314. emit2(($3<<10)|($5<<7)|$1);
  315. }
  316. | FMONADIC fsize ea ',' FPREG
  317. { emit2((0170000|co_id|mrg_2));
  318. emit2((0040000|($2<<10)|($5<<7)|$1));
  319. ch_sz_dreg($2, mrg_2&070);
  320. ea_2(SIZE_L, DTA);
  321. }
  322. | FMONADIC fsize FPREG ',' FPREG
  323. { check_fsize($2, FSIZE_X);
  324. emit2(0170000|co_id);
  325. emit2(($3<<10)|($5<<7)|$1);
  326. }
  327. | FMONADIC fsize FPREG
  328. { check_fsize($2, FSIZE_X);
  329. emit2(0170000|co_id);
  330. emit2(($3<<10)|($3<<7)|$1);
  331. }
  332. | FSINCOS fsize ea ',' FPREG ':' FPREG
  333. { emit2(0170000|co_id|mrg_2);
  334. emit2(0040000|($2<<10)|($7<<7)|$1|$5);
  335. ea_2(SIZE_L, DTA);
  336. }
  337. | FSINCOS fsize FPREG ',' FPREG ':' FPREG
  338. { check_fsize($2, FSIZE_X);
  339. emit2(0170000|co_id);
  340. emit2(($3<<10)|($7<<7)|$1|$5);
  341. }
  342. | FBCC expr
  343. { fbranch($1, $2);}
  344. | FDBCC DREG ',' expr
  345. { emit2(0170110|co_id|$2);
  346. emit2($1);
  347. $4.val -= DOTVAL;
  348. fit(fitw($4.val));
  349. #ifdef RELOCATION
  350. newrelo($4.typ, RELPC|RELO2|RELBR|RELWR);
  351. #endif
  352. emit2(loww($4.val));
  353. }
  354. | FNOP
  355. { emit2(0170200|co_id);
  356. emit2(0);
  357. }
  358. | FSCC ea
  359. { emit2(0170100|co_id|mrg_2);
  360. emit2($1);
  361. ea_2(SIZE_B, DTA|ALT);
  362. }
  363. | FTST fsize ea
  364. { emit2((0170000|co_id|mrg_2));
  365. emit2((0040072|($2<<10)));
  366. ch_sz_dreg($2, mrg_2&070);
  367. ea_2(SIZE_L, DTA);
  368. }
  369. | FTST fsize FPREG
  370. { check_fsize($2, FSIZE_X);
  371. emit2(0170000|co_id);
  372. emit2(($3<<10)|072);
  373. }
  374. | FSAVRES ea
  375. { if ((mrg_2&070) == ($1&070))
  376. badoperand();
  377. emit2((0170000|co_id|($1&0700)|mrg_2));
  378. ea_2(0, $1&07);
  379. }
  380. | FTRAPCC
  381. { emit2(0170174|co_id);
  382. emit2($1);
  383. }
  384. | FTRAPCC SIZE imm
  385. { checksize($2, 2|4);
  386. emit2((0170170|co_id|($2==SIZE_L?03:02)));
  387. emit2($1);
  388. ea_2($2,0);
  389. }
  390. ;
  391. fregs : DREG
  392. { $$ = 04000 | $1 << 4; }
  393. | frlist
  394. ;
  395. frlist : frrange
  396. | frlist '/' frrange
  397. { $$ = $1 | $3;}
  398. ;
  399. frrange : FPREG
  400. { $$ = 1 << $1; }
  401. | FPREG '-' FPREG
  402. { if ($1 > $3)
  403. badoperand();
  404. for ($$ = 0; $1 <= $3; $1++)
  405. $$ |= (1 << $1);
  406. }
  407. ;
  408. fcregs : FPCR
  409. { $$ = $1 << 10; }
  410. | fcregs '/' FPCR
  411. { $$ = $1 | ($3 << 10); }
  412. ;
  413. fsize : /* empty */
  414. { $$ = FSIZE_X; }
  415. | SIZE
  416. { if ($1 == SIZE_L)
  417. $$ = FSIZE_L;
  418. else if ($1 == SIZE_W)
  419. $$ = FSIZE_W;
  420. else $$ = FSIZE_B;
  421. }
  422. | FSIZE
  423. ;