operation
: { instrp = instr;
dot_offset = 0;
+ curr_instr = curr_token;
}
instruction
{ emit_instr();
{ movem(0, $2, $3);}
| MOVEM sizedef notimmreg ',' regs
{ movem(1, $2, $5);}
- | MOVESP sizedef ea_ea
+ | MOVESP sizedef
+ { curr_size = $1; }
+ ea_ea
{ if ($1 == 0) {
/* movep */
movep($2);
{ $$ = $1 | 010;}
;
sizedef : /* empty */
- { $$ = SIZE_DEF;}
- | SIZE
+ { $$ = SIZE_DEF; curr_size = SIZE_DEF; }
+ | SIZE { curr_size = $1; $$ = $1; }
;
sizenon : /* empty */
{ $$ = SIZE_NON;}
return;
}
if ((bd_2.typ & ~S_DOT) == DOTTYP) {
- if (small(fitw(bd_2.val-(DOTVAL+2)), 2)) {
- bd_2.val -= (DOTVAL+2);
+ /* the "off" variable fixes the problem described above,
+ * e.g., when references to program space are made by
+ * instructions with more than one opcode word.
+ */
+ int off = 2;
+
+ switch(curr_instr) {
+ case MOVEM:
+ case FMOVE:
+ case FMOVEM:
+ case FDYADIC:
+ case FMONADIC:
+ case FSINCOS:
+ case FSCC:
+ case FTST:
+ case DIVL:
+ case OP_RANGE:
+ case CALLM:
+ case CAS:
+ case CPSCC:
+ case CPTRAPCC:
+ case PFLUSH:
+ case PTEST:
+ case PMOVE:
+ case PLOAD:
+ off = 4;
+ break;
+ case MOVESP:
+ if (curr_size != 0) off = 4;
+ break;
+ case DIVMUL:
+ if (curr_size != SIZE_W) off = 4;
+ break;
+ }
+ if (small(fitw(bd_2.val-(DOTVAL+off)), 2)) {
+ bd_2.val -= (DOTVAL+off);
mrg_2 = 072;
}
} else