shithub: mc

Download patch

ref: 2b00b4a0fc8f56bd47fa9e8fab3a9e47add497fc
parent: f60dbb91eeb4bd2c39242669a5f35252aab21fce
author: Ori Bernstein <[email protected]>
date: Wed Jun 6 19:49:52 EDT 2012

Add missing test files.

--- a/8/asm.h
+++ b/8/asm.h
@@ -54,6 +54,7 @@
             /* only one of lbldisp and constdisp may be used */
             char *lbldisp;
             long constdisp;
+            int scale;
             Reg base;
             Reg idx;
         } mem;
@@ -85,8 +86,11 @@
 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);
 
 /* useful functions */
 size_t size(Node *n);
 void breakhere();
+
--- a/8/isel.c
+++ b/8/isel.c
@@ -121,9 +121,17 @@
     l->mem.constdisp = disp;
     l->mem.base = base;
     l->mem.idx = idx;
+    l->mem.scale = 0;
     return l;
 }
 
+Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode)
+{
+    locmem(l, disp, base, idx, mode);
+    l->mem.scale = scale;
+    return l;
+}
+
 Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode)
 {
     l->type = Locmem;
@@ -131,9 +139,18 @@
     l->mem.lbldisp = strdup(disp);
     l->mem.base = base;
     l->mem.idx = idx;
+    l->mem.scale = 0;
     return l;
 }
 
+Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode)
+{
+    locmeml(l, disp, base, idx, mode);
+    l->mem.scale = scale;
+    return l;
+}
+
+
 Loc *loclit(Loc *l, long val)
 {
     l->type = Loclit;
@@ -394,11 +411,29 @@
     return a;
 }
 
+static int ismergablemul(Node *n, int *r)
+{
+    int v;
+
+    if (exprop(n) != Omul)
+        return 0;
+    if (exprop(n->expr.args[1]) != Olit)
+        return 0;
+    if (n->expr.args[1]->expr.args[0]->type != Nlit)
+        return 0;
+    if (n->expr.args[1]->expr.args[0]->lit.littype != Lint)
+        return 0;
+    v = n->expr.args[1]->expr.args[0]->lit.intval;
+    if (v != 2 && v != 4 && v != 8)
+        return 0;
+    *r = v;
+    return 1;
+}
 /* We have a few common cases to optimize here:
  *    Oadd(
  *        reg,
  *        reg||const))
- * TODO:
+ * or:
  *    Oadd(
  *        reg,
  *        Omul(reg,
@@ -408,11 +443,16 @@
 {
     Node **args;
     Loc l, b, o; /* location, base, offset */
+    int scale;
 
+    scale = 0;
     if (exprop(e) == Oadd) {
         args = e->expr.args;
         b = selexpr(s, args[0]);
-        o = selexpr(s, args[1]);
+        if (ismergablemul(args[1], &scale))
+            o = selexpr(s, args[1]->expr.args[0]);
+        else
+            o = selexpr(s, args[1]);
         if (b.type != Locreg)
             b = inr(s, b);
         if (o.type == Loclit) {
@@ -419,7 +459,7 @@
             locmem(&l, o.lit, b.reg, Rnone, m);
         } else if (o.type == Locreg) {
             b = inr(s, b);
-            locmem(&l, 0, b.reg, o.reg, m);
+            locmems(&l, 0, b.reg, o.reg, scale, m);
         }
     } else {
         l = selexpr(s, e);
@@ -472,6 +512,7 @@
 Loc selexpr(Isel *s, Node *n)
 {
     Loc a, b, c, r;
+    Loc eax;
     Node **args;
 
     args = n->expr.args;
@@ -480,7 +521,14 @@
         case Oadd:      r = binop(s, Iadd, args[0], args[1]); break;
         case Osub:      r = binop(s, Isub, args[0], args[1]); break;
 
-        case Omul:      die("Unimplemented op %s", opstr(exprop(n))); break;
+        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]);
+            r = 
+            break;
         case Odiv:      die("Unimplemented op %s", opstr(exprop(n))); break;
         case Omod:      die("Unimplemented op %s", opstr(exprop(n))); break;
         case Oneg:      die("Unimplemented op %s", opstr(exprop(n))); break;
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -295,8 +295,10 @@
 
 static Node *idxaddr(Simp *s, Node *n)
 {
-    Node *t, *u, *r;
+    Node *t, *u, *v; /* temps */
+    Node *r; /* result */
     Node **args;
+    size_t sz;
 
     assert(exprop(n) == Oidx);
     args = n->expr.args;
@@ -307,23 +309,28 @@
     else
         die("Can't index type %s\n", tystr(n->expr.type));
     u = rval(s, args[1]);
-    r = mkexpr(-1, Oadd, t, u, NULL);
+    sz = size(n);
+    v = mkexpr(-1, Omul, u, mkexpr(-1, Olit, mkint(-1, sz), NULL));
+    r = mkexpr(-1, Oadd, t, v, NULL);
     return r;
 }
 
 static Node *slicebase(Simp *s, Node *n, Node *off)
 {
-    Node *t, *u;
+    Node *t, *u, *v;
+    int sz;
 
     t = rval(s, n);
     u = NULL;
     switch (n->expr.type->type) {
         case Typtr:     u = n;
-        case Tyarray:   u = mkexpr(-1, Oaddr, n, NULL); break;
-        case Tyslice:   u = mkexpr(-1, Oslbase, n, NULL); break;
+        case Tyarray:   u = mkexpr(-1, Oaddr, t, NULL); break;
+        case Tyslice:   u = mkexpr(-1, Oslbase, t, NULL); break;
         default: die("Unslicable type %s", tystr(n->expr.type));
     }
-    return mkexpr(-1, Oadd, u, off, NULL);
+    sz = tysize(n->expr.args[0]->expr.type->sub[0]);
+    v = mkexpr(-1, Omul, u, mkexpr(-1, Olit, mkint(-1, sz), NULL));
+    return mkexpr(-1, Oadd, u, v, NULL);
 }
 
 Node *lval(Simp *s, Node *n)
--- /dev/null
+++ b/test/call.myr
@@ -1,0 +1,7 @@
+const f = {
+	-> 21
+}
+
+const main = {
+	-> f() + f()
+}
--- /dev/null
+++ b/test/loop.myr
@@ -1,0 +1,14 @@
+const f = {a
+}
+
+const main = {
+	var i
+	var n
+	i = f
+
+	n = 0
+	for i = 0; i < 10; ++i
+		n += i
+	;;
+	-> n
+}