mach5.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. #define RCSID5 "$Id$"
  6. /*
  7. * INTEL 8086 special routines
  8. */
  9. ea_1(param) {
  10. if ((mrg_1 & 070) || (param & ~070)) {
  11. serror("bad operand");
  12. }
  13. emit1(mrg_1 | param);
  14. switch(mrg_1 >> 6) {
  15. case 0:
  16. if (mrg_1 == 6 || (mrg_1 & 040)) {
  17. #ifdef RELOCATION
  18. RELOMOVE(relonami, rel_1);
  19. newrelo(exp_1.typ, RELO2);
  20. #endif
  21. emit2(exp_1.val);
  22. }
  23. break;
  24. case 1:
  25. #ifdef RELOCATION
  26. RELOMOVE(relonami, rel_1);
  27. newrelo(exp_1.typ, RELO1);
  28. #endif
  29. emit1(exp_1.val);
  30. break;
  31. case 2:
  32. #ifdef RELOCATION
  33. RELOMOVE(relonami, rel_1);
  34. newrelo(exp_1.typ, RELO2);
  35. #endif
  36. emit2(exp_1.val);
  37. break;
  38. }
  39. }
  40. ea_2(param) {
  41. mrg_1 = mrg_2;
  42. exp_1 = exp_2;
  43. RELOMOVE(rel_1, rel_2);
  44. ea_1(param);
  45. }
  46. reverse() {
  47. register m, r; expr_t e;
  48. m = mrg_1; mrg_1 = mrg_2; mrg_2 = m;
  49. e = exp_1; exp_1 = exp_2; exp_2 = e;
  50. #ifndef ASLD
  51. r = rel_1; rel_1 = rel_2; rel_2 = r;
  52. #endif
  53. }
  54. badsyntax() {
  55. serror("bad operands");
  56. }
  57. regsize(sz) register sz; {
  58. register bit;
  59. sz <<= 3;
  60. bit = 010;
  61. sz &= bit;
  62. if ((mrg_1 >= 0300 && (mrg_1 & bit) != sz) ||
  63. (mrg_2 >= 0300 && (mrg_2 & bit) != sz))
  64. serror("register error");
  65. mrg_1 &= ~bit;
  66. mrg_2 &= ~bit;
  67. }
  68. indexed() {
  69. int sm1, sm2;
  70. if (mrg_2 & ~7)
  71. serror("register error");
  72. sm1 = exp_2.typ == S_ABS && fitb((short)(exp_2.val));
  73. if (sm1) {
  74. sm2 = exp_2.val == 0 && mrg_2 != 6;
  75. }
  76. else sm2 = 0;
  77. if (small(sm1, 1)) {
  78. if (small(sm2, 1)) {
  79. }
  80. else mrg_2 |= 0100;
  81. }
  82. else {
  83. if (small(0, 1)) {}
  84. mrg_2 |= 0200;
  85. }
  86. }
  87. branch(opc,exp) register opc; expr_t exp; {
  88. register sm,dist;
  89. int saving = opc == 0353 ? 1 : 3;
  90. dist = exp.val - (DOTVAL + 2);
  91. if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
  92. dist -= DOTGAIN;
  93. sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
  94. if ((exp.typ & ~S_DOT) != DOTTYP)
  95. sm = 0;
  96. if ((opc & 0370) == 0340) {
  97. fit(sm);
  98. sm = 1;
  99. } else {
  100. if ((sm = small(sm,saving)) == 0) {
  101. if (opc != 0353) {
  102. emit1(opc^1);
  103. emit1(3);
  104. dist -= 2;
  105. }
  106. opc = 0351;
  107. dist--;
  108. }
  109. }
  110. emit1(opc);
  111. if (sm == 0) {
  112. #ifdef RELOCATION
  113. newrelo(exp.typ, RELPC | RELO2);
  114. #endif
  115. emit2(dist);
  116. } else
  117. emit1(dist);
  118. }
  119. pushop(opc) register opc; {
  120. regsize(1);
  121. if (mrg_1 & 020) {
  122. if ( (mrg_1&3) == 1 && opc==1 ) badsyntax() ;
  123. emit1(6 | opc | (mrg_1&3)<<3);
  124. } else if (mrg_1 >= 0300) {
  125. emit1(0120 | opc<<3 | (mrg_1&7));
  126. } else if (opc == 0) {
  127. if (mrg_1 & 040) { /* 070 ??? */
  128. if (small(exp_1.typ == S_ABS && fitb((short)exp_1.val),1)) {
  129. emit1(0152);
  130. emit1((int) exp_1.val);
  131. } else {
  132. emit1(0150);
  133. RELOMOVE(relonami, rel_1);
  134. #ifdef RELOCATION
  135. newrelo(exp_1.typ, RELO2);
  136. emit2((int) exp_1.val);
  137. #endif
  138. }
  139. } else {
  140. emit1(0377); ea_1(6<<3);
  141. }
  142. } else {
  143. emit1(0217); ea_1(0<<3);
  144. }
  145. }
  146. addop(opc) register opc; {
  147. regsize(opc);
  148. if (mrg_2 >= 0300) {
  149. emit1(opc); ea_1((mrg_2&7)<<3);
  150. } else if ((mrg_2 & 040) && mrg_1 == 0300) {
  151. emit1(opc | 4);
  152. #ifdef RELOCATION
  153. RELOMOVE(relonami, rel_2);
  154. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  155. #endif
  156. emitx(exp_2.val, (opc&1)+1);
  157. } else if (mrg_2 & 040) {
  158. if ((opc&1) == 0) {
  159. emit1(0200);
  160. } else {
  161. int sm = exp_2.typ == S_ABS && fitb((short)exp_2.val) &&
  162. opc != 011 && opc != 041 && opc != 061;
  163. if (small(sm, 1)) {
  164. emit1(0203); opc &= ~1;
  165. }
  166. else emit1(0201);
  167. }
  168. ea_1(opc & 070);
  169. #ifdef RELOCATION
  170. RELOMOVE(relonami, rel_2);
  171. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  172. #endif
  173. emitx(exp_2.val, (opc&1)+1);
  174. } else if (mrg_1 >= 0300) {
  175. emit1(opc | 2);
  176. ea_2((mrg_1&7)<<3);
  177. } else
  178. badsyntax();
  179. }
  180. rolop(opc) register opc; {
  181. register cmrg;
  182. cmrg = mrg_2;
  183. mrg_2 = mrg_1;
  184. regsize(opc);
  185. if (cmrg == 0301) {
  186. emit1(0322 | (opc&1)); ea_1(opc&070);
  187. } else if (cmrg & 040) {
  188. if (small(exp_2.val == 1, 1)) {
  189. emit1(0320 | (opc&1)); ea_1(opc&070);
  190. } else {
  191. fit(fitb(exp_2.val));
  192. emit1(0300|(opc&1)); ea_1(opc&070);
  193. emit1((int)exp_2.val);
  194. }
  195. } else
  196. badsyntax();
  197. }
  198. incop(opc) register opc; {
  199. regsize(opc);
  200. if ((opc&1) && mrg_1>=0300) {
  201. emit1(0100 | (opc&010) | (mrg_1&7));
  202. } else {
  203. emit1(0376 | (opc&1));
  204. ea_1(opc & 010);
  205. }
  206. }
  207. callop(opc) register opc; {
  208. regsize(1);
  209. if (mrg_1 & 040) {
  210. if (opc == (040+(0351<<8))) {
  211. RELOMOVE(relonami, rel_1);
  212. branch(0353,exp_1);
  213. } else {
  214. exp_1.val -= (DOTVAL+3);
  215. emit1(opc>>8);
  216. #ifdef RELOCATION
  217. RELOMOVE(relonami, rel_1);
  218. newrelo(exp_1.typ, RELPC | RELO2);
  219. #endif
  220. emit2(exp_1.val);
  221. }
  222. } else {
  223. emit1(0377); ea_1(opc&070);
  224. }
  225. }
  226. xchg(opc) register opc; {
  227. regsize(opc);
  228. if (mrg_2 == 0300 || mrg_1 < 0300)
  229. reverse();
  230. if (opc == 1 && mrg_1 == 0300 && mrg_2 >= 0300) {
  231. emit1(0220 | (mrg_2&7));
  232. } else if (mrg_1 >= 0300) {
  233. emit1(0206 | opc); ea_2((mrg_1&7)<<3);
  234. } else
  235. badsyntax();
  236. }
  237. test(opc) register opc; {
  238. regsize(opc);
  239. if ((mrg_1 & 040) || mrg_2 >= 0300)
  240. reverse();
  241. if ((mrg_2 & 040) && mrg_1 == 0300) {
  242. emit1(0250 | opc);
  243. #ifdef RELOCATION
  244. RELOMOVE(relonami, rel_2);
  245. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  246. #endif
  247. emitx(exp_2.val, (opc&1)+1);
  248. } else if (mrg_2 & 040) {
  249. emit1(0366 | opc);
  250. ea_1(0<<3);
  251. #ifdef RELOCATION
  252. RELOMOVE(relonami, rel_2);
  253. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  254. #endif
  255. emitx(exp_2.val, (opc&1)+1);
  256. } else if (mrg_1 >= 0300) {
  257. emit1(0204 | opc); ea_2((mrg_1&7)<<3);
  258. } else
  259. badsyntax();
  260. }
  261. mov(opc) register opc; {
  262. regsize(opc);
  263. if (mrg_1 & 020) {
  264. emit1(0216); ea_2((mrg_1&3)<<3);
  265. } else if (mrg_2 & 020) {
  266. emit1(0214); ea_1((mrg_2&3)<<3);
  267. } else if (mrg_2 & 040) {
  268. if (mrg_1 >= 0300) {
  269. emit1(0260 | opc<<3 | (mrg_1&7));
  270. #ifdef RELOCATION
  271. RELOMOVE(relonami, rel_2);
  272. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  273. #endif
  274. emitx(exp_2.val, (opc&1)+1);
  275. } else {
  276. emit1(0306 | opc); ea_1(0<<3);
  277. #ifdef RELOCATION
  278. RELOMOVE(relonami, rel_2);
  279. newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
  280. #endif
  281. emitx(exp_2.val, (opc&1)+1);
  282. }
  283. } else if (mrg_2 == 0300 && mrg_1 == 6) {
  284. emit1(0242 | opc);
  285. #ifdef RELOCATION
  286. RELOMOVE(relonami, rel_1);
  287. newrelo(exp_1.typ, RELO2);
  288. #endif
  289. emit2(exp_1.val);
  290. } else if (mrg_1 == 0300 && mrg_2 == 6) {
  291. emit1(0240 | opc);
  292. #ifdef RELOCATION
  293. RELOMOVE(relonami, rel_2);
  294. newrelo(exp_2.typ, RELO2);
  295. #endif
  296. emit2(exp_2.val);
  297. } else if (mrg_2 >= 0300) {
  298. emit1(0210 | opc); ea_1((mrg_2&7)<<3);
  299. } else if (mrg_1 >= 0300) {
  300. emit1(0212 | opc); ea_2((mrg_1&7)<<3);
  301. } else {
  302. badsyntax();
  303. }
  304. }
  305. imul(opc)
  306. int opc;
  307. {
  308. regsize(opc);
  309. if (exp_2.typ != S_ABS || ((mrg_2 & 040) == 0)) {
  310. serror("bad operand");
  311. } else {
  312. if (small(exp_2.typ == S_ABS && fitb((short)exp_2.val),1)) {
  313. emit1(0153);
  314. ea_1((mrg_2&7)<<3);
  315. emit1((int)exp_2.val);
  316. } else {
  317. emit1(0151);
  318. ea_1((mrg_2&7)<<3);
  319. RELOMOVE(relonami, rel_2);
  320. #ifdef RELOCATION
  321. newrelo(exp_2.typ, RELO2);
  322. emit2((int) exp_2.val);
  323. #endif
  324. }
  325. }
  326. }