shithub: mc

Download patch

ref: fa492d6d9f5addf0231506d9c8f97308152eca23
parent: 00b71aa9ba7d44b7231da3c139eec45c22844a81
author: Ori Bernstein <[email protected]>
date: Sun May 6 14:00:58 EDT 2012

More work towards instruction selection working.

    Reduce more instructions to their primitive form, and select
    more instruction types.

--- a/8/insns.def
+++ b/8/insns.def
@@ -36,13 +36,13 @@
 Insn(Isetge,      "\tsetge\n",                  0)
 
 /* branch instructions */
-Insn(Ijmp,      "\tjmp\n",                      0)
-Insn(Ijz,       "\tjz\n",                       0)
-Insn(Ijnz,      "\tjnz\n",                      0)
-Insn(Ijlt,      "\tjlt\n",                      0)
-Insn(Ijle,      "\tjle\n",                      0)
-Insn(Ijgt,      "\tjgt\n",                      0)
-Insn(Ijge,      "\tjge\n",                      0)
+Insn(Ijmp,      "\tjmp %v\n",                   0)
+Insn(Ijz,       "\tjz %v\n",                    0)
+Insn(Ijnz,      "\tjnz %v\n",                   0)
+Insn(Ijlt,      "\tjlt %v\n",                   0)
+Insn(Ijle,      "\tjle %v\n",                   0)
+Insn(Ijgt,      "\tjgt %v\n",                   0)
+Insn(Ijge,      "\tjge %v\n",                   0)
 Insn(Iret,      "\tret\n",                      0)
 
 /* not really an insn... */
--- a/8/isel.c
+++ b/8/isel.c
@@ -48,6 +48,7 @@
     AsmOp jmp;
     AsmOp getflag;
 } reloptab[Numops] = {
+    [Olnot] = {Itest, Ijz, Isetz},
     [Oeq] = {Itest, Ijnz, Isetnz},
     [One] = {Itest, Ijz, Isetz},
     [Ogt] = {Icmp, Ijgt, Isetgt},
@@ -61,11 +62,12 @@
 Loc selexpr(Isel *s, Node *n);
 
 
-Loc *loclbl(Loc *l, char *lbl)
+Loc *loclbl(Loc *l, Node *lbl)
 {
+    assert(lbl->type = Nlbl);
     l->type = Loclbl;
     l->mode = ModeL;
-    l->lbl = strdup(lbl);
+    l->lbl = strdup(lbl->lbl.name);
     return l;
 }
 
@@ -248,8 +250,8 @@
     }
 
     /* the jump targets will always be evaluated the same way */
-    l1 = selexpr(s, args[1]); /* if true */
-    l2 = selexpr(s, args[2]); /* if false */
+    loclbl(&l1, args[1]); /* if true */
+    loclbl(&l2, args[2]); /* if false */
 
     g(s, cond, &a, &b, NULL);
     g(s, jmp, &l1, NULL);
@@ -293,6 +295,15 @@
         case Oaddr: die("Unimplemented op %s", opstr(exprop(n))); break;
         case Oderef: die("Unimplemented op %s", opstr(exprop(n))); 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);
+            break;
+
         case Oeq: case One: case Ogt: case Oge: case Olt: case Ole:
             a = selexpr(s, args[0]);
             b = selexpr(s, args[1]);
@@ -300,7 +311,7 @@
             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);
+            g(s, Imovz, &c, &r, NULL);
             return r;
 
         case Oasn:
@@ -313,7 +324,7 @@
         case Ocall: die("Unimplemented op %s", opstr(exprop(n))); break;
         case Ocast: die("Unimplemented op %s", opstr(exprop(n))); break;
         case Ojmp:
-            g(s, Ijmp, loclbl(&a, args[0]->lbl.name), NULL);
+            g(s, Ijmp, loclbl(&a, args[0]), NULL);
             break;
         case Ocjmp:
             selcjmp(s, n, args);
@@ -320,6 +331,8 @@
             break;
 
         case Olit: /* fall through */
+            r = loc(s, n);
+            break;
         case Ovar:
             b = loc(s, n);
             a = getreg(s, mode(args[0]));
@@ -327,14 +340,14 @@
             r = b;
             break;
         case Olbl:
-            loclbl(&r, args[0]->lbl.name);
-            break;
+            loclbl(&r, args[0]);
+            break; 
 
         /* These operators should never show up in the reduced trees,
          * since they should have been replaced with more primitive
          * expressions by now */
         case Obad: case Oret: case Opreinc: case Opostinc: case Opredec:
-        case Opostdec: case Olor: case Oland: case Olnot: case Oaddeq:
+        case Opostdec: case Olor: case Oland: case Oaddeq:
         case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
         case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
         case Oslice: case Oidx: case Osize: case Numops:
@@ -435,7 +448,7 @@
 
     switch (n->type) {
         case Nlbl:
-            g(s, Ilbl, loclbl(&lbl, n->lbl.name), NULL);
+            g(s, Ilbl, loclbl(&lbl, n), NULL);
             break;
         case Nexpr:
             selexpr(s, n);
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -23,8 +23,14 @@
 struct Simp {
     Node **blk;
     size_t nblk;
+
+    /* return handling */
     Node *endlbl;
     Node *retval;
+
+    /* pre/postinc handling */
+    Node **incqueue;
+    size_t nqueue;
 };
 
 Node *simp(Simp *s, Node *n);
@@ -152,9 +158,72 @@
 {
     Node *r, *t, *v;
     int i;
+    Node **args;
+    const Op fusedmap[] = {
+        [Osubeq]        = Osub,
+        [Omuleq]        = Omul,
+        [Odiveq]        = Odiv,
+        [Omodeq]        = Omod,
+        [Oboreq]        = Obor,
+        [Obandeq]       = Oband,
+        [Obxoreq]       = Obxor,
+        [Obsleq]        = Obsl,
+    };
 
+
     r = NULL;
+    args = n->expr.args;
     switch (exprop(n)) {
+        case Obad: 
+        case Olor: case Oland: case Oaddeq:
+        case Obsreq: case Omemb:
+        case Oslice: case Oidx: case Osize:
+            die("Have not implemented lowering op %s", opstr(exprop(n)));
+            break;
+
+        /* fused ops:
+         * foo ?= blah
+         *    =>
+         *     foo = foo ? blah*/
+        case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
+        case Obandeq: case Obxoreq: case Obsleq:
+            v = mkexpr(-1, fusedmap[exprop(n)], args[0], args[1], NULL);
+            r = mkexpr(-1, Oasn, args[0], v, NULL);
+            break;
+
+        /* ++expr(x)
+         *  => x = x + 1
+         *     expr(x) */
+        case Opreinc:
+            t = simp(s, args[0]);
+            v = mkexpr(-1, Oadd, mkint(-1, 1), args[0], NULL);
+            r = mkexpr(-1, Oasn, args[0], v, NULL);
+            lappend(&s->incqueue, &s->nqueue, t); 
+            break;
+        case Opredec:
+            t = simp(s, args[0]);
+            v = mkexpr(-1, Oadd, mkint(-1, -1), args[0], NULL);
+            r = mkexpr(-1, Oasn, args[0], v, NULL);
+            lappend(&s->incqueue, &s->nqueue, t); 
+            break;
+
+        /* expr(x++)
+         *     => 
+         *      expr
+         *      x = x + 1 
+         */
+        case Opostinc:
+            r = simp(s, args[0]);
+            v = mkexpr(-1, Oadd, mkint(-1, 1), r, NULL);
+            t = mkexpr(-1, Oasn, args[0], v, NULL);
+            lappend(&s->incqueue, &s->nqueue, t); 
+            break;
+        case Opostdec:
+            r = simp(s, args[0]);
+            v = mkexpr(-1, Osub, mkint(-1, -1), args[0], NULL);
+            t = mkexpr(-1, Oasn, args[0], v, NULL);
+            lappend(&s->incqueue, &s->nqueue, t); 
+            break;
         case Ovar:
             r = n;
             break;
@@ -221,31 +290,11 @@
     s.nblk = 0;
     s.endlbl = genlbl();
     s.retval = NULL;
-    switch (n->type) {
-        /* these should never be inside functions */
-        case Nnone:
-        case Nfile:
-            die("Bad node type in func");
-            break;
-        case Nfunc:
-            die("FIXME: generate thunks");
-            break;
-            /* no code generated */
-        case Nuse:
-            break;
-            /* complex nodes */
-        case Nblock:
-            simp(&s, n);
-            break;
-        case Nifstmt:
-        case Nloopstmt:
-        case Nexpr:
-        case Nlit:
-        case Nname:
-        case Ndecl:
-        case Nlbl:
-            break;
-    }
+    if (n->type == Nblock)
+        simp(&s, n);
+    else
+        die("Got a non-block (%s) to reduce", nodestr(n->type));
+
     append(&s, s.endlbl);
 
     *ret_nn = s.nblk;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -302,7 +302,6 @@
 Node *mkuse(int line, char *use, int islocal);
 Node *mkexpr(int line, Op op, ...); /* NULL terminated */
 Node *mkcall(int line, Node *fn, Node **args, size_t nargs);
-Node *mklit(int line, Littype lt, void *val);
 Node *mkif(int line, Node *cond, Node *iftrue, Node *iffalse);
 Node *mkloop(int line, Node *init, Node *cond, Node *incr, Node *body);
 Node *mkblock(int line, Stab *scope);