1 /* $Id: mach5.c,v 2.13 1994/06/24 13:02:56 ceriel Exp $ */
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".
8 * Motorola 68000/68010 auxiliary functions
33 serror("no specials");
34 if ((flag = eamode[mrg_1>>3]) == 0)
35 if ((flag = eamode[010 + (mrg_1&07)]) == 0)
36 flag = eamode[015 + (sz>>6)];
37 if ((mrg_1 & 070) == 010)
41 serror("bad addressing category");
43 Xfit (fitw(exp_1.val) ||
44 (mrg_1 == 074 && fit16(exp_1.val))
47 Xfit (fitb(exp_1.val) ||
48 (mrg_1 == 074 && fit8(exp_1.val))
54 RELOMOVE(relonami, rel_1);
56 newrelo(exp_1.typ, (flag>>8) | RELBR | RELWR);
61 emit2(loww(exp_1.val));
68 RELOMOVE(rel_1, rel_2);
74 Xfit(fitb(exp_2.val));
75 exp_2.val = hibyte | lowb(exp_2.val);
80 if ((bits & (1 << (sz>>6))) == 0)
86 if (model != 1 && pass == PASS_3)
87 warning("68010 instruction");
92 serror("bad operands");
97 if (mrg_1 < 010 && mrg_2 < 010) {
98 emit2((opc&0170470) | sz | mrg_1<<9 | mrg_2);
101 if (exp_1.typ != S_ABS || mrg_1 != 074) {
106 Xfit(fit3(exp_1.val));
107 emit2((opc&0170430) | sz | low3(exp_1.val)<<9 | mrg_2);
111 Xfit(exp_1.val == 1);
112 emit2((opc&0177700) | mrg_2);
113 ea_2(SIZE_W, MEM|ALT);
121 if (opc == 0 && (mrg_1 < 010 || mrg_2 != 074))
124 emit2(opc | 0400 | mrg_1<<9 | mrg_2);
129 emit2(opc | 04000 | mrg_2);
139 if ((mrg_2 & 070) == 010)
145 exp_1.typ==S_ABS && fit3(exp_1.val),
149 emit2((opc&0400) | 050000 | low3(exp_1.val)<<9 | sz | mrg_2);
153 if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
154 emit2((opc&03000) | sz | mrg_2);
159 if ((mrg_2 & 070) == 010) {
160 emit2((opc&0170300) | (mrg_2&7)<<9 | sz<<1 | mrg_1);
164 if (to_dreg(opc, sz, 0))
166 if (from_dreg(opc, sz, ALT|MEM))
173 if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
175 checksize(sz, mrg_2==076 ? 1 : 2);
177 sz = (mrg_2==076 ? SIZE_B : SIZE_W);
178 emit2((opc&07400) | sz | 074);
185 emit2((opc&07400) | sz | mrg_2);
190 if ((opc & 010000) == 0 && to_dreg(opc, sz, DTA))
192 if (from_dreg(opc, sz, (opc & 010000) ? DTA|ALT : ALT|MEM))
197 to_dreg(opc, sz, bits)
199 if ((mrg_2 & 070) != 000)
201 emit2((opc & 0170000) | sz | (mrg_2&7)<<9 | mrg_1);
206 from_dreg(opc, sz, bits)
208 if ((mrg_1 & 070) != 000)
210 emit2((opc & 0170000) | sz | (mrg_1&7)<<9 | 0400 | mrg_2);
219 if ((mrg_1&070) == 030 && (mrg_2&070) == 030) {
220 emit2(0130410 | sz | (mrg_1&7) | (mrg_2&7)<<9);
223 if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
225 /* In this case, the ea707172 routine changed the
226 addressing mode to PC-relative. However, this is
227 not allowed for this instruction. Change it back
228 to absolute, but also correct for the optimization
229 that the ea707172 routine thought it made.
231 if (pass == PASS_1) {
232 /* In this case, the user wrote it PC-relative.
238 exp_2.val += DOTVAL+2;
239 if (pass == PASS_2) {
243 emit2(06000 | sz | mrg_2);
251 opc = 0130300 | sz<<1;
255 emit2(opc | mrg_2<<9 | mrg_1);
266 if (mrg_1 > 074 || mrg_2 > 074) {
279 small(exp_1.typ==S_ABS && fitb(exp_1.val), 4)
281 emit2(070000 | mrg_2<<9 | lowb(exp_1.val));
285 case SIZE_B: opc = 010000; break;
286 case SIZE_W: opc = 030000; break;
287 case SIZE_L: opc = 020000; break;
289 emit2(opc | mrg_1 | (mrg_2&7)<<9 | (mrg_2&070)<<3);
299 emit2(042300 | (mrg_2==076?0:01000) | mrg_1);
308 emit2(040300 | (mrg_1==076?01000:0) | mrg_2);
309 ea_2(SIZE_W, DTA|ALT);
314 if (mrg_1==075 && (mrg_2&070)==010) {
315 emit2(047150 | (mrg_2&7));
318 if (mrg_2==075 && (mrg_1&070)==010) {
319 emit2(047140 | (mrg_1&7));
332 for (i = max; i > 0; i--) {
344 if ((mrg_2>>3) == 04) {
345 regs = reverse(regs, 16);
348 if ((mrg_2>>3)-3 == dr)
350 emit2(044200 | dr<<10 | (sz & 0200) >> 1 | mrg_2);
353 if (dr == 0 && (mrg_2&070) == 040)
355 if (dr != 0 && (mrg_2&070) == 030)
365 if (mrg_1<010 && (mrg_2&070)==050) {
366 emit2(0610 | (sz & 0200)>>1 | mrg_1<<9 | (mrg_2&7));
370 if (mrg_2<010 && (mrg_1&070)==050) {
371 emit2(0410 | (sz & 0200)>>1 | mrg_2<<9 | (mrg_1&7));
383 exp.val -= (DOTVAL + 2);
388 ((exp.typ & S_DOT) == 0)
392 if ((exp.typ & ~S_DOT) != DOTTYP)
396 emit2(047161); /* NOP */
398 emit2(opc | lowb(exp.val));
403 newrelo(exp.typ, RELPC|RELO2|RELBR|RELWR);
405 emit2(loww(exp.val));
411 if ((exp_2.typ & ~S_DOT) == DOTTYP) {
412 /* pc relative with index */
415 exp_2.val -= (DOTVAL + extension_offset());
418 index(rg<<12 | (sz&0200)<<4);
423 if (pass == PASS_1) /* tricky, maybe 073 in next passes */
425 if ((rg & 010) == 0 || sz != SIZE_NON)
444 if (pass == PASS_1) {
446 * reserve a bit in the bittable
447 * in the following passes one call to small()
448 * will be done, but we don't know which one
449 * since exp_2.typ cannot be trusted
454 if ((exp_2.typ & ~S_DOT) == DOTTYP) {
455 int off = extension_offset();
456 sm = fitw(exp_2.val-(DOTVAL+off));
458 if (sm) { /* pc relative */
459 exp_2.val -= (DOTVAL+off);
463 sm = fitw(exp_2.val);
465 if (exp_2.typ & S_VAR)
468 if (exp_2.typ != S_ABS)
481 index(ir<<12 | (sz&0200)<<4);
487 exp_2.val -= (DOTVAL + extension_offset());
493 exp_2.val -= (DOTVAL + extension_offset());
495 index(ri<<12 | (sz&0200)<<4);
500 if (pass == PASS_3) serror("too big");
508 exp.val -= (DOTVAL + 2);
513 ((exp.typ & S_DOT) == 0)
517 if ((exp.typ & ~S_DOT) != DOTTYP)
520 emit2(0170200|co_id|opc);
521 emit2(loww(exp.val));
524 emit2(0170300|co_id|opc); /* 4 byte offset */
526 newrelo(exp.typ, RELPC|RELO4|RELBR|RELWR);
531 ch_sz_dreg(size, mode)
534 (size == FSIZE_X || size == FSIZE_P || size == FSIZE_D))
535 serror("illegal size for data register");
538 check_fsize(sz, size)
540 if (sz != size) serror("bad size");