ack/mach/m65oo2/as/mach5.c

70 lines
1.1 KiB
C

void
encode_imm(int opc, int sz, expr_t exp)
{
emit1(opc);
emit1(sz);
switch(TARGET_SIZE(sz))
{
case 0:
if (!FIT8(exp.val)) serror("bad operand size");
emit1(exp.val);
break;
case 1:
if (!FIT16(exp.val)) serror("bad operand size");
emit2(exp.val);
break;
case 2:
emit4(exp.val);
break;
default:
break;
}
}
void
encode_addr(expr_t exp, int sz)
{
uint32_t dist;
dist = exp.val;
if (FIT8(dist))
{
emit1(ADDR_SIZE_B | sz);
emit1(dist & 0xFF);
}
else if (FIT16(dist))
{
emit1(ADDR_SIZE_W | sz);
emit2(dist & 0xFFFF);
}
else
{
emit1(ADDR_SIZE_L | sz);
emit4(dist);
}
}
void branch(register int opc, expr_t exp)
{
uint32_t dist;
dist = exp.val - (DOTVAL + 2);
if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
dist -= DOTGAIN;
if (small(FIT16(dist) && (exp.typ & ~S_DOT) == DOTTYP, 3)) {
emit1(opc); emit2(dist & 0xFFFF);
} else {
emit1(opc^0x20); emit1(0x03); /* Skip over ... */
emit1(0x4C); /* ... far jump. */
#ifdef RELOCATION
newrelo(exp.typ, RELO2);
#endif
emit2(exp.val);
}
}