shithub: mc

Download patch

ref: 8f5b7baf54f08113a4b46aeafa795163e70f5ac5
parent: 4a494e3b48d42de7b8316edd82a1fb4a7400ca3b
author: Ori Bernstein <[email protected]>
date: Thu Sep 11 17:32:39 EDT 2014

Don't generate obscene movs for big blits.

    Then again, big blits are a bad thing anyways. Should we warn?

--- a/6/isel.c
+++ b/6/isel.c
@@ -381,7 +381,7 @@
         [1] = ModeB
     };
     size_t i, modesz;
-    Loc *sp, *dp; /* pointers to src, dst */
+    Loc *sp, *dp, *len; /* pointers to src, dst */
     Loc *tmp, *src, *dst; /* source memory, dst memory */
 
     assert(modes[align] != ModeNone);   /* make sure we have a valid alignment */
@@ -389,16 +389,37 @@
     dp = inr(s, to);
 
     i = 0;
-    for (modesz = align; modes[modesz] != ModeNone; modesz /= 2) {
-        tmp = locreg(modes[modesz]);
-        while (i + modesz <= sz) {
-            src = locmem(i + srcoff, sp, NULL, modes[modesz]);
-            dst = locmem(i + dstoff, dp, NULL, modes[modesz]);
-            g(s, Imov, src, tmp, NULL);
-            g(s, Imov, tmp, dst, NULL);
-            i += modesz;
+    if (sz <= 64*align) { /* arbitrary threshold; should be tuned */
+        for (modesz = align; modes[modesz] != ModeNone; modesz /= 2) {
+            tmp = locreg(modes[modesz]);
+            while (i + modesz <= sz) {
+                src = locmem(i + srcoff, sp, NULL, modes[modesz]);
+                dst = locmem(i + dstoff, dp, NULL, modes[modesz]);
+                g(s, Imov, src, tmp, NULL);
+                g(s, Imov, tmp, dst, NULL);
+                i += modesz;
+            }
         }
+    } else {
+        len = loclit(sz, ModeQ);
+        sp = newr(s, from);
+        dp = newr(s, to);
+ 
+        /* length to blit */
+        g(s, Imov, len, locphysreg(Rrcx), NULL);
+        /* source address with offset */
+        if (srcoff)
+            g(s, Ilea, locmem(srcoff, sp, NULL, ModeQ), locphysreg(Rrsi), NULL);
+        else
+            g(s, Imov, sp, locphysreg(Rrsi), NULL);
+        /* dest address with offset */
+        if (dstoff)
+            g(s, Ilea, locmem(dstoff, dp, NULL, ModeQ), locphysreg(Rrdi), NULL);
+        else
+            g(s, Imov, dp, locphysreg(Rrdi), NULL);
+        g(s, Irepmovsb, NULL);
     }
+        
 }
 
 static int isfunc(Isel *s, Node *n)