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".
5 #define RCSID5 "$Id: mach5.c,v 3.8 1994/06/28 14:41:17 ceriel Exp $"
8 * INTEL 8086 special routines
13 if ((mrg_1 & 070) || (param & ~070)) {
14 serror("bad operand");
19 if (mrg_1 == 6 || (mrg_1 & 040)) {
21 RELOMOVE(relonami, rel_1);
22 newrelo(exp_1.typ, RELO2);
29 RELOMOVE(relonami, rel_1);
30 newrelo(exp_1.typ, RELO1);
36 RELOMOVE(relonami, rel_1);
37 newrelo(exp_1.typ, RELO2);
48 RELOMOVE(rel_1, rel_2);
53 register m, r; expr_t e;
55 m = mrg_1; mrg_1 = mrg_2; mrg_2 = m;
56 e = exp_1; exp_1 = exp_2; exp_2 = e;
58 r = rel_1; rel_1 = rel_2; rel_2 = r;
64 serror("bad operands");
67 regsize(sz) register sz; {
73 if ((mrg_1 >= 0300 && (mrg_1 & bit) != sz) ||
74 (mrg_2 >= 0300 && (mrg_2 & bit) != sz))
75 serror("register error");
84 serror("register error");
85 sm1 = exp_2.typ == S_ABS && fitb((short)(exp_2.val));
87 sm2 = exp_2.val == 0 && mrg_2 != 6;
101 branch(opc,exp) register opc; expr_t exp; {
103 int saving = opc == 0353 ? 1 : 3;
105 dist = exp.val - (DOTVAL + 2);
106 if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
108 sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
109 if ((exp.typ & ~S_DOT) != DOTTYP)
111 if ((opc & 0370) == 0340) {
115 if ((sm = small(sm,saving)) == 0) {
128 newrelo(exp.typ, RELPC | RELO2);
135 pushop(opc) register opc; {
139 if ( (mrg_1&3) == 1 && opc==1 ) badsyntax() ;
140 emit1(6 | opc | (mrg_1&3)<<3);
141 } else if (mrg_1 >= 0300) {
142 emit1(0120 | opc<<3 | (mrg_1&7));
143 } else if (opc == 0) {
144 if (mrg_1 & 040) { /* 070 ??? */
145 if (small(exp_1.typ == S_ABS && fitb((short)exp_1.val),1)) {
147 emit1((int) exp_1.val);
150 RELOMOVE(relonami, rel_1);
152 newrelo(exp_1.typ, RELO2);
153 emit2((int) exp_1.val);
157 emit1(0377); ea_1(6<<3);
160 emit1(0217); ea_1(0<<3);
164 addop(opc) register opc; {
168 emit1(opc); ea_1((mrg_2&7)<<3);
169 } else if ((mrg_2 & 040) && mrg_1 == 0300) {
172 RELOMOVE(relonami, rel_2);
173 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
175 emitx(exp_2.val, (opc&1)+1);
176 } else if (mrg_2 & 040) {
180 int sm = exp_2.typ == S_ABS && fitb((short)exp_2.val) &&
181 opc != 011 && opc != 041 && opc != 061;
183 emit1(0203); opc &= ~1;
189 RELOMOVE(relonami, rel_2);
190 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
192 emitx(exp_2.val, (opc&1)+1);
193 } else if (mrg_1 >= 0300) {
200 rolop(opc) register opc; {
207 emit1(0322 | (opc&1)); ea_1(opc&070);
208 } else if (cmrg & 040) {
209 if (small(exp_2.val == 1, 1)) {
210 emit1(0320 | (opc&1)); ea_1(opc&070);
212 fit(fitb(exp_2.val));
213 emit1(0300|(opc&1)); ea_1(opc&070);
214 emit1((int)exp_2.val);
220 incop(opc) register opc; {
223 if ((opc&1) && mrg_1>=0300) {
224 emit1(0100 | (opc&010) | (mrg_1&7));
226 emit1(0376 | (opc&1));
231 callop(opc) register opc; {
235 if (opc == (040+(0351<<8))) {
236 RELOMOVE(relonami, rel_1);
239 exp_1.val -= (DOTVAL+3);
242 RELOMOVE(relonami, rel_1);
243 newrelo(exp_1.typ, RELPC | RELO2);
248 emit1(0377); ea_1(opc&070);
252 xchg(opc) register opc; {
255 if (mrg_2 == 0300 || mrg_1 < 0300)
257 if (opc == 1 && mrg_1 == 0300 && mrg_2 >= 0300) {
258 emit1(0220 | (mrg_2&7));
259 } else if (mrg_1 >= 0300) {
260 emit1(0206 | opc); ea_2((mrg_1&7)<<3);
265 test(opc) register opc; {
268 if ((mrg_1 & 040) || mrg_2 >= 0300)
270 if ((mrg_2 & 040) && mrg_1 == 0300) {
273 RELOMOVE(relonami, rel_2);
274 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
276 emitx(exp_2.val, (opc&1)+1);
277 } else if (mrg_2 & 040) {
281 RELOMOVE(relonami, rel_2);
282 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
284 emitx(exp_2.val, (opc&1)+1);
285 } else if (mrg_1 >= 0300) {
286 emit1(0204 | opc); ea_2((mrg_1&7)<<3);
291 mov(opc) register opc; {
295 emit1(0216); ea_2((mrg_1&3)<<3);
296 } else if (mrg_2 & 020) {
297 emit1(0214); ea_1((mrg_2&3)<<3);
298 } else if (mrg_2 & 040) {
300 emit1(0260 | opc<<3 | (mrg_1&7));
302 RELOMOVE(relonami, rel_2);
303 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
305 emitx(exp_2.val, (opc&1)+1);
307 emit1(0306 | opc); ea_1(0<<3);
309 RELOMOVE(relonami, rel_2);
310 newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
312 emitx(exp_2.val, (opc&1)+1);
314 } else if (mrg_2 == 0300 && mrg_1 == 6) {
317 RELOMOVE(relonami, rel_1);
318 newrelo(exp_1.typ, RELO2);
321 } else if (mrg_1 == 0300 && mrg_2 == 6) {
324 RELOMOVE(relonami, rel_2);
325 newrelo(exp_2.typ, RELO2);
328 } else if (mrg_2 >= 0300) {
329 emit1(0210 | opc); ea_1((mrg_2&7)<<3);
330 } else if (mrg_1 >= 0300) {
331 emit1(0212 | opc); ea_2((mrg_1&7)<<3);
341 if (exp_2.typ != S_ABS || ((mrg_2 & 040) == 0)) {
342 serror("bad operand");
344 if (small(exp_2.typ == S_ABS && fitb((short)exp_2.val),1)) {
347 emit1((int)exp_2.val);
351 RELOMOVE(relonami, rel_2);
353 newrelo(exp_2.typ, RELO2);
354 emit2((int) exp_2.val);