shithub: mc

Download patch

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);
 }