summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2012-08-01 21:00:23 -0400
committerOri Bernstein <ori@eigenstate.org>2012-08-01 21:00:23 -0400
commitc2d507cdfe2d67c5d3bb4cc01cec2f0614421599 (patch)
tree29c9113dd642b0878b5c5f9b6c4f899a49d79f18 /6
parent08cf7754b28fc26034bd752022e47ed516686210 (diff)
parente167f13dc955f93afddca65750e0c0be467bf344 (diff)
downloadmc-c2d507cdfe2d67c5d3bb4cc01cec2f0614421599.tar.gz
Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2
Diffstat (limited to '6')
-rw-r--r--6/asm.h1
-rw-r--r--6/insns.def4
-rw-r--r--6/isel.c72
-rw-r--r--6/locs.c65
-rw-r--r--6/ra.c5
-rw-r--r--6/simp.c56
6 files changed, 107 insertions, 96 deletions
diff --git a/6/asm.h b/6/asm.h
index 9851e00..2941e81 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -110,6 +110,7 @@ struct Isel {
Node *ret; /* we store the return into here */
Htab *locs; /* decl id => int stkoff */
+ Htab *reglocs; /* decl id => Loc *reg */
Htab *globls; /* decl id => char *globlname */
/* increased when we spill */
diff --git a/6/insns.def b/6/insns.def
index 8d8e7e7..244f82f 100644
--- a/6/insns.def
+++ b/6/insns.def
@@ -54,8 +54,8 @@ Insn(Isetg, "\tsetg %v\n", Use(), Def(.l={1}))
Insn(Isetge, "\tsetge %v\n", Use(), Def(.l={1}))
/* branch instructions */
-Insn(Icall, "\tcall %v\n", Use(.l={1}), Def())
-Insn(Icallind, "\tcall *%v\n", Use(.l={1}), Def())
+Insn(Icall, "\tcall %v\n", Use(.l={1}), Def(.r={Rrax}))
+Insn(Icallind, "\tcall *%v\n", Use(.l={1}), Def(.r={Rrax}))
Insn(Ijmp, "\tjmp %v\n", Use(.l={1}), Def())
Insn(Ijz, "\tjz %v\n", Use(.l={1}), Def())
Insn(Ijnz, "\tjnz %v\n", Use(.l={1}), Def())
diff --git a/6/isel.c b/6/isel.c
index acb3042..3e0ee29 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -56,12 +56,15 @@ static Mode mode(Node *n)
Type *t;
t = tybase(exprtype(n));
+ /* FIXME: What should the mode for, say, structs be when we have no
+ * intention of loading /through/ the pointer? For now, we'll just say it's
+ * the pointer mode, since we expect to address through the pointer */
switch (t->type) {
case Tyfloat32: return ModeF; break;
case Tyfloat64: return ModeD; break;
default:
if (stacktype(t))
- return ModeNone;
+ return ModeQ;
switch (size(n)) {
case 1: return ModeB; break;
case 2: return ModeS; break;
@@ -70,10 +73,7 @@ static Mode mode(Node *n)
}
break;
}
- /* FIXME: huh. what should the mode for, say, structs
- * be when we have no intention of loading /through/ the
- * pointer? */
- return ModeNone;
+ return ModeQ;
}
static Loc *loc(Isel *s, Node *n)
@@ -94,7 +94,9 @@ static Loc *loc(Isel *s, Node *n)
rip = locphysreg(Rrip);
l = locmeml(htget(s->globls, n), rip, NULL, mode(n));
} else {
- die("%s (id=%ld) not found", namestr(n->expr.args[0]), n->expr.did);
+ if (!hthas(s->reglocs, n))
+ htput(s->reglocs, n, locreg(mode(n)));
+ return htget(s->reglocs, n);
}
break;
case Olit:
@@ -356,19 +358,23 @@ static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size
static Loc *gencall(Isel *s, Node *n)
{
- Loc *src, *dst, *arg, *fn; /* values we reduced */
- Loc *rax, *rsp; /* hard-coded registers */
+ Loc *src, *dst, *arg, *fn; /* values we reduced */
+ Loc *rax, *rsp, *ret; /* hard-coded registers */
Loc *stkbump; /* calculated stack offset */
int argsz, argoff;
size_t i;
rsp = locphysreg(Rrsp);
- if (tybase(exprtype(n))->type == Tyvoid)
+ if (tybase(exprtype(n))->type == Tyvoid) {
rax = NULL;
- else if (stacktype(exprtype(n)))
+ ret = NULL;
+ } else if (stacktype(exprtype(n))) {
rax = locphysreg(Rrax);
- else
+ ret = locreg(ModeQ);
+ } else {
rax = coreg(Rrax, mode(n));
+ ret = locreg(mode(n));
+ }
argsz = 0;
/* Have to calculate the amount to bump the stack
* pointer by in one pass first, otherwise if we push
@@ -405,7 +411,9 @@ static Loc *gencall(Isel *s, Node *n)
g(s, Icallind, fn, NULL);
if (argsz)
g(s, Iadd, stkbump, rsp, NULL);
- return rax;
+ if (rax)
+ g(s, Imov, rax, ret, NULL);
+ return ret;
}
Loc *selexpr(Isel *s, Node *n)
@@ -436,8 +444,9 @@ Loc *selexpr(Isel *s, Node *n)
r = locreg(a->mode);
if (r->mode == ModeB)
g(s, Ixor, eax, eax, NULL);
+ else
+ g(s, Ixor, edx, edx, NULL);
g(s, Imov, a, c, NULL);
- g(s, Ixor, edx, edx, NULL);
g(s, Idiv, b, NULL);
if (exprop(n) == Odiv)
d = coreg(Reax, mode(n));
@@ -568,8 +577,10 @@ Loc *selexpr(Isel *s, Node *n)
r = b;
break;
case Otrunc:
- r = selexpr(s, args[0]);
- r->mode = mode(n);
+ a = selexpr(s, args[0]);
+ a = inr(s, a);
+ r = locreg(mode(n));
+ g(s, Imov, a, r, NULL);
break;
case Ozwiden:
a = selexpr(s, args[0]);
@@ -603,6 +614,7 @@ Loc *selexpr(Isel *s, Node *n)
void locprint(FILE *fd, Loc *l, char spec)
{
+ assert(l->mode);
switch (l->type) {
case Loclitl:
assert(spec == 'i' || spec == 'x' || spec == 'u');
@@ -664,13 +676,26 @@ void iprintf(FILE *fd, Insn *insn)
* means that we need to do a movl when we really want a movzlq. Since
* we don't know the name of the reg to use, we need to sub it in when
* writing... */
- if (insn->op == Imovz) {
- if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
- if (insn->args[1]->reg.colour) {
- insn->op = Imov;
- insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
+ switch (insn->op) {
+ case Imovz:
+ if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
+ if (insn->args[1]->reg.colour) {
+ insn->op = Imov;
+ insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
+ }
}
- }
+ break;
+ case Imov:
+ if (insn->args[0]->type == Locreg && insn->args[1]->type == Locreg &&
+ insn->args[0]->reg.colour != Rnone && insn->args[1]->reg.colour != Rnone) {
+ if (insn->args[0]->mode != insn->args[1]->mode)
+ insn->args[0] = coreg(insn->args[1]->reg.colour, insn->args[1]->mode);
+ /* moving a reg to itself is dumb. */
+ if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ return;
+ }
+ default:
+ break;
}
p = insnfmts[insn->op];
i = 0;
@@ -870,10 +895,15 @@ void genasm(FILE *fd, Func *fn, Htab *globls)
size_t i, j;
char buf[128];
+ is.reglocs = mkht(dclhash, dcleq);
is.locs = fn->locs;
is.globls = globls;
is.ret = fn->ret;
is.cfg = fn->cfg;
+ /* ensure that all physical registers have a loc created, so we
+ * don't get any surprises referring to them in the allocator */
+ for (i = 0; i < Nreg; i++)
+ locphysreg(i);
for (i = 0; i < fn->cfg->nbb; i++)
lappend(&is.bb, &is.nbb, mkasmbb(fn->cfg->bb[i]));
diff --git a/6/locs.c b/6/locs.c
index c95ab7b..b9b2877 100644
--- a/6/locs.c
+++ b/6/locs.c
@@ -189,14 +189,14 @@ Loc *loclit(long val, Mode m)
Loc *coreg(Reg r, Mode m)
{
Reg crtab[][Nmode + 1] = {
- [Ral] = {Rnone, Ral, Rax, Reax, Rrax},
- [Rcl] = {Rnone, Rcl, Rcx, Recx, Rrcx},
- [Rdl] = {Rnone, Rdl, Rdx, Redx, Rrdx},
- [Rbl] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
- [Rsil] = {Rnone, Rsil, Rsi, Resi, Rrsi},
- [Rdil] = {Rnone, Rdil, Rdi, Redi, Rrdi},
- [R8b] = {Rnone, R8b, R8w, R8d, R8},
- [R9b] = {Rnone, R9b, R9w, R9d, R9},
+ [Ral] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Rcl] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Rdl] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rbl] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Rsil] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Rdil] = {Rnone, Rdil, Rdi, Redi, Rrdi},
+ [R8b] = {Rnone, R8b, R8w, R8d, R8},
+ [R9b] = {Rnone, R9b, R9w, R9d, R9},
[R10b] = {Rnone, R10b, R10w, R10d, R10},
[R11b] = {Rnone, R11b, R11w, R11d, R11},
[R12b] = {Rnone, R12b, R12w, R12d, R12},
@@ -204,14 +204,14 @@ Loc *coreg(Reg r, Mode m)
[R14b] = {Rnone, R14b, R14w, R14d, R14},
[R15b] = {Rnone, R15b, R15w, R15d, R15},
- [Rax] = {Rnone, Ral, Rax, Reax, Rrax},
- [Rcx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
- [Rdx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
- [Rbx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
- [Rsi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
- [Rdi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
- [R8w] = {Rnone, R8b, R8w, R8d, R8},
- [R9w] = {Rnone, R9b, R9w, R9d, R9},
+ [Rax] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Rcx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Rdx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rbx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Rsi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Rdi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
+ [R8w] = {Rnone, R8b, R8w, R8d, R8},
+ [R9w] = {Rnone, R9b, R9w, R9d, R9},
[R10w] = {Rnone, R10b, R10w, R10d, R10},
[R11w] = {Rnone, R11b, R11w, R11d, R11},
[R12w] = {Rnone, R12b, R12w, R12d, R12},
@@ -219,14 +219,14 @@ Loc *coreg(Reg r, Mode m)
[R14w] = {Rnone, R14b, R14w, R14d, R14},
[R15w] = {Rnone, R15b, R15w, R15d, R15},
- [Reax] = {Rnone, Ral, Rax, Reax},
- [Recx] = {Rnone, Rcl, Rcx, Recx},
- [Redx] = {Rnone, Rdl, Rdx, Redx},
- [Rebx] = {Rnone, Rbl, Rbx, Rebx},
- [Resi] = {Rnone, Rsil, Rsi, Resi},
- [Redi] = {Rnone, Rsil, Rdi, Redi},
- [R8d] = {Rnone, R8b, R8w, R8d, R8},
- [R9d] = {Rnone, R9b, R9w, R9d, R9},
+ [Reax] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Recx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Redx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rebx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Resi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Redi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
+ [R8d] = {Rnone, R8b, R8w, R8d, R8},
+ [R9d] = {Rnone, R9b, R9w, R9d, R9},
[R10d] = {Rnone, R10b, R10w, R10d, R10},
[R11d] = {Rnone, R11b, R11w, R11d, R11},
[R12d] = {Rnone, R12b, R12w, R12d, R12},
@@ -234,14 +234,14 @@ Loc *coreg(Reg r, Mode m)
[R14d] = {Rnone, R14b, R14w, R14d, R14},
[R15d] = {Rnone, R15b, R15w, R15d, R15},
- [Rrax] = {Rnone, Ral, Rax, Reax, Rrax},
- [Rrcx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
- [Rrdx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
- [Rrbx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
- [Rrsi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
- [Rrdi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
- [R8] = {Rnone, R8b, R8w, R8d, R8},
- [R9] = {Rnone, R9b, R9w, R9d, R9},
+ [Rrax] = {Rnone, Ral, Rax, Reax, Rrax},
+ [Rrcx] = {Rnone, Rcl, Rcx, Recx, Rrcx},
+ [Rrdx] = {Rnone, Rdl, Rdx, Redx, Rrdx},
+ [Rrbx] = {Rnone, Rbl, Rbx, Rebx, Rrbx},
+ [Rrsi] = {Rnone, Rsil, Rsi, Resi, Rrsi},
+ [Rrdi] = {Rnone, Rsil, Rdi, Redi, Rrdi},
+ [R8] = {Rnone, R8b, R8w, R8d, R8},
+ [R9] = {Rnone, R9b, R9w, R9d, R9},
[R10] = {Rnone, R10b, R10w, R10d, R10},
[R11] = {Rnone, R11b, R11w, R11d, R11},
[R12] = {Rnone, R12b, R12w, R12d, R12},
@@ -253,4 +253,3 @@ Loc *coreg(Reg r, Mode m)
assert(crtab[r][m] != Rnone);
return locphysreg(crtab[r][m]);
}
-
diff --git a/6/ra.c b/6/ra.c
index 2c62d9e..a5a8acf 100644
--- a/6/ra.c
+++ b/6/ra.c
@@ -559,6 +559,11 @@ static int combinable(Isel *s, regid u, regid v)
{
regid t;
+ /* Regs of different modes can't be combined as things stand.
+ * In principle they should be combinable, but it confused the
+ * whole mode dance. */
+ if (locmap[u]->mode != locmap[v]->mode)
+ return 0;
/* if u isn't prepainted, can we conservatively coalesce? */
if (!bshas(s->prepainted, u) && conservative(s, u, v))
return 1;
diff --git a/6/simp.c b/6/simp.c
index faa352c..1cb55cb 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -161,30 +161,6 @@ static Node *word(int line, uint v)
return n;
}
-static size_t did(Node *n)
-{
- if (n->type == Ndecl) {
- return n->decl.did;
- } else if (n->type == Nexpr) {
- assert(exprop(n) == Ovar);
- return n->expr.did;
- }
- dump(n, stderr);
- die("Can't get did");
- return 0;
-}
-
-static ulong dclhash(void *dcl)
-{
- /* large-prime hash. meh. */
- return did(dcl) * 366787;
-}
-
-static int dcleq(void *a, void *b)
-{
- return did(a) == did(b);
-}
-
static void append(Simp *s, Node *n)
{
lappend(&s->stmts, &s->nstmts, n);
@@ -546,7 +522,7 @@ static void simpblk(Simp *s, Node *n)
}
}
-static Node *lowerlit(Simp *s, Node *lit, Node ***l, size_t *nl)
+static Node *simplit(Simp *s, Node *lit, Node ***l, size_t *nl)
{
Node *n, *d, *r;
char lbl[128];
@@ -710,7 +686,7 @@ static Node *simplazy(Simp *s, Node *n, Node *r)
return r;
}
-static Node *lowerslice(Simp *s, Node *n, Node *dst)
+static Node *simpslice(Simp *s, Node *n, Node *dst)
{
Node *t;
Node *start, *end;
@@ -735,7 +711,7 @@ static Node *lowerslice(Simp *s, Node *n, Node *dst)
return t;
}
-static Node *lowercast(Simp *s, Node *n)
+static Node *simpcast(Simp *s, Node *n)
{
Node **args;
Node *sz;
@@ -868,7 +844,7 @@ Node *assign(Simp *s, Node *lhs, Node *rhs)
return r;
}
-static Node *lowertup(Simp *s, Node *n, Node *dst)
+static Node *simptup(Simp *s, Node *n, Node *dst)
{
Node *pdst, *pval, *val, *sz, *stor, **args;
Node *r;
@@ -896,7 +872,7 @@ static Node *lowertup(Simp *s, Node *n, Node *dst)
return dst;
}
-static Node *lowerucon(Simp *s, Node *n, Node *dst)
+static Node *simpucon(Simp *s, Node *n, Node *dst)
{
Node *tmp, *u, *tag, *elt, *sz;
Node *r;
@@ -977,7 +953,7 @@ static Node *rval(Simp *s, Node *n, Node *dst)
r->expr.type = exprtype(n);
break;
case Oslice:
- r = lowerslice(s, n, dst);
+ r = simpslice(s, n, dst);
break;
case Oidx:
t = idxaddr(s, n);
@@ -996,14 +972,14 @@ static Node *rval(Simp *s, Node *n, Node *dst)
}
break;
case Ocons:
- r = lowerucon(s, n, dst);
+ r = simpucon(s, n, dst);
break;
case Otup:
- r = lowertup(s, n, dst);
+ r = simptup(s, n, dst);
break;
case Ocast:
/* slice -> ptr cast */
- r = lowercast(s, n);
+ r = simpcast(s, n);
break;
/* fused ops:
@@ -1055,10 +1031,10 @@ static Node *rval(Simp *s, Node *n, Node *dst)
r = n;
break;
case Lstr: case Lseq: case Lflt:
- r = lowerlit(s, n, &s->blobs, &s->nblobs);
+ r = simplit(s, n, &s->blobs, &s->nblobs);
break;
case Lfunc:
- r = lowerlit(s, n, &file->file.stmts, &file->file.nstmts);
+ r = simplit(s, n, &file->file.stmts, &file->file.nstmts);
break;
}
break;
@@ -1202,7 +1178,7 @@ static void flatten(Simp *s, Node *f)
append(s, s->endlbl);
}
-static Func *lowerfn(Simp *s, char *name, Node *n, int export)
+static Func *simpfn(Simp *s, char *name, Node *n, int export)
{
size_t i;
Func *fn;
@@ -1272,7 +1248,7 @@ static void fillglobls(Stab *st, Htab *globls)
free(k);
}
-static void lowerdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
+static void simpdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
{
Simp s = {0,};
char *name;
@@ -1286,7 +1262,7 @@ static void lowerdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***b
if (isconstfn(dcl)) {
if (!dcl->decl.isextern && !dcl->decl.isgeneric) {
- f = lowerfn(&s, name, dcl->decl.init, dcl->decl.isexport);
+ f = simpfn(&s, name, dcl->decl.init, dcl->decl.isexport);
lappend(fn, nfn, f);
}
} else {
@@ -1297,7 +1273,7 @@ static void lowerdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***b
else if (!dcl->decl.isconst && !dcl->decl.init)
lappend(&s.blobs, &s.nblobs, dcl);
else
- die("We don't lower globls with nonlit inits yet...");
+ die("We don't simp globls with nonlit inits yet...");
}
*blob = s.blobs;
*nblob = s.nblobs;
@@ -1333,7 +1309,7 @@ void gen(Node *file, char *out)
case Nuse: /* nothing to do */
break;
case Ndecl:
- lowerdcl(n, globls, &fn, &nfn, &blob, &nblob);
+ simpdcl(n, globls, &fn, &nfn, &blob, &nblob);
break;
default:
die("Bad node %s in toplevel", nodestr(n->type));