start work on comparisons
There are two things I overlooked so far. 1. Binary instructions like cmp that do not have a result in registers need the size suffix sometimes, for example when comparing a spill location with a constant. 2. The register allocator needs to be adapted to support the comparison instruction: it is not possible to compare two spill locations without using a register.
This commit is contained in:
parent
1477dffe32
commit
246a48ba94
6 changed files with 109 additions and 22 deletions
44
lisc/emit.c
44
lisc/emit.c
|
@ -40,6 +40,36 @@ static char *rtoa[] = {
|
|||
[R15D] = "r15d",
|
||||
};
|
||||
|
||||
static char *rbtoa[] = {
|
||||
[RXX] = "OH GOD!",
|
||||
|
||||
|
||||
[RAX] = "al",
|
||||
[RCX] = "cl",
|
||||
[RDX] = "dl",
|
||||
[RSI] = "sil",
|
||||
[RDI] = "dil",
|
||||
[R8] = "r8b",
|
||||
[R9] = "r9b",
|
||||
[R10] = "r10b",
|
||||
[R11] = "r11b",
|
||||
|
||||
[RBX] = "bl",
|
||||
[R12] = "r12b",
|
||||
[R13] = "r13b",
|
||||
[R14] = "r14b",
|
||||
[R15] = "r15b",
|
||||
|
||||
[RBP] = "bpl",
|
||||
[RSP] = "spl",
|
||||
|
||||
};
|
||||
|
||||
static char *ctoa[NCmp] = {
|
||||
[Ceq] = "e",
|
||||
[Csle] = "le",
|
||||
};
|
||||
|
||||
static void
|
||||
eref(Ref r, Fn *fn, FILE *f)
|
||||
{
|
||||
|
@ -87,7 +117,7 @@ eop(char *op, Ref a, Ref b, Fn *fn, FILE *f)
|
|||
static void
|
||||
eins(Ins i, Fn *fn, FILE *f)
|
||||
{
|
||||
static char *opi[] = {
|
||||
static char *otoa[OLast] = {
|
||||
[OAdd] = "add",
|
||||
[OSub] = "sub",
|
||||
};
|
||||
|
@ -103,7 +133,7 @@ eins(Ins i, Fn *fn, FILE *f)
|
|||
}
|
||||
if (!req(i.to, i.arg[0]))
|
||||
eop("mov", i.arg[0], i.to, fn, f);
|
||||
eop(opi[i.op], i.arg[1], i.to, fn, f);
|
||||
eop(otoa[i.op], i.arg[1], i.to, fn, f);
|
||||
break;
|
||||
case OStore:
|
||||
i.to = i.arg[1];
|
||||
|
@ -127,9 +157,19 @@ eins(Ins i, Fn *fn, FILE *f)
|
|||
case OXDiv:
|
||||
eop("idiv", i.arg[0], R, fn, f);
|
||||
break;
|
||||
case OXCmp:
|
||||
eop("cmp", i.arg[0], i.arg[1], fn, f);
|
||||
break;
|
||||
case ONop:
|
||||
break;
|
||||
default:
|
||||
if (OXSet <= i.op && i.op <= OXSet1) {
|
||||
eop("mov $0,", i.to, R, fn, f);
|
||||
fprintf(f, "\tset%s %%%s\n",
|
||||
ctoa[i.op-OXSet],
|
||||
rbtoa[BASE(i.to.val)]);
|
||||
break;
|
||||
}
|
||||
diag("emit: unhandled instruction (3)");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue