diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-20 17:46:17 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-09-20 17:47:23 -0400 |
commit | 9fcad221d074f09bde0ff7da9a49558d2ab067c7 (patch) | |
tree | a186bf9bfd28c0083ca92f017996333b71305f35 /lisc/emit.c | |
parent | dab9590ce754e6fd4b3a311a195fcf797c3b3eb3 (diff) | |
download | roux-9fcad221d074f09bde0ff7da9a49558d2ab067c7.tar.gz |
save callee-save registers
Diffstat (limited to 'lisc/emit.c')
-rw-r--r-- | lisc/emit.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 7b15229..116d0d2 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -286,14 +286,17 @@ eins(Ins i, Fn *fn, FILE *f) static int framesz(Fn *fn) { - int i, a, f; + int i, o, a, f; + for (i=0, o=0; i<NRClob; i++) + o ^= 1 & (fn->reg >> rclob[i]); f = 0; for (i=NAlign-1, a=1<<i; i>=0; i--, a/=2) if (f == 0 || f - a == fn->svec[i]) f = fn->svec[i]; a = 1 << (NAlign-2); - while ((f + a) % (2 * a) != a) + o *= a; + while ((f + o) % (2 * a)) f += a - f % a; return f * 16 / (1 << (NAlign-1)); } @@ -303,7 +306,7 @@ emitfn(Fn *fn, FILE *f) { Blk *b, *s; Ins *i; - int c, fs; + int r, j, c, fs; fprintf(f, ".text\n" @@ -317,12 +320,23 @@ emitfn(Fn *fn, FILE *f) fs = framesz(fn); if (fs) fprintf(f, "\tsub $%d, %%rsp\n", fs); + for (j=0; j<NRClob; j++) { + r = rclob[j]; + if (fn->reg & BIT(r)) + emitf(fn, f, "\tpush%w %R\n", 1, TMP(r)); + } + for (b=fn->start; b; b=b->link) { fprintf(f, ".L%s:\n", b->name); for (i=b->ins; i-b->ins < b->nins; i++) eins(*i, fn, f); switch (b->jmp.type) { case JRet: + for (j=NRClob; j>=0; j--) { + r = rclob[j]; + if (fn->reg & BIT(r)) + emitf(fn, f, "\tpop%w %R\n", 1, TMP(r)); + } fprintf(f, "\tleave\n" "\tret\n" |