70 lines
1.1 KiB
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);
|
|
}
|
|
}
|