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 | |
parent | dab9590ce754e6fd4b3a311a195fcf797c3b3eb3 (diff) | |
download | roux-9fcad221d074f09bde0ff7da9a49558d2ab067c7.tar.gz |
save callee-save registers
-rw-r--r-- | lisc/emit.c | 20 | ||||
-rw-r--r-- | lisc/isel.c | 24 | ||||
-rw-r--r-- | lisc/lisc.h | 17 | ||||
-rw-r--r-- | lisc/rega.c | 12 |
4 files changed, 50 insertions, 23 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" diff --git a/lisc/isel.c b/lisc/isel.c index c4d7dca..8c428e7 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -486,42 +486,46 @@ classify(Ins *i0, Ins *i1, AClass *ac, int op) } int rsave[NRSave] = {RDI, RSI, RDX, RCX, R8, R9, R10, R11, RAX}; +int rclob[NRClob] = {RBX, R12, R13, R14, R15}; -uint64_t calldef(Ins i, int *p) +ulong +calldef(Ins i, int *p) { - uint64_t b; + ulong b; int n; n = i.arg[1].val & 15; - b = 1ll << RAX; + b = BIT(RAX); if (n == 2) - b |= 1ll << RDX; + b |= BIT(RDX); if (p) *p = n; return b; } -uint64_t calluse(Ins i, int *p) +ulong +calluse(Ins i, int *p) { - uint64_t b; + ulong b; int j, n; n = (i.arg[1].val >> 4) & 15; for (j = 0, b = 0; j < n; j++) - b |= 1ll << rsave[j]; + b |= BIT(rsave[j]); if (p) *p = n; return b; } -uint64_t callclb(Ins i, int *p) +ulong +callclb(Ins i, int *p) { - uint64_t b; + ulong b; int j, n; n = (i.arg[1].val >> 4) & 15; for (j = n, b = 0; j < NRSave; j++) - b |= 1ll << rsave[j]; + b |= BIT(rsave[j]); if (p) *p = n; return b; diff --git a/lisc/lisc.h b/lisc/lisc.h index 930651d..43713a5 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -5,6 +5,7 @@ #include <string.h> typedef unsigned int uint; +typedef unsigned long long ulong; typedef struct Bits Bits; typedef struct Ref Ref; @@ -45,6 +46,7 @@ enum Reg { NReg = R12 - RAX + 1, NRSave = 9, + NRClob = 5, }; enum { @@ -61,12 +63,13 @@ enum { }; struct Bits { - uint64_t t[BITS]; + ulong t[BITS]; }; +#define BIT(n) (1ull << (n)) #define BGET(b, n) (1&((b).t[n/NBit]>>(n%NBit))) -#define BSET(b, n) ((b).t[n/NBit] |= 1ll<<(n%NBit)) -#define BCLR(b, n) ((b).t[n/NBit] &= ~(1ll<<(n%NBit))) +#define BSET(b, n) ((b).t[n/NBit] |= BIT(n%NBit)) +#define BCLR(b, n) ((b).t[n/NBit] &= ~BIT(n%NBit)) struct Ref { uint16_t type:2; @@ -240,6 +243,7 @@ struct Fn { int ncon; int nblk; Blk **rpo; + ulong reg; int svec[NAlign]; char name[NString]; }; @@ -280,9 +284,10 @@ void filllive(Fn *); /* isel.c */ extern int rsave[NRSave]; -uint64_t calldef(Ins, int *); -uint64_t calluse(Ins, int *); -uint64_t callclb(Ins, int *); +extern int rclob[NRClob]; +ulong calldef(Ins, int *); +ulong calluse(Ins, int *); +ulong callclb(Ins, int *); int slota(int, int, int *); void isel(Fn *); diff --git a/lisc/rega.c b/lisc/rega.c index e792d55..66836be 100644 --- a/lisc/rega.c +++ b/lisc/rega.c @@ -13,6 +13,7 @@ struct RMap { }; extern Ins insb[NIns], *curi; +static ulong regu; /* registers used */ static Tmp *tmp; /* function temporaries */ static struct { Ref src, dst; @@ -58,6 +59,7 @@ radd(RMap *m, int t, int r) m->t[m->n] = t; m->r[m->n] = r; m->n++; + regu |= BIT(r); } static Ref @@ -218,7 +220,7 @@ dopm(Blk *b, Ins *i, RMap *m) RMap m0; int n, r, r1, t, nins; Ins *i1, *ib, *ip, *ir; - uint64_t def; + ulong def; m0 = *m; i1 = i+1; @@ -233,7 +235,7 @@ dopm(Blk *b, Ins *i, RMap *m) if (i > b->ins && (i-1)->op == OCall) { def = calldef(*i, 0); for (r=0; r<NRSave; r++) - if (!((1ll << rsave[r]) & def)) + if (!(BIT(rsave[r]) & def)) move(rsave[r], R, m); } for (npm=0, n=0; n<m->n; n++) @@ -280,8 +282,9 @@ rega(Fn *fn) Phi *p; uint a; Ref src, dst; - uint64_t rs; + ulong rs; + regu = 0; tmp = fn->tmp; end = alloc(fn->nblk * sizeof end[0]); beg = alloc(fn->nblk * sizeof beg[0]); @@ -322,7 +325,7 @@ rega(Fn *fn) case OCall: rs = calluse(*i, 0); for (r=0; r<NRSave; r++) - if (!((1ll << rsave[r]) & rs)) + if (!(BIT(rsave[r]) & rs)) rfree(&cur, rsave[r]); continue; case OCopy: @@ -430,6 +433,7 @@ rega(Fn *fn) b->phi = p->link; free(p); } + fn->reg = regu; free(end); free(beg); |