shithub: mc

Download patch

ref: 1eb59b7b99d6dbb3c37cc9c8503450427f4d9564
parent: 245116529d23936eb8da6537359e5467e064baab
author: Ori Bernstein <[email protected]>
date: Fri Jun 8 10:33:54 EDT 2012

Reduce slices correctly.

    Now, slicing creates stores/loads to the slice components. A good
    optimization opportunity would involve recognizing
        Oasn(some_slice, Oslice(some_slicable, start, end))
    But that's for another day.

    I think this is as far as I can get without rudimentary register
    allocation.

--- a/8/isel.c
+++ b/8/isel.c
@@ -39,7 +39,7 @@
 #undef Reg
 };
 
-const Reg reginterferes[][Nmode + 1] = {
+const Reg reginterferes[Nreg][Nmode + 1] = {
     /* byte */
     [Ral] = {Ral, Rax, Reax},
     [Rcl] = {Rcl, Rcx, Recx},
@@ -61,6 +61,8 @@
     [Rebx] = {Rbl, Rbx, Rebx},
     [Resi] = {Rsi, Resi},
     [Redi] = {Rdi, Redi},
+    [Resp] = {Resp},
+    [Rebp] = {Rebp},
 };
 
 char *insnfmts[] = {
@@ -699,7 +701,18 @@
             b = selexpr(s, args[0]);
             a = selexpr(s, args[1]);
             blit(s, a, b, args[2]->expr.args[0]->lit.intval);
+            r = b;
             break;
+        case Oslbase:
+            a = selexpr(s, args[0]);
+            a = inr(s, a);
+            locmem(&r, 0, a.reg, Rnone, ModeL);
+            break;
+        case Osllen:
+            a = selexpr(s, args[0]);
+            a = inr(s, a);
+            locmem(&r, 4, a.reg, Rnone, ModeL);
+            break;
 
         /* These operators should never show up in the reduced trees,
          * since they should have been replaced with more primitive
@@ -709,7 +722,6 @@
         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:
-        case Oslbase: case Osllen:
             dump(n, stdout);
             die("Should not see %s in isel", opstr(exprop(n)));
             break;
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -371,6 +371,25 @@
     return r;
 }
 
+Node *lowerslice(Simp *s, Node *n)
+{
+    Node *t;
+    Node *base;
+    Node *len;
+    Node *stbase;
+    Node *stlen;
+
+    t = temp(s, n);
+    /* base = (void*)base + off*sz */
+    base = slicebase(s, n->expr.args[0], n->expr.args[1]);
+    len = mkexpr(-1, Osub, n->expr.args[2], n->expr.args[1], NULL);
+    stbase = mkexpr(-1, Ostor, mkexpr(-1, Oaddr, mkexpr(-1, Oslbase, t, NULL), NULL), base, NULL);
+    stlen = mkexpr(-1, Ostor, mkexpr(-1, Oaddr, mkexpr(-1, Osllen, t, NULL), NULL), len, NULL);
+    append(s, stbase);
+    append(s, stlen);
+    return t;
+}
+
 Node *rval(Simp *s, Node *n)
 {
     Node *r; /* expression result */
@@ -404,11 +423,7 @@
             r = mkexpr(-1, Olit, mkint(-1, size(args[0])), NULL);
             break;
         case Oslice:
-            /* normalize to '(base + off)[0,len]' */
-            args[0] = slicebase(s, args[0], args[1]);
-            args[2] = mkexpr(-1, Osub, args[2], args[1], NULL);
-            args[1] = mkexpr(-1, Olit, mkint(-1, 0), NULL);
-            r = n;
+            r = lowerslice(s, n);
             break;
         case Oidx:
             t = idxaddr(s, n);