summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisc/emit.c20
-rw-r--r--lisc/isel.c24
-rw-r--r--lisc/lisc.h17
-rw-r--r--lisc/rega.c12
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);