ref: 637b1e8cb316cff76682b868012904e77040f034
parent: c4336db289bfad5a3e9274bf181282be86bc6ce7
author: Ori Bernstein <[email protected]>
date: Wed Jun 13 13:18:20 EDT 2012
Put the location allocation into shape For register allocation, we need to assign pseudos. Do this. This breaks every fucking test we have.
--- a/8/asm.h
+++ b/8/asm.h
@@ -17,7 +17,6 @@
Locnone,
Loclbl, /* label */
Locreg, /* register */
- Locpseu, /* pseudo-reg */
Locmem, /* reg offset mem */
Locmeml, /* label offset mem */
Loclit,
@@ -50,8 +49,10 @@
Mode mode;
union {
char *lbl;
- Reg reg;
- long pseudo;
+ struct {
+ long pseudo;
+ Reg colour;
+ } reg;
long lit;
/* disp(base + index) */
struct {
@@ -58,9 +59,9 @@
/* only one of lbldisp and constdisp may be used */
char *lbldisp;
long constdisp;
- int scale;
- Reg base;
- Reg idx;
+ int scale; /* 0,1,2,4, or 8 */
+ Loc *base; /* needed */
+ Loc *idx; /* optional */
} mem;
};
};
@@ -67,7 +68,7 @@
struct Insn {
AsmOp op;
- Loc args[MaxArg];
+ Loc *args[MaxArg];
int narg;
};
@@ -89,6 +90,8 @@
Htab *locs; /* decl id => int stkoff */
Htab *globls; /* decl id => char *globlname */
+ /* increased when we spill */
+ Loc *stksz;
/* 6 general purpose regs */
int rtaken[Nreg];
};
@@ -98,22 +101,20 @@
void gen(Node *file, char *out);
/* location generation */
-Loc *loclbl(Loc *l, Node *lbl);
-Loc *locstrlbl(Loc *l, char *lbl);
-Loc *locreg(Loc *l, Reg r);
-Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode);
-Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode);
-Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode);
-Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode);
-Loc *loclit(Loc *l, long val);
+Loc *loclbl(Node *lbl);
+Loc *locstrlbl(char *lbl);
+Loc *locreg(Mode m);
+Loc *locphysreg(Reg r);
+Loc *locmem(long disp, Loc *base, Loc *idx, Mode mode);
+Loc *locmeml(char *disp, Loc *base, Loc *idx, Mode mode);
+Loc *locmems(long disp, Loc *base, Loc *idx, int scale, Mode mode);
+Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode);
+Loc *loclit(long val);
+
void locprint(FILE *fd, Loc *l);
void iprintf(FILE *fd, Insn *insn);
/* register allocation */
-Loc getreg(Isel *s, Mode m);
-void freeloc(Isel *s, Loc l);
-Loc claimreg(Isel *s, Reg r);
-void freereg(Isel *s, Reg r);
extern const char *regnames[];
extern const Mode regmodes[];
--- a/8/isel.c
+++ b/8/isel.c
@@ -29,7 +29,7 @@
};
/* forward decls */
-Loc selexpr(Isel *s, Node *n);
+Loc *selexpr(Isel *s, Node *n);
/* used to decide which operator is appropriate
* for implementing various conditional operators */
@@ -48,9 +48,9 @@
};
-static Loc loc(Isel *s, Node *n)
+static Loc *loc(Isel *s, Node *n)
{
- Loc l;
+ Loc *l;
Node *v;
size_t stkoff;
@@ -58,9 +58,9 @@
case Ovar:
if (hthas(s->locs, (void*)n->expr.did)) {
stkoff = (size_t)htget(s->locs, (void*)n->expr.did);
- locmem(&l, -stkoff, Rebp, Rnone, ModeL);
+ l = locmem(-stkoff, locphysreg(Rebp), NULL, ModeL);
} else if (hthas(s->globls, (void*)n->expr.did)) {
- locstrlbl(&l, htget(s->globls, (void*)n->expr.did));
+ l = locstrlbl(htget(s->globls, (void*)n->expr.did));
} else {
die("%s (id=%ld) not found", namestr(n->expr.args[0]), n->expr.did);
}
@@ -68,9 +68,9 @@
case Olit:
v = n->expr.args[0];
switch (v->lit.littype) {
- case Lchr: loclit(&l, v->lit.chrval); break;
- case Lbool: loclit(&l, v->lit.boolval); break;
- case Lint: loclit(&l, v->lit.intval); break;
+ case Lchr: l = loclit(v->lit.chrval); break;
+ case Lbool: l = loclit(v->lit.boolval); break;
+ case Lint: l = loclit(v->lit.intval); break;
default:
die("Literal type %s should be blob", litstr(v->lit.littype));
}
@@ -87,10 +87,8 @@
return ModeL;
}
-static Loc coreg(Loc r, Mode m)
+static Loc *coreg(Reg r, Mode m)
{
- Loc l;
-
Reg crtab[][Nmode + 1] = {
[Ral] = {Rnone, Ral, Rax, Reax},
[Rcl] = {Rnone, Rcl, Rcx, Recx},
@@ -111,10 +109,9 @@
[Resi] = {Rnone, Rnone, Rsi, Resi},
[Redi] = {Rnone, Rnone, Rdi, Redi},
};
- if (r.type != Locreg)
- die("Non-reg passed to coreg()");
- locreg(&l, crtab[r.reg][m]);
- return l;
+
+ assert(crtab[r][m] != Rnone);
+ return locphysreg(crtab[r][m]);
}
static Insn *mkinsnv(AsmOp op, va_list ap)
@@ -127,7 +124,7 @@
i = malloc(sizeof(Insn));
i->op = op;
while ((l = va_arg(ap, Loc*)) != NULL)
- i->args[n++] = *l;
+ i->args[n++] = l;
i->narg = n;
return i;
}
@@ -145,43 +142,43 @@
static void load(Isel *s, Loc *a, Loc *b)
{
- Loc l;
+ Loc *l;
assert(b->type == Locreg);
if (a->type == Locreg)
- locmem(&l, 0, b->reg, Rnone, a->mode);
+ locmem(0, b, Rnone, a->mode);
else
- l = *a;
- g(s, Imov, &l, b, NULL);
+ l = a;
+ g(s, Imov, l, b, NULL);
}
static void stor(Isel *s, Loc *a, Loc *b)
{
- Loc l;
+ Loc *l;
assert(a->type == Locreg || a->type == Loclit);
if (b->type == Locreg)
- locmem(&l, 0, b->reg, Rnone, b->mode);
+ locmem(0, b, Rnone, b->mode);
else
- l = *b;
- g(s, Imov, a, &l, NULL);
+ l = b;
+ g(s, Imov, a, l, NULL);
}
/* ensures that a location is within a reg */
-static Loc inr(Isel *s, Loc a)
+static Loc *inr(Isel *s, Loc *a)
{
- Loc r;
+ Loc *r;
- if (a.type == Locreg)
+ if (a->type == Locreg)
return a;
- r = getreg(s, a.mode);
- load(s, &a, &r);
+ r = locreg(a->mode);
+ load(s, a, r);
return r;
}
/* ensures that a location is within a reg or an imm */
-static Loc inri(Isel *s, Loc a)
+static Loc *inri(Isel *s, Loc *a)
{
- if (a.type == Locreg || a.type == Loclit)
+ if (a->type == Locreg || a->type == Loclit)
return a;
else
return inr(s, a);
@@ -188,9 +185,9 @@
}
/* ensures that a location is within a reg or an imm */
-static Loc inrm(Isel *s, Loc a)
+static Loc *inrm(Isel *s, Loc *a)
{
- if (a.type == Locreg || a.type == Locmem)
+ if (a->type == Locreg || a->type == Locmem)
return a;
else
return inr(s, a);
@@ -207,8 +204,8 @@
* directly */
static void selcjmp(Isel *s, Node *n, Node **args)
{
- Loc a, b;
- Loc l1, l2;
+ Loc *a, *b;
+ Loc *l1, *l2;
AsmOp cond, jmp;
cond = reloptab[exprop(args[0])].test;
@@ -227,23 +224,22 @@
}
/* the jump targets will always be evaluated the same way */
- loclbl(&l1, args[1]); /* if true */
- loclbl(&l2, args[2]); /* if false */
+ l1 = loclbl(args[1]); /* if true */
+ l2 = loclbl(args[2]); /* if false */
- g(s, cond, &a, &b, NULL);
- g(s, jmp, &l1, NULL);
- g(s, Ijmp, &l2, NULL);
+ g(s, cond, a, b, NULL);
+ g(s, jmp, l1, NULL);
+ g(s, Ijmp, l2, NULL);
}
-static Loc binop(Isel *s, AsmOp op, Node *x, Node *y)
+static Loc *binop(Isel *s, AsmOp op, Node *x, Node *y)
{
- Loc a, b;
+ Loc *a, *b;
a = selexpr(s, x);
b = selexpr(s, y);
a = inr(s, a);
- g(s, op, &b, &a, NULL);
- freeloc(s, b);
+ g(s, op, b, a, NULL);
return a;
}
@@ -276,10 +272,10 @@
return 1;
}
-static Loc memloc(Isel *s, Node *e, Mode m)
+static Loc *memloc(Isel *s, Node *e, Mode m)
{
Node **args;
- Loc l, b, o; /* location, base, offset */
+ Loc *l, *b, *o; /* location, base, offset */
int scale;
scale = 0;
@@ -290,33 +286,32 @@
o = selexpr(s, args[1]->expr.args[0]);
else
o = selexpr(s, args[1]);
- if (b.type != Locreg)
+ if (b->type != Locreg)
b = inr(s, b);
- if (o.type == Loclit) {
- locmem(&l, o.lit, b.reg, Rnone, m);
- } else if (o.type == Locreg) {
+ if (o->type == Loclit) {
+ locmem(o->lit, b, Rnone, m);
+ } else if (o->type == Locreg) {
b = inr(s, b);
- locmems(&l, 0, b.reg, o.reg, scale, m);
+ l = locmems(0, b, o, scale, m);
}
} else {
l = selexpr(s, e);
- if (l.type == Locreg)
- locmem(&l, 0, l.reg, Rnone, m);
+ if (l->type == Locreg)
+ locmem(0, l, Rnone, m);
}
return l;
}
-static Loc gencall(Isel *s, Node *n)
+static Loc *gencall(Isel *s, Node *n)
{
int argsz, argoff;
size_t i;
- Loc eax, esp; /* hard-coded registers */
- Loc stkbump; /* calculated stack offset */
- Loc dst, arg, fn; /* values we reduced */
+ Loc *eax, *esp; /* hard-coded registers */
+ Loc *stkbump; /* calculated stack offset */
+ Loc *dst, *arg, *fn; /* values we reduced */
- locreg(&esp, Resp);
- locreg(&eax, Reax);
- claimreg(s, Reax);
+ esp = locphysreg(Resp);
+ eax = locphysreg(Reax);
argsz = 0;
/* Have to calculate the amount to bump the stack
* pointer by in one pass first, otherwise if we push
@@ -326,9 +321,9 @@
* We skip the first operand, since it's the function itself */
for (i = 1; i < n->expr.nargs; i++)
argsz += size(n->expr.args[i]);
- loclit(&stkbump, argsz);
+ stkbump = loclit(argsz);
if (argsz)
- g(s, Isub, &stkbump, &esp, NULL);
+ g(s, Isub, stkbump, esp, NULL);
/* Now, we can evaluate the arguments */
argoff = 0;
@@ -335,56 +330,56 @@
for (i = 1; i < n->expr.nargs; i++) {
arg = selexpr(s, n->expr.args[i]);
arg = inri(s, arg);
- locmem(&dst, argoff, Resp, Rnone, arg.mode);
- stor(s, &arg, &dst);
+ dst = locmem(argoff, esp, NULL, arg->mode);
+ stor(s, arg, dst);
argsz += size(n->expr.args[i]);
}
fn = selexpr(s, n->expr.args[0]);
- g(s, Icall, &fn, NULL);
+ g(s, Icall, fn, NULL);
if (argsz)
- g(s, Iadd, &stkbump, &esp, NULL);
+ g(s, Iadd, stkbump, esp, NULL);
return eax;
}
-static void blit(Isel *s, Loc a, Loc b, int sz)
+static void blit(Isel *s, Loc *a, Loc *b, int sz)
{
int i;
- Reg sp, dp; /* pointers to src, dst */
- Loc tmp, src, dst; /* source memory, dst memory */
+ Loc *sp, *dp; /* pointers to src, dst */
+ Loc *tmp, src, dst; /* source memory, dst memory */
- sp = inr(s, a).reg;
- dp = inr(s, b).reg;
+ sp = inr(s, a);
+ dp = inr(s, b);
/* Slightly funny loop condition: We might have trailing bytes
* that we can't blit word-wise. */
- tmp = getreg(s, ModeL);
+ tmp = locreg(ModeL);
for (i = 0; i + 4 <= sz; i+= 4) {
- locmem(&src, i, sp, Rnone, ModeL);
- locmem(&dst, i, dp, Rnone, ModeL);
- g(s, Imov, &src, &tmp, NULL);
- g(s, Imov, &tmp, &dst, NULL);
+ locmem(i, sp, NULL, ModeL);
+ locmem(i, dp, NULL, ModeL);
+ g(s, Imov, src, tmp, NULL);
+ g(s, Imov, tmp, dst, NULL);
}
/* now, the trailing bytes */
- tmp = coreg(tmp, ModeB);
+ tmp = locreg(ModeB);
for (; i < sz; i++) {
- locmem(&src, i, sp, Rnone, ModeB);
- locmem(&dst, i, dp, Rnone, ModeB);
- g(s, Imov, &src, &tmp, NULL);
- g(s, Imov, &tmp, &dst, NULL);
+ locmem(i, sp, NULL, ModeB);
+ locmem(i, dp, NULL, ModeB);
+ g(s, Imov, src, tmp, NULL);
+ g(s, Imov, tmp, dst, NULL);
}
}
-Loc selexpr(Isel *s, Node *n)
+Loc *selexpr(Isel *s, Node *n)
{
- Loc a, b, c, r;
- Loc eax, edx, cl; /* x86 wanst some hard-coded regs */
+ Loc *a, *b, *c, *r;
+ Loc *eax, *edx, *cl; /* x86 wanst some hard-coded regs */
Node **args;
args = n->expr.args;
- r = (Loc){Locnone, };
- locreg(&eax, Reax);
- locreg(&edx, Redx);
- locreg(&cl, Rcl);
+ r = NULL;
+ eax = locphysreg(Reax);
+ edx = locphysreg(Redx);
+ cl = locphysreg(Rcl);
switch (exprop(n)) {
case Oadd: r = binop(s, Iadd, args[0], args[1]); break;
case Osub: r = binop(s, Isub, args[0], args[1]); break;
@@ -394,30 +389,24 @@
case Omul:
/* these get clobbered by the mul insn */
- claimreg(s, Reax);
- claimreg(s, Redx);
a = selexpr(s, args[0]);
b = selexpr(s, args[1]);
b = inr(s, b);
- c = coreg(eax, mode(n));
- g(s, Imov, &a, &c, NULL);
- g(s, Imul, &b, NULL);
- freereg(s, Redx);
+ c = coreg(Reax, mode(n));
+ g(s, Imov, a, c, NULL);
+ g(s, Imul, b, NULL);
r = eax;
break;
case Odiv:
case Omod:
/* these get clobbered by the div insn */
- claimreg(s, Reax);
- claimreg(s, Redx);
a = selexpr(s, args[0]);
b = selexpr(s, args[1]);
b = inr(s, b);
- c = coreg(eax, mode(n));
- g(s, Imov, &a, &c, NULL);
- g(s, Ixor, &edx, &edx, NULL);
- g(s, Idiv, &b, NULL);
- freereg(s, Redx);
+ c = coreg(Reax, mode(n));
+ g(s, Imov, a, c, NULL);
+ g(s, Ixor, edx, edx, NULL);
+ g(s, Idiv, b, NULL);
if (exprop(n) == Odiv)
r = eax;
else
@@ -426,56 +415,53 @@
case Oneg:
r = selexpr(s, args[0]);
r = inr(s, r);
- g(s, Ineg, &r, NULL);
+ g(s, Ineg, r, NULL);
break;
case Obsl:
case Obsr:
- claimreg(s, Rcl); /* shift requires cl as it's arg. stupid. */
a = selexpr(s, args[0]);
a = inr(s, a);
b = selexpr(s, args[1]);
- c = coreg(cl, b.mode);
- g(s, Imov, &b, &c, NULL);
+ c = coreg(Rcl, b->mode);
+ g(s, Imov, b, c, NULL);
if (exprop(n) == Obsr) {
if (istysigned(n->expr.type))
- g(s, Isar, &cl, &a, NULL);
+ g(s, Isar, cl, a, NULL);
else
- g(s, Ishr, &cl, &a, NULL);
+ g(s, Ishr, cl, a, NULL);
} else {
- g(s, Ishl, &cl, &a, NULL);
+ g(s, Ishl, cl, a, NULL);
}
- freeloc(s, cl);
- freeloc(s, b);
r = a;
break;
case Obnot:
r = selexpr(s, args[0]);
r = inrm(s, r);
- g(s, Inot, &r, NULL);
+ g(s, Inot, r, NULL);
break;
case Oderef:
a = selexpr(s, args[0]);
a = inr(s, a);
- r = getreg(s, a.mode);
- locmem(&c, 0, a.reg, Rnone, a.mode);
- g(s, Imov, &c, &r, NULL);
+ r = locreg(a->mode);
+ c = locmem(0, a, Rnone, a->mode);
+ g(s, Imov, c, r, NULL);
break;
case Oaddr:
a = selexpr(s, args[0]);
- r = getreg(s, ModeL);
- g(s, Ilea, &a, &r, NULL);
+ r = locreg(ModeL);
+ g(s, Ilea, a, r, NULL);
break;
case Olnot:
a = selexpr(s, args[0]);
- b = getreg(s, ModeB);
- r = coreg(b, mode(n));
- g(s, reloptab[exprop(n)].test, &a, &a, NULL);
- g(s, reloptab[exprop(n)].getflag, &b, NULL);
- g(s, Imovz, &b, &r, NULL);
+ b = locreg(ModeB);
+ r = locreg(mode(n));
+ g(s, reloptab[exprop(n)].test, a, a, NULL);
+ g(s, reloptab[exprop(n)].getflag, b, NULL);
+ g(s, Imovz, b, r, NULL);
break;
case Oeq: case One: case Ogt: case Oge: case Olt: case Ole:
@@ -482,11 +468,11 @@
a = selexpr(s, args[0]);
b = selexpr(s, args[1]);
b = inr(s, b);
- c = getreg(s, ModeB);
- r = coreg(c, mode(n));
- g(s, reloptab[exprop(n)].test, &a, &b, NULL);
- g(s, reloptab[exprop(n)].getflag, &c, NULL);
- g(s, Imovz, &c, &r, NULL);
+ c = locreg(ModeB);
+ r = locreg(mode(n));
+ g(s, reloptab[exprop(n)].test, a, b, NULL);
+ g(s, reloptab[exprop(n)].getflag, c, NULL);
+ g(s, Imovz, c, r, NULL);
return r;
case Oasn: /* relabel */
@@ -496,13 +482,13 @@
a = memloc(s, args[0], mode(n));
b = selexpr(s, args[1]);
b = inri(s, b);
- g(s, Imov, &b, &a, NULL);
+ g(s, Imov, b, a, NULL);
r = b;
break;
case Oload: /* mem -> reg */
b = memloc(s, args[0], mode(n));
- r = getreg(s, mode(n));
- g(s, Imov, &b, &r, NULL);
+ r = locreg(mode(n));
+ g(s, Imov, b, r, NULL);
break;
case Ocall:
@@ -510,7 +496,7 @@
break;
case Ocast: die("Unimplemented op %s", opstr(exprop(n))); break;
case Ojmp:
- g(s, Ijmp, loclbl(&a, args[0]), NULL);
+ g(s, Ijmp, a = loclbl(args[0]), NULL);
break;
case Ocjmp:
selcjmp(s, n, args);
@@ -521,7 +507,7 @@
r = loc(s, n);
break;
case Olbl:
- loclbl(&r, args[0]);
+ r = loclbl(args[0]);
break;
case Oblit:
b = selexpr(s, args[0]);
@@ -532,12 +518,12 @@
case Oslbase:
a = selexpr(s, args[0]);
a = inr(s, a);
- locmem(&r, 0, a.reg, Rnone, ModeL);
+ locmem(0, a, Rnone, ModeL);
break;
case Osllen:
a = selexpr(s, args[0]);
a = inr(s, a);
- locmem(&r, 4, a.reg, Rnone, ModeL);
+ locmem(4, a, Rnone, ModeL);
break;
/* These operators should never show up in the reduced trees,
@@ -563,13 +549,10 @@
fprintf(fd, "%s", l->lbl);
break;
case Locreg:
- fprintf(fd, "%s", regnames[l->reg]);
- break;
- case Locpseu:
- if (debug)
- fprintf(fd, "%c%lu", modenames[l->mode], l->pseudo);
+ if (l->reg.colour == Rnone)
+ fprintf(fd, "%%P.%ld", l->reg.pseudo);
else
- die("Trying to print pseudoreg %lu", l->pseudo);
+ fprintf(fd, "%s", regnames[l->reg.colour]);
break;
case Locmem:
case Locmeml:
@@ -580,10 +563,12 @@
if (l->mem.lbldisp)
fprintf(fd, "%s", l->mem.lbldisp);
}
- if (l->mem.base)
- fprintf(fd, "(%s", regnames[l->mem.base]);
- if (l->mem.idx)
- fprintf(fd, ",%s", regnames[l->mem.idx]);
+ fprintf(fd, "(");
+ locprint(fd, l->mem.base);
+ if (l->mem.idx) {
+ fprintf(fd, ",");
+ locprint(fd, l->mem.idx);
+ }
if (l->mem.scale)
fprintf(fd, ",%d", l->mem.scale);
if (l->mem.base)
@@ -622,7 +607,7 @@
case 'l':
case 'x':
case 'v':
- locprint(fd, &insn->args[i]);
+ locprint(fd, insn->args[i]);
i++;
break;
case 't':
@@ -632,7 +617,7 @@
modeidx = strtol(p, &p, 10);
if (*p == 't')
- fputc(modenames[insn->args[modeidx].mode], fd);
+ fputc(modenames[insn->args[modeidx]->mode], fd);
else
die("Invalid %%-specifier '%c'", *p);
break;
@@ -644,11 +629,11 @@
static void isel(Isel *s, Node *n)
{
- Loc lbl;
+ Loc *lbl;
switch (n->type) {
case Nlbl:
- g(s, Ilbl, loclbl(&lbl, n), NULL);
+ g(s, Ilbl, lbl = loclbl(n), NULL);
break;
case Nexpr:
selexpr(s, n);
@@ -663,32 +648,33 @@
static void prologue(Isel *s, size_t sz)
{
- Loc esp;
- Loc ebp;
- Loc stksz;
+ Loc *esp;
+ Loc *ebp;
+ Loc *stksz;
- locreg(&esp, Resp);
- locreg(&ebp, Rebp);
- loclit(&stksz, sz);
- g(s, Ipush, &ebp, NULL);
- g(s, Imov, &esp, &ebp, NULL);
- g(s, Isub, &stksz, &esp, NULL);
+ esp = locphysreg(Resp);
+ ebp = locphysreg(Rebp);
+ stksz = loclit(sz);
+ g(s, Ipush, ebp, NULL);
+ g(s, Imov, esp, ebp, NULL);
+ g(s, Isub, stksz, esp, NULL);
+ s->stksz = stksz; /* need to update if we spill */
}
static void epilogue(Isel *s)
{
- Loc esp, ebp, eax;
- Loc ret;
+ Loc *esp, *ebp, *eax;
+ Loc *ret;
- locreg(&esp, Resp);
- locreg(&ebp, Rebp);
- locreg(&eax, Reax);
+ esp = locphysreg(Resp);
+ ebp = locphysreg(Rebp);
+ eax = locphysreg(Reax);
if (s->ret) {
ret = loc(s, s->ret);
- g(s, Imov, &ret, &eax, NULL);
+ g(s, Imov, ret, eax, NULL);
}
- g(s, Imov, &ebp, &esp, NULL);
- g(s, Ipop, &ebp, NULL);
+ g(s, Imov, ebp, esp, NULL);
+ g(s, Ipop, ebp, NULL);
g(s, Iret, NULL);
}
--- a/8/regalloc.c
+++ b/8/regalloc.c
@@ -52,8 +52,11 @@
[Rebp] = {Rebp},
};
-Loc *locstrlbl(Loc *l, char *lbl)
+Loc *locstrlbl(char *lbl)
{
+ Loc *l;
+
+ l = zalloc(sizeof(Loc));
l->type = Loclbl;
l->mode = ModeL;
l->lbl = strdup(lbl);
@@ -60,22 +63,38 @@
return l;
}
-Loc *loclbl(Loc *l, Node *lbl)
+Loc *loclbl(Node *lbl)
{
assert(lbl->type = Nlbl);
- return locstrlbl(l, lbl->lbl.name);
+ return locstrlbl(lbl->lbl.name);
}
-Loc *locreg(Loc *l, Reg r)
+Loc *locreg(Mode m)
{
+ Loc *l;
+ static long nextpseudo;
+
+ l = zalloc(sizeof(Loc));
l->type = Locreg;
- l->mode = regmodes[r];
- l->reg = r;
+ l->mode = m;
+ l->reg.pseudo = nextpseudo++;
return l;
}
-Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode)
+Loc *locphysreg(Reg r)
{
+ Loc *l;
+
+ l = locreg(regmodes[r]);
+ l->reg.colour = r;
+ return l;
+}
+
+Loc *locmem(long disp, Loc *base, Loc *idx, Mode mode)
+{
+ Loc *l;
+
+ l = zalloc(sizeof(Loc));
l->type = Locmem;
l->mode = mode;
l->mem.constdisp = disp;
@@ -85,15 +104,20 @@
return l;
}
-Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode)
+Loc *locmems(long disp, Loc *base, Loc *idx, int scale, Mode mode)
{
- locmem(l, disp, base, idx, mode);
+ Loc *l;
+
+ l = locmem(disp, base, idx, mode);
l->mem.scale = scale;
return l;
}
-Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode)
+Loc *locmeml(char *disp, Loc *base, Loc *idx, Mode mode)
{
+ Loc *l;
+
+ l = zalloc(sizeof(Loc));
l->type = Locmem;
l->mode = mode;
l->mem.lbldisp = strdup(disp);
@@ -103,67 +127,23 @@
return l;
}
-Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode)
+Loc *locmemls(char *disp, Loc *base, Loc *idx, int scale, Mode mode)
{
- locmeml(l, disp, base, idx, mode);
+ Loc *l;
+
+ l = locmeml(disp, base, idx, mode);
l->mem.scale = scale;
return l;
}
-Loc *loclit(Loc *l, long val)
+Loc *loclit(long val)
{
+ Loc *l;
+
+ l = zalloc(sizeof(Loc));
l->type = Loclit;
l->mode = ModeL; /* FIXME: what do we do for mode? */
l->lit = val;
return l;
-}
-
-Loc getreg(Isel *s, Mode m)
-{
-
- Loc l;
- int i;
-
- assert(m != ModeNone);
- l.reg = Rnone;
- for (i = 0; i < Nreg; i++) {
- if (!s->rtaken[i] && regmodes[i] == m) {
- locreg(&l, i);
- break;
- }
- }
- if (l.reg == Rnone)
- die("Not enough registers. Please split your expression and try again (FIXME: implement spilling)");
- for (i = 0; i < Nmode; i++)
- s->rtaken[reginterferes[l.reg][i]] = 1;
-
- return l;
-}
-
-Loc claimreg(Isel *s, Reg r)
-{
- Loc l;
- int i;
-
- if (s->rtaken[r])
- die("Reg %s is already taken", regnames[r]);
- for (i = 0; i < Nmode; i++)
- s->rtaken[reginterferes[r][i]] = 1;
- locreg(&l, r);
- return l;
-}
-
-void freereg(Isel *s, Reg r)
-{
- int i;
-
- for (i = 0; i < Nmode; i++)
- s->rtaken[reginterferes[r][i]] = 0;
-}
-
-void freeloc(Isel *s, Loc l)
-{
- if (l.type == Locreg)
- freereg(s, l.reg);
}