shithub: mc

Download patch

ref: e96403b109bba4cf9581079a9bdf7dec22384075
parent: 53d4b23c3f4dc40f8f3d78343b35b12495193fcf
author: Ori Bernstein <[email protected]>
date: Thu Jun 7 12:05:53 EDT 2012

Add blit operator.

    For copying around structs/slices/anything that doesn't fit into
    a register.

--- a/8/isel.c
+++ b/8/isel.c
@@ -518,6 +518,34 @@
     return eax;
 }
 
+void blit(Isel *s, Loc a, Loc b, int sz)
+{
+    int i;
+    Reg sp, dp; /* pointers to src, dst */
+    Loc tmp, src, dst; /* source memory, dst memory */
+
+    sp = inr(s, a).reg;
+    dp = inr(s, b).reg;
+
+    /* Slightly funny loop condition: We might have trailing bytes
+     * that we can't blit word-wise. */
+    tmp = getreg(s, ModeL);
+    for (i = 0; i + 4 <= sz; i+= 4) {
+        locmem(&src, i, sp, Rnone, ModeL);
+        locmem(&dst, i, dp, Rnone, ModeL);
+        g(s, Imov, &src, &tmp, NULL);
+        g(s, Imov, &tmp, &dst, NULL);
+    }
+    /* now, the trailing bytes */
+    tmp = coreg(tmp, ModeB);
+    for (; i < sz; i++) {
+        locmem(&src, i, sp, Rnone, ModeB);
+        locmem(&dst, i, dp, Rnone, ModeB);
+        g(s, Imov, &src, &tmp, NULL);
+        g(s, Imov, &tmp, &dst, NULL);
+    }
+}
+
 Loc selexpr(Isel *s, Node *n)
 {
     Loc a, b, c, r;
@@ -666,7 +694,12 @@
             break;
         case Olbl:
             loclbl(&r, args[0]);
-            break; 
+            break;
+        case Oblit:
+            a = selexpr(s, args[0]);
+            b = selexpr(s, args[1]);
+            blit(s, a, b, args[2]->expr.args[0]->lit.intval);
+            break;
 
         /* These operators should never show up in the reduced trees,
          * since they should have been replaced with more primitive
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -414,31 +414,31 @@
             t = lval(s, args[0]);
             v = mkexpr(-1, Oadd, one, t, NULL);
             r = mkexpr(-1, Ostor, t, v, NULL);
-            lappend(&s->incqueue, &s->nqueue, t); 
+            lappend(&s->incqueue, &s->nqueue, t);
             break;
         case Opredec:
             t = lval(s, args[0]);
             v = mkexpr(-1, Osub, one, t, NULL);
             r = mkexpr(-1, Ostor, t, v, NULL);
-            lappend(&s->incqueue, &s->nqueue, t); 
+            lappend(&s->incqueue, &s->nqueue, t);
             break;
 
         /* expr(x++)
-         *     => 
+         *     =>
          *      expr
-         *      x = x + 1 
+         *      x = x + 1
          */
         case Opostinc:
             r = lval(s, args[0]);
             v = mkexpr(-1, Oadd, one, r, NULL);
             t = mkexpr(-1, Ostor, r, v, NULL);
-            lappend(&s->incqueue, &s->nqueue, t); 
+            lappend(&s->incqueue, &s->nqueue, t);
             break;
         case Opostdec:
             r = lval(s, args[0]);
             v = mkexpr(-1, Osub, one, args[0], NULL);
             t = mkexpr(-1, Ostor, r, v, NULL);
-            lappend(&s->incqueue, &s->nqueue, t); 
+            lappend(&s->incqueue, &s->nqueue, t);
             break;
         case Olit:
         case Ovar:
@@ -457,8 +457,15 @@
             break;
         case Oasn:
             t = lval(s, args[0]);
-            v = rval(s, args[1]);
-            r = mkexpr(-1, Ostor, t, v, NULL);
+            u = rval(s, args[1]);
+            if (size(n) > 4) {
+                t = mkexpr(-1, Oaddr, t, NULL);
+                u = mkexpr(-1, Oaddr, u, NULL);
+                v = mkexpr(-1, Olit, mkint(-1, size(n)), NULL);
+                r = mkexpr(-1, Oblit, t, u, v, NULL);
+            } else {
+              r = mkexpr(-1, Ostor, t, u, NULL);
+            }
             break;
         default:
             for (i = 0; i < n->expr.nargs; i++)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -374,9 +374,10 @@
             break;
         case Olbl:      /* :lbl -> void* */
             settype(n, mktyptr(n->line, mkty(-1, Tyvoid)));
-        case Obad: case Numops: case Ocjmp:
+        case Obad: case Ocjmp:
         case Oload: case Ostor:
         case Oslbase: case Osllen:
+        case Oblit: case Numops:
             die("Should not see %s in fe", opstr(exprop(n)));
             break;
     }
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -52,5 +52,6 @@
 O(Ocjmp, 1)        /* conditional jump */
 O(Oload, 1)        /* load from memory */
 O(Ostor, 1)        /* store to memory */
-O(Osllen, 1)
-O(Oslbase, 1)
+O(Osllen, 1)       /* size of slice */
+O(Oslbase, 1)      /* base of sice */
+O(Oblit, 1)        /* block copy of memory */