1 /* $Id: mach5.c,v 1.11 1994/06/24 13:05:54 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".
7 * Motorola 68020 auxiliary functions
10 /* With pc-relative modes the offset is calulated from the address of the
11 * extension word. This address is not known until the instruction opcode(s)
12 * have been emitted. Since this address is unknown, the offset from pc
13 * cannot be calculated correctly, so it cannot immediately be decided whether
14 * to use mode 072 (pc-relative with 16 bit offset) or mode 073 (pc_relative
15 * with possibly 32 bit offset) Because of this, instruction opcodes
16 * are not really emitted right away, but temporarily stored. This way
17 * the address of the extension word is known so the offset can be calculated
18 * correctly and it then can be decided to use mode 072 or 073; this can be
19 * altered in the instruction opcode, if necessary. For the sake of consistency
20 * the effective address(es) are also stored temporarily. The instruction is
21 * then emitted in one go, by emit_instr().
28 for (ip=instr; ip<instrp; emit2((ip++)->i_word)) {
30 RELOMOVE(relonami, ip->i_relonami);
32 newrelo(ip->i_relotype, ip->i_reloinfo | RELBR | RELWR);
39 t_emit2(word, relotype, reloinfo, relnm)
49 if (instrp->i_reloinfo = reloinfo) {
50 RELOMOVE(instrp->i_relonami, relnm);
51 instrp->i_relotype = relotype;
54 instrp->i_word = word;
60 t_emit4(words, relotype, reloinfo, relnm)
69 T_EMIT2((short)(words>>16), relotype, reloinfo, relnm);
70 T_EMIT2((short)(words), 0, 0, 0);
75 /* Because displacements come in three sizes (null displacement,
76 * word and long displacement), each displacement requires
77 * two bits in the bittable, so two calls to small. Sometimes
78 * one of these calls is a dummy call.
82 register sm, sm1, sm2;
85 serror("no specials");
86 if ((flag = eamode[mrg_1>>3]) == 0)
87 if ((flag = eamode[010 + (mrg_1&07)]) == 0)
88 flag = eamode[015 + (sz>>6)];
89 if ((mrg_1 & 070) == 010)
93 serror("bad addressing category");
94 if (mrg_1==073 && (ffew_1 & 0200) == 0 && (bd_1.typ & ~S_DOT) == DOTTYP)
95 bd_1.val -= (DOTVAL + dot_offset);
97 if ( (mrg_1==073) || (mrg_1&070)==060 ) {
99 (mrg_1==073 && (bd_1.typ & ~S_DOT)==DOTTYP)
103 if (small(sm && fitw(bd_1.val), 2)) {
105 (sm1 = ((ffew_1 & 0307)==0 && fitb(bd_1.val)))
107 (sm2 = ((ffew_1 & 0307)==0100 && mrg_1==073))
112 if (sm1) { /* brief format extension */
113 T_EMIT2((ffew_1&0177000) | lowb(bd_1.val),
118 /* change mode to 072 in opcode word */
120 T_EMIT2(loww(bd_1.val), 0, 0, 0);
123 ffew_1 &= ~040; /* null displacement */
126 ffew_1 &= ~020; /* word displacement */
128 sm = small(0,2); /* dummy call */
131 sm = (od_1.typ == S_ABS);
132 if (small(sm && fitw(od_1.val), 2))
133 ffew_1 &= small(od_1.val==0, 2) ? ~2 : ~1;
135 sm = small(0,2); /* dummy call */
138 assert((ffew_1 & 0410) == 0400);
139 T_EMIT2(ffew_1, 0, 0, 0);
141 assert(ffew_1 & 060);
142 switch(ffew_1 & 060) {
146 T_EMIT2(loww(bd_1.val), 0, 0, 0);
151 (mrg_1 == 073 && (ffew_1 & 0200) == 0)
163 T_EMIT2(loww(od_1.val), 0, 0, 0);
166 T_EMIT4(od_1.val, od_1.typ, RELO4, od_rel1);
169 return; /* mode 060 and 073 have been dealt with */
176 (mrg_1 != 074 || ! fit16(bd_1.val))
183 (mrg_1 != 074 || ! fit8(bd_1.val))
190 T_EMIT4(bd_1.val, bd_1.typ, (flag>>8), bd_rel1);
192 T_EMIT2(loww(bd_1.val), bd_1.typ, (flag>>8), bd_rel1);
201 RELOMOVE(bd_rel1, bd_rel2);
202 RELOMOVE(od_rel1, od_rel2);
208 if ((bits & (1 << (sz>>6))) == 0)
212 check_fsize(sz, size)
218 ch_sz_dreg(size, mode)
221 (size == FSIZE_X || size == FSIZE_P || size == FSIZE_D))
222 serror("illegal size for data register");
236 default: serror("bad scale"); return 0;
242 serror("bad operand(s)");
247 if (mrg_1 < 010 && mrg_2 < 010) {
248 T_EMIT2((opc & 0170470) | sz | mrg_1<<9 | mrg_2, 0, 0, 0);
251 if (bd_1.typ != S_ABS || mrg_1 != 074) {
257 T_EMIT2((opc & 0170430) | sz | low3(bd_1.val)<<9 | mrg_2,0,0,0);
262 T_EMIT2((opc & 0177700) | mrg_2, 0, 0, 0);
263 ea_2(SIZE_W, MEM|ALT);
271 if (opc == 0 && (mrg_1 < 010 || mrg_2 != 074))
274 T_EMIT2(opc | 0400 | mrg_1<<9 | mrg_2, 0, 0, 0);
279 T_EMIT2(opc | 04000 | mrg_2, 0, 0, 0);
287 bitfield(opc, extension)
289 T_EMIT2(opc | mrg_2, 0, 0, 0);
290 T_EMIT2(extension, 0, 0, 0);
291 ea_2(SIZE_L, (mrg_2 < 010) ? 0 : (CTR | ALT));
296 if ((mrg_2 & 070) == 010)
302 bd_1.typ==S_ABS && fit3(bd_1.val),
306 T_EMIT2((opc&0400) | 050000 | low3(bd_1.val)<<9 | sz | mrg_2,
311 if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
312 T_EMIT2((opc&03000) | sz | mrg_2, 0, 0, 0);
317 if ((mrg_2 & 070) == 010) {
318 T_EMIT2((opc&0170300) | (mrg_2&7)<<9 | sz<<1 | mrg_1, 0, 0, 0);
322 if (to_dreg(opc, sz, 0))
324 if (from_dreg(opc, sz, ALT|MEM))
331 if (mrg_1 == 074 && mrg_2 >= 076) { /* ccr or sr */
333 checksize(sz, mrg_2==076 ? 1 : 2);
335 sz = (mrg_2==076 ? SIZE_B : SIZE_W);
336 T_EMIT2((opc&07400) | sz | 074, 0, 0, 0);
343 T_EMIT2((opc&07400) | sz | mrg_2, 0, 0, 0);
348 if ((opc & 010000) == 0 && to_dreg(opc, sz, DTA))
350 if (from_dreg(opc, sz, (opc & 010000) ? DTA|ALT : ALT|MEM))
355 to_dreg(opc, sz, bits)
357 if ((mrg_2 & 070) != 000)
359 T_EMIT2((opc & 0170000) | sz | (mrg_2&7)<<9 | mrg_1, 0, 0, 0);
364 from_dreg(opc, sz, bits)
366 if ((mrg_1 & 070) != 000)
368 T_EMIT2((opc & 0170000) | sz | (mrg_1&7)<<9 | 0400 | mrg_2, 0, 0, 0);
377 if ((mrg_1&070) == 030 && (mrg_2&070) == 030) {
378 T_EMIT2(0130410 | sz | (mrg_1&7) | (mrg_2&7)<<9, 0, 0, 0);
381 if (mrg_1 == 074 && (mrg_2 & 070) != 010) {
384 T_EMIT2(06000 | sz | mrg_2, 0, 0, 0);
392 opc = 0130300 | sz<<1;
396 T_EMIT2(opc | mrg_2<<9 | mrg_1, 0, 0, 0);
405 if (sz == SIZE_NON) {
406 if (bd_2.typ == S_ABS && fitw(bd_2.val))
413 T_EMIT2(047120 | areg, 0, 0, 0);
414 else /* sz == SIZE_L */
415 T_EMIT2(044010 | areg, 0, 0, 0);
423 if (mrg_1 > 074 || mrg_2 > 074) {
436 small(bd_1.typ==S_ABS && fitb(bd_1.val), 4)
438 T_EMIT2(070000 | mrg_2<<9 | lowb(bd_1.val), 0, 0, 0);
442 case SIZE_B: opc = 010000; break;
443 case SIZE_W: opc = 030000; break;
444 case SIZE_L: opc = 020000; break;
446 T_EMIT2(opc | mrg_1 | (mrg_2&7)<<9 | (mrg_2&070)<<3, 0, 0, 0);
456 T_EMIT2(042300 | (mrg_2==076?0:01000) | mrg_1, 0, 0, 0);
463 T_EMIT2(040300 | (mrg_1==076?01000:0) | mrg_2, 0, 0, 0);
464 ea_2(SIZE_W, DTA|ALT);
469 if (mrg_1==075 && (mrg_2&070)==010) {
470 T_EMIT2(047150 | (mrg_2&7), 0, 0, 0);
473 if (mrg_2==075 && (mrg_1&070)==010) {
474 T_EMIT2(047140 | (mrg_1&7), 0, 0, 0);
484 if ((mrg_2>>3) == 04) {
485 regs = reverse(regs, 16);
488 if ((mrg_2>>3)-3 == dr)
490 T_EMIT2(044200 | dr<<10 | (sz & 0200) >> 1 | mrg_2, 0, 0, 0);
491 T_EMIT2(regs, 0, 0, 0);
493 if (dr == 0 && (mrg_2&070) == 040)
495 if (dr != 0 && (mrg_2&070) == 030)
508 for (i = max; i > 0; i--) {
520 if (mrg_1<010 && (mrg_2&070)==050) {
521 T_EMIT2(0610 | (sz & 0200)>>1 | mrg_1<<9 | (mrg_2&7), 0, 0, 0);
525 if (mrg_2<010 && (mrg_1&070)==050) {
526 T_EMIT2(0410 | (sz & 0200)>>1 | mrg_2<<9 | (mrg_1&7), 0, 0, 0);
538 exp.val -= (DOTVAL + 2);
543 ((exp.typ & S_DOT) == 0)
547 if ((exp.typ & ~S_DOT) != DOTTYP)
550 if (small(fitb(exp.val),2)) {
552 T_EMIT2(047161, 0, 0, 0); /* NOP */
553 else if (exp.val == -1) {
554 T_EMIT2(047161, 0, 0, 0);
555 serror("bad branch offset");
557 T_EMIT2(opc | lowb(exp.val), 0, 0, 0);
559 T_EMIT2(opc, 0, 0, 0);
560 T_EMIT2(loww(exp.val), 0, 0, 0);
564 sm = small(0,2); /* dummy call; two calls to small per branch */
565 T_EMIT2(opc | 0377, 0, 0, 0); /* 4 byte offset */
566 T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
574 exp.val -= (DOTVAL + 2);
579 ((exp.typ & S_DOT) == 0)
583 if ((exp.typ & ~S_DOT) != DOTTYP)
586 T_EMIT2(opc, 0, 0, 0);
587 T_EMIT2(loww(exp.val), 0, 0, 0);
591 T_EMIT2(opc | 0100, 0, 0, 0); /* 4 byte offset */
592 /* NB: no coprocessor defined extension words are emitted */
593 T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
609 /* If this absolute address is in program space, and if we
610 * can assume that the only references to program space are made
611 * by instructins like 'jsr', 'jmp', 'lea' and 'pea', it might
612 * be possible to use a (PC,d16) effective address mode instead
613 * of absolute long. This is done here. If this scheme is in
614 * some way undesirable (e.g. when references to program space
615 * are made by instructions with more than one opcode word or by
616 * second effective addresses in instructions), the rest
617 * of this routine can simply be removed and replaced by the
618 * next two lines (which of course are in comment brackets now).
619 if (small(bd_2.typ == S_ABS && fitw(bd_2.val), 2))
622 if (pass == PASS_1) {
623 /* Reserve a bit in the bittable; in the following
624 * passes one call to small() will be done, but know yet
625 * which one, because bd_2.typ cannot be trusted yet.
630 if ((bd_2.typ & ~S_DOT) == DOTTYP) {
631 /* the "off" variable fixes the problem described above,
632 * e.g., when references to program space are made by
633 * instructions with more than one opcode word.
659 if (curr_size != 0) off = 4;
662 if (curr_size != SIZE_W) off = 4;
665 if (small(fitw(bd_2.val-(DOTVAL+off)), 2)) {
666 bd_2.val -= (DOTVAL+off);
670 if (small(bd_2.typ == S_ABS && fitw(bd_2.val), 2))
679 exp.val -= (DOTVAL + 2);
684 ((exp.typ & S_DOT) == 0)
688 if ((exp.typ & ~S_DOT) != DOTTYP)
691 T_EMIT2(0170200|co_id|opc, 0, 0, 0);
692 T_EMIT2(loww(exp.val), 0, 0, 0);
695 T_EMIT2(0170300|co_id|opc, 0, 0, 0); /* 4 byte offset */
696 T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);