From 78bf28f56e7dcdd89efba5c69bd90ed858658162 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Wed, 12 Aug 2015 15:25:53 -0400 Subject: add basic support for stack allocation --- lisc/isel.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'lisc/isel.c') diff --git a/lisc/isel.c b/lisc/isel.c index 7c634d8..5b83081 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -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; cncon; 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; -- cgit 1.4.1