ref: c2d507cdfe2d67c5d3bb4cc01cec2f0614421599
parent: 08cf7754b28fc26034bd752022e47ed516686210
parent: e167f13dc955f93afddca65750e0c0be467bf344
author: Ori Bernstein <[email protected]>
date: Wed Aug 1 17:00:23 EDT 2012
Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2
--- a/6/asm.h
+++ b/6/asm.h
@@ -110,6 +110,7 @@
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 */
--- a/6/insns.def
+++ b/6/insns.def
@@ -54,8 +54,8 @@
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())
--- a/6/isel.c
+++ b/6/isel.c
@@ -56,12 +56,15 @@
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 @@
}
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
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]));
--- a/6/locs.c
+++ b/6/locs.c
@@ -189,14 +189,14 @@
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 @@
[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 @@
[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 @@
[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 @@
assert(crtab[r][m] != Rnone);
return locphysreg(crtab[r][m]);
}
-
--- a/6/ra.c
+++ b/6/ra.c
@@ -559,6 +559,11 @@
{
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;
--- a/6/simp.c
+++ b/6/simp.c
@@ -161,30 +161,6 @@
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 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 @@
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 @@
return t;
}
-static Node *lowercast(Simp *s, Node *n)
+static Node *simpcast(Simp *s, Node *n)
{
Node **args;
Node *sz;
@@ -868,7 +844,7 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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));
--- a/parse/node.c
+++ b/parse/node.c
@@ -335,3 +335,28 @@
assert(name->type == Nname);
return name->name.name;
}
+
+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;
+}
+
+ulong dclhash(void *dcl)
+{
+ /* large-prime hash. meh. */
+ return did(dcl) * 366787;
+}
+
+int dcleq(void *a, void *b)
+{
+ return did(a) == did(b);
+}
+
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -393,6 +393,8 @@
void addstmt(Node *file, Node *stmt);
void setns(Node *n, char *ns);
void updatens(Stab *st, char *ns);
+ulong dclhash(void *dcl);
+int dcleq(void *a, void *b);
Op exprop(Node *n);
/* specialize generics */
--- a/util/muse.c
+++ b/util/muse.c
@@ -69,6 +69,8 @@
st = file->file.exports;
f = fopen(path, "r");
+ if (!f)
+ die("Couldn't open %s\n", path);
loaduse(f, st);
fclose(f);
}