mach5.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  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. /* @(#)mach5.c 1.16 */
  7. /*
  8. * Motorola 68000/68010 auxiliary functions
  9. */
  10. static int
  11. extension_offset()
  12. {
  13. switch(curr_instr) {
  14. case MOVEM:
  15. case FMOVE:
  16. case FMOVEM:
  17. case FDYADIC:
  18. case FMONADIC:
  19. case FSINCOS:
  20. case FSCC:
  21. case FTST:
  22. return 4;
  23. }
  24. return 2;
  25. }
  26. ea_1(sz, bits)
  27. {
  28. register flag;
  29. if (mrg_1 > 074)
  30. serror("no specials");
  31. if ((flag = eamode[mrg_1>>3]) == 0)
  32. if ((flag = eamode[010 + (mrg_1&07)]) == 0)
  33. flag = eamode[015 + (sz>>6)];
  34. if ((mrg_1 & 070) == 010)
  35. checksize(sz, 2|4);
  36. bits &= ~flag;
  37. if (bits)
  38. serror("bad addressing category");
  39. if (flag & FITW)
  40. Xfit (fitw(exp_1.val) ||
  41. (mrg_1 == 074 && fit16(exp_1.val))
  42. ) ;
  43. if (flag & FITB) {
  44. Xfit (fitb(exp_1.val) ||
  45. (mrg_1 == 074 && fit8(exp_1.val))
  46. );
  47. if (mrg_1 == 074)
  48. exp_1.val &= 0xFF;
  49. }
  50. #ifdef RELOCATION
  51. RELOMOVE(relonami, rel_1);
  52. if (flag & ~0xFF)
  53. newrelo(exp_1.typ, (flag>>8) | RELBR | RELWR);
  54. #endif
  55. if (flag & PUTL)
  56. emit4(exp_1.val);
  57. if (flag & PUTW)
  58. emit2(loww(exp_1.val));
  59. }
  60. ea_2(sz, bits)
  61. {
  62. mrg_1 = mrg_2;
  63. exp_1 = exp_2;
  64. RELOMOVE(rel_1, rel_2);
  65. ea_1(sz, bits);
  66. }
  67. indexmode(hibyte)
  68. {
  69. Xfit(fitb(exp_2.val));
  70. exp_2.val = hibyte | lowb(exp_2.val);
  71. }
  72. checksize(sz, bits)
  73. {
  74. if ((bits & (1 << (sz>>6))) == 0)
  75. serror("bad size");
  76. }
  77. test68010()
  78. {
  79. if (model != 1 && pass == PASS_3)
  80. warning("68010 instruction");
  81. }
  82. badoperand()
  83. {
  84. serror("bad operands");
  85. }
  86. shift_op(opc, sz)
  87. {
  88. if (mrg_1 < 010 && mrg_2 < 010) {
  89. emit2((opc&0170470) | sz | mrg_1<<9 | mrg_2);
  90. return;
  91. }
  92. if (exp_1.typ != S_ABS || mrg_1 != 074) {
  93. badoperand();
  94. return;
  95. }
  96. if (mrg_2 < 010) {
  97. Xfit(fit3(exp_1.val));
  98. emit2((opc&0170430) | sz | low3(exp_1.val)<<9 | mrg_2);
  99. return;
  100. }
  101. checksize(sz, 2);
  102. Xfit(exp_1.val == 1);
  103. emit2((opc&0177700) | mrg_2);
  104. ea_2(SIZE_W, MEM|ALT);
  105. }
  106. bitop(opc)
  107. {
  108. register bits;
  109. bits = DTA|ALT;
  110. if (opc == 0 && (mrg_1 < 010 || mrg_2 != 074))
  111. bits = DTA;
  112. if (mrg_1 < 010) {
  113. emit2(opc | 0400 | mrg_1<<9 | mrg_2);
  114. ea_2(0, bits);
  115. return;
  116. }
  117. if (mrg_1 == 074) {
  118. emit2(opc | 04000 | mrg_2);
  119. ea_1(SIZE_W, 0);
  120. ea_2(0, bits);
  121. return;
  122. }
  123. badoperand();
  124. }
  125. add(opc, sz)
  126. {
  127. if ((mrg_2 & 070) == 010)
  128. checksize(sz, 2|4);
  129. if (
  130. mrg_1 == 074
  131. &&
  132. small(
  133. exp_1.typ==S_ABS && fit3(exp_1.val),
  134. sz==SIZE_L ? 4 : 2
  135. )
  136. ) {
  137. emit2((opc&0400) | 050000 | low3(exp_1.val)<<9 | sz | mrg_2);
  138. ea_2(sz, ALT);
  139. return;
  140. }
  141. if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
  142. emit2((opc&03000) | sz | mrg_2);
  143. ea_1(sz, 0);
  144. ea_2(sz, DTA|ALT);
  145. return;
  146. }
  147. if ((mrg_2 & 070) == 010) {
  148. emit2((opc&0170300) | (mrg_2&7)<<9 | sz<<1 | mrg_1);
  149. ea_1(sz, 0);
  150. return;
  151. }
  152. if (to_dreg(opc, sz, 0))
  153. return;
  154. if (from_dreg(opc, sz, ALT|MEM))
  155. return;
  156. badoperand();
  157. }
  158. and(opc, sz)
  159. {
  160. if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
  161. if (sz != SIZE_NON)
  162. checksize(sz, mrg_2==076 ? 1 : 2);
  163. else
  164. sz = (mrg_2==076 ? SIZE_B : SIZE_W);
  165. emit2((opc&07400) | sz | 074);
  166. ea_1(sz, 0);
  167. return;
  168. }
  169. if (sz == SIZE_NON)
  170. sz = SIZE_DEF;
  171. if (mrg_1 == 074) {
  172. emit2((opc&07400) | sz | mrg_2);
  173. ea_1(sz, 0);
  174. ea_2(sz, DTA|ALT);
  175. return;
  176. }
  177. if ((opc & 010000) == 0 && to_dreg(opc, sz, DTA))
  178. return;
  179. if (from_dreg(opc, sz, (opc & 010000) ? DTA|ALT : ALT|MEM))
  180. return;
  181. badoperand();
  182. }
  183. to_dreg(opc, sz, bits)
  184. {
  185. if ((mrg_2 & 070) != 000)
  186. return(0);
  187. emit2((opc & 0170000) | sz | (mrg_2&7)<<9 | mrg_1);
  188. ea_1(sz, bits);
  189. return(1);
  190. }
  191. from_dreg(opc, sz, bits)
  192. {
  193. if ((mrg_1 & 070) != 000)
  194. return(0);
  195. emit2((opc & 0170000) | sz | (mrg_1&7)<<9 | 0400 | mrg_2);
  196. ea_2(sz, bits);
  197. return(1);
  198. }
  199. cmp(sz)
  200. {
  201. register opc;
  202. if ((mrg_1&070) == 030 && (mrg_2&070) == 030) {
  203. emit2(0130410 | sz | (mrg_1&7) | (mrg_2&7)<<9);
  204. return;
  205. }
  206. if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
  207. if (mrg_2 == 072) {
  208. /* In this case, the ea707172 routine changed the
  209. addressing mode to PC-relative. However, this is
  210. not allowed for this instruction. Change it back
  211. to absolute, but also correct for the optimization
  212. that the ea707172 routine thought it made.
  213. */
  214. if (pass == PASS_1) {
  215. /* In this case, the user wrote it PC-relative.
  216. Error.
  217. */
  218. badoperand();
  219. }
  220. mrg_2 = 071;
  221. exp_2.val += DOTVAL+2;
  222. if (pass == PASS_2) {
  223. DOTGAIN -= 2;
  224. }
  225. }
  226. emit2(06000 | sz | mrg_2);
  227. ea_1(sz, 0);
  228. ea_2(sz, DTA|ALT);
  229. return;
  230. }
  231. if (mrg_2 < 020) {
  232. if (mrg_2 >= 010) {
  233. checksize(sz, 2|4);
  234. opc = 0130300 | sz<<1;
  235. mrg_2 &= 7;
  236. } else
  237. opc = 0130000 | sz;
  238. emit2(opc | mrg_2<<9 | mrg_1);
  239. ea_1(sz, 0);
  240. return;
  241. }
  242. badoperand();
  243. }
  244. move(sz)
  245. {
  246. register opc;
  247. if (mrg_1 > 074 || mrg_2 > 074) {
  248. move_special(sz);
  249. return;
  250. }
  251. if (sz == SIZE_NON)
  252. sz = SIZE_DEF;
  253. if (
  254. mrg_2<010
  255. &&
  256. mrg_1==074
  257. &&
  258. sz==SIZE_L
  259. &&
  260. small(exp_1.typ==S_ABS && fitb(exp_1.val), 4)
  261. ) {
  262. emit2(070000 | mrg_2<<9 | lowb(exp_1.val));
  263. return;
  264. }
  265. switch (sz) {
  266. case SIZE_B: opc = 010000; break;
  267. case SIZE_W: opc = 030000; break;
  268. case SIZE_L: opc = 020000; break;
  269. }
  270. emit2(opc | mrg_1 | (mrg_2&7)<<9 | (mrg_2&070)<<3);
  271. ea_1(sz, 0);
  272. ea_2(sz, ALT);
  273. }
  274. move_special(sz)
  275. {
  276. if (mrg_2 >= 076) {
  277. if (sz != SIZE_NON)
  278. checksize(sz, 2);
  279. emit2(042300 | (mrg_2==076?0:01000) | mrg_1);
  280. ea_1(SIZE_W, DTA);
  281. return;
  282. }
  283. if (mrg_1 >= 076) {
  284. if (mrg_1 == 076)
  285. test68010();
  286. if (sz != SIZE_NON)
  287. checksize(sz, 2);
  288. emit2(040300 | (mrg_1==076?01000:0) | mrg_2);
  289. ea_2(SIZE_W, DTA|ALT);
  290. return;
  291. }
  292. if (sz != SIZE_NON)
  293. checksize(sz, 4);
  294. if (mrg_1==075 && (mrg_2&070)==010) {
  295. emit2(047150 | (mrg_2&7));
  296. return;
  297. }
  298. if (mrg_2==075 && (mrg_1&070)==010) {
  299. emit2(047140 | (mrg_1&7));
  300. return;
  301. }
  302. badoperand();
  303. }
  304. int
  305. reverse(regs, max)
  306. register int regs;
  307. {
  308. register int r, i;
  309. r = regs; regs = 0;
  310. for (i = max; i > 0; i--) {
  311. regs <<= 1;
  312. if (r & 1) regs++;
  313. r >>= 1;
  314. }
  315. return regs;
  316. }
  317. movem(dr, sz, regs)
  318. {
  319. register i;
  320. if ((mrg_2>>3) == 04) {
  321. regs = reverse(regs, 16);
  322. }
  323. checksize(sz, 2|4);
  324. if ((mrg_2>>3)-3 == dr)
  325. badoperand();
  326. emit2(044200 | dr<<10 | (sz & 0200) >> 1 | mrg_2);
  327. emit2(regs);
  328. i = CTR;
  329. if (dr == 0 && (mrg_2&070) == 040)
  330. i = MEM;
  331. if (dr != 0 && (mrg_2&070) == 030)
  332. i = MEM;
  333. if (dr == 0)
  334. i |= ALT;
  335. ea_2(sz, i);
  336. }
  337. movep(sz)
  338. {
  339. checksize(sz, 2|4);
  340. if (mrg_1<010 && (mrg_2&070)==050) {
  341. emit2(0610 | (sz & 0200)>>1 | mrg_1<<9 | (mrg_2&7));
  342. ea_2(sz, 0);
  343. return;
  344. }
  345. if (mrg_2<010 && (mrg_1&070)==050) {
  346. emit2(0410 | (sz & 0200)>>1 | mrg_2<<9 | (mrg_1&7));
  347. ea_1(sz, 0);
  348. return;
  349. }
  350. badoperand();
  351. }
  352. branch(opc, exp)
  353. expr_t exp;
  354. {
  355. register sm;
  356. exp.val -= (DOTVAL + 2);
  357. if ((pass == PASS_2)
  358. &&
  359. (exp.val > 0)
  360. &&
  361. ((exp.typ & S_DOT) == 0)
  362. )
  363. exp.val -= DOTGAIN;
  364. sm = fitb(exp.val);
  365. if ((exp.typ & ~S_DOT) != DOTTYP)
  366. sm = 0;
  367. if (small(sm,2)) {
  368. if (exp.val == 0)
  369. emit2(047161); /* NOP */
  370. else
  371. emit2(opc | lowb(exp.val));
  372. } else {
  373. Xfit(fitw(exp.val));
  374. emit2(opc);
  375. #ifdef RELOCATION
  376. newrelo(exp.typ, RELPC|RELO2|RELBR|RELWR);
  377. #endif
  378. emit2(loww(exp.val));
  379. }
  380. }
  381. ea5x73(rg, sz)
  382. {
  383. if ((exp_2.typ & ~S_DOT) == DOTTYP) {
  384. /* pc relative with index */
  385. if (sz == SIZE_NON)
  386. sz = SIZE_DEF;
  387. exp_2.val -= (DOTVAL + extension_offset());
  388. mrg_2 = 073;
  389. checksize(sz, 2|4);
  390. indexmode(rg<<12 | (sz&0200)<<4);
  391. return;
  392. }
  393. /* displacement */
  394. mrg_2 = 050 | rg;
  395. if (pass == PASS_1) /* tricky, maybe 073 in next passes */
  396. return;
  397. if ((rg & 010) == 0 || sz != SIZE_NON)
  398. badoperand();
  399. }
  400. ea707172(sz)
  401. {
  402. register sm;
  403. mrg_2 = 071;
  404. switch (sz) {
  405. case SIZE_B:
  406. badoperand();
  407. case SIZE_W:
  408. mrg_2 = 070;
  409. case SIZE_L:
  410. return;
  411. case SIZE_NON:
  412. break;
  413. }
  414. if (pass == PASS_1) {
  415. /*
  416. * reserve a bit in the bittable
  417. * in the following passes one call to small()
  418. * will be done, but we don't know which one
  419. * since exp_2.typ cannot be trusted
  420. */
  421. small(0, 2);
  422. return;
  423. }
  424. if ((exp_2.typ & ~S_DOT) == DOTTYP) {
  425. int off = extension_offset();
  426. sm = fitw(exp_2.val-(DOTVAL+off));
  427. sm = small(sm, 2);
  428. if (sm) { /* pc relative */
  429. exp_2.val -= (DOTVAL+off);
  430. mrg_2 = 072;
  431. }
  432. } else {
  433. sm = fitw(exp_2.val);
  434. #ifdef ASLD
  435. if (exp_2.typ & S_VAR)
  436. sm = 0;
  437. #else
  438. if (exp_2.typ != S_ABS)
  439. sm = 0;
  440. #endif /* ASLD */
  441. sm = small(sm, 2);
  442. if (sm)
  443. mrg_2 = 070;
  444. }
  445. }
  446. ea6x(rg, ir, sz)
  447. {
  448. mrg_2 = 060 | rg;
  449. checksize(sz, 2|4);
  450. indexmode(ir<<12 | (sz&0200)<<4);
  451. }
  452. ea72()
  453. {
  454. mrg_2 = 072;
  455. exp_2.val -= (DOTVAL + extension_offset());
  456. }
  457. ea73(ri, sz)
  458. {
  459. mrg_2 = 073;
  460. exp_2.val -= (DOTVAL + extension_offset());
  461. checksize(sz, 2|4);
  462. indexmode(ri<<12 | (sz&0200)<<4);
  463. }
  464. Xnofit()
  465. {
  466. if (pass == PASS_3) serror("too big");
  467. }
  468. fbranch(opc, exp)
  469. expr_t exp;
  470. {
  471. register sm;
  472. exp.val -= (DOTVAL + 2);
  473. if ((pass == PASS_2)
  474. &&
  475. (exp.val > 0)
  476. &&
  477. ((exp.typ & S_DOT) == 0)
  478. )
  479. exp.val -= DOTGAIN;
  480. sm = fitw(exp.val);
  481. if ((exp.typ & ~S_DOT) != DOTTYP)
  482. sm = 0;
  483. if (small(sm,2)) {
  484. emit2(0170200|co_id|opc);
  485. emit2(loww(exp.val));
  486. return;
  487. }
  488. emit2(0170300|co_id|opc); /* 4 byte offset */
  489. #ifdef RELOCATION
  490. newrelo(exp.typ, RELPC|RELO4|RELBR|RELWR);
  491. #endif
  492. emit4(exp.val);
  493. }
  494. ch_sz_dreg(size, mode)
  495. {
  496. if (mode == 0 &&
  497. (size == FSIZE_X || size == FSIZE_P || size == FSIZE_D))
  498. serror("illegal size for data register");
  499. }
  500. check_fsize(sz, size)
  501. {
  502. if (sz != size) serror("bad size");
  503. }