add basic support for stack allocation

This commit is contained in:
Quentin Carbonneaux 2015-08-12 15:25:53 -04:00
parent 8be35bf2be
commit 78bf28f56e
4 changed files with 54 additions and 3 deletions

View file

@ -42,6 +42,22 @@ newtmp(int type, Fn *fn)
return TMP(t);
}
static Ref
newcon(int64_t val, Fn *fn)
{
int c;
for (c=0; c<fn->ncon; c++)
if (fn->con[c].type == CNum && fn->con[c].val == val)
return CON(c);
fn->ncon++;
fn->con = realloc(fn->con, fn->ncon * sizeof fn->con[0]);
if (!fn->con)
diag("isel: out of memory");
fn->con[c] = (Con){.type = CNum, .val = val};
return CON(c);
}
static int
noimm(Ref r, Fn *fn)
{
@ -96,6 +112,7 @@ sel(Ins i, Fn *fn)
{
Ref r0, r1, ra, rd;
int n, ty, c;
int64_t val;
switch (i.op) {
case ODiv:
@ -166,6 +183,29 @@ Emit:
}
}
break;
case OAlloc:
/* we need to make sure
* the stack remains aligned
* (rsp + 8 = 0) mod 16
* as a consequence, the alloc
* alignment is 8, we can change
* that in the future
*/
if (rtype(i.arg[0]) == RCon) {
val = fn->con[i.arg[0].val].val;
val = (val + 15) & ~INT64_C(15);
if (val < 0 || val > INT32_MAX)
diag("isel: alloc too large");
emit(OAlloc, i.to, newcon(val, fn), R);
} else {
/* r0 = (i.arg[0] + 15) & -16 */
r0 = newtmp(TLong, fn);
r1 = newtmp(TLong, fn);
emit(OAlloc, i.to, r0, R);
emit(OAnd, r0, r1, newcon(-16, fn));
emit(OAdd, r1, i.arg[0], newcon(15, fn));
}
break;
default:
if (OCmp <= i.op && i.op <= OCmp1) {
c = i.op - OCmp;