shithub: mc

Download patch

ref: af80a22d3c4d5345af67f749aee6008ae6d2e92f
parent: e285c2cb9e9a0fcdd2c4dce862842b691713e7a0
author: Ori Bernstein <[email protected]>
date: Tue Jun 19 08:45:53 EDT 2012

Try to store large values correctly through calls.

--- a/8/isel.c
+++ b/8/isel.c
@@ -323,6 +323,34 @@
     return l;
 }
 
+static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz)
+{
+    size_t i;
+    Loc *sp, *dp; /* pointers to src, dst */
+    Loc *tmp, *src, *dst; /* source memory, dst memory */
+
+    sp = inr(s, from);
+    dp = inr(s, to);
+
+    /* Slightly funny loop condition: We might have trailing bytes
+     * that we can't blit word-wise. */
+    tmp = locreg(ModeL);
+    for (i = 0; i < sz/4; i++) {
+        src = locmem(i*4 + srcoff, sp, NULL, ModeL);
+        dst = locmem(i*4 + dstoff, dp, NULL, ModeL);
+        g(s, Imov, src, tmp, NULL);
+        g(s, Imov, tmp, dst, NULL);
+    }
+    /* now, the trailing bytes */
+    tmp = locreg(ModeB);
+    for (; i < sz%4; i++) {
+        src = locmem(i, sp, NULL, ModeB);
+        dst = locmem(i, dp, NULL, ModeB);
+        g(s, Imov, src, tmp, NULL);
+        g(s, Imov, tmp, dst, NULL);
+    }
+}
+
 static Loc *gencall(Isel *s, Node *n)
 {
     int argsz, argoff;
@@ -350,9 +378,14 @@
     argoff = 0;
     for (i = 1; i < n->expr.nargs; i++) {
         arg = selexpr(s, n->expr.args[i]);
-        arg = inri(s, arg);
-        dst = locmem(argoff, esp, NULL, arg->mode);
-        stor(s, arg, dst);
+        if (size(n->expr.args[i]) > 4) {
+            dst = locreg(ModeL);
+            blit(s, esp, arg, argoff, 0, size(n->expr.args[i]));
+        } else {
+            dst = locmem(argoff, esp, NULL, arg->mode);
+            arg = inri(s, arg);
+            stor(s, arg, dst);
+        }
         argoff += size(n->expr.args[i]);
     }
     fn = selexpr(s, n->expr.args[0]);
@@ -362,34 +395,6 @@
     return eax;
 }
 
-static void blit(Isel *s, Loc *a, Loc *b, int sz)
-{
-    int i;
-    Loc *sp, *dp; /* pointers to src, dst */
-    Loc *tmp, *src, *dst; /* source memory, dst memory */
-
-    sp = inr(s, a);
-    dp = inr(s, b);
-
-    /* Slightly funny loop condition: We might have trailing bytes
-     * that we can't blit word-wise. */
-    tmp = locreg(ModeL);
-    for (i = 0; i < sz/4; i++) {
-        src = locmem(i, sp, NULL, ModeL);
-        dst = locmem(i, dp, NULL, ModeL);
-        g(s, Imov, src, tmp, NULL);
-        g(s, Imov, tmp, dst, NULL);
-    }
-    /* now, the trailing bytes */
-    tmp = locreg(ModeB);
-    for (; i < sz%4; i++) {
-        src = locmem(i, sp, NULL, ModeB);
-        dst = locmem(i, dp, NULL, ModeB);
-        g(s, Imov, src, tmp, NULL);
-        g(s, Imov, tmp, dst, NULL);
-    }
-}
-
 Loc *selexpr(Isel *s, Node *n)
 {
     Loc *a, *b, *c, *d, *r;
@@ -538,9 +543,9 @@
             r = loclbl(args[0]);
             break;
         case Oblit:
-            b = selexpr(s, args[0]);
-            a = selexpr(s, args[1]);
-            blit(s, a, b, args[2]->expr.args[0]->lit.intval);
+            a = selexpr(s, args[0]);
+            b = selexpr(s, args[1]);
+            blit(s, a, b, 0, 0, args[2]->expr.args[0]->lit.intval);
             r = b;
             break;