shithub: mc

Download patch

ref: 63102e84123635698b1e23aa725f52bfdb39d2f0
parent: f16265cf009101ef36cc0d0fcf32490ebaf13b6e
author: Ori Bernstein <[email protected]>
date: Wed Sep 17 21:08:57 EDT 2014

Correctly save/restore xmm registers.

    Our allocator wasn't acutally saving them, so we clobbered.

--- a/6/asm.h
+++ b/6/asm.h
@@ -3,7 +3,6 @@
 #define Maxdef (2*Maxarg)       /* maximum number of registers an insn can use or def */
 #define Wordsz 4                /* the size of a "natural int" */
 #define Ptrsz 8                 /* the size of a machine word (ie, pointer size) */
-#define Nsaved 13               /* number of registers saved in the ABI */
 
 typedef size_t regid;
 
@@ -131,7 +130,8 @@
 
     /* increased when we spill */
     Loc *stksz;
-    Loc *calleesave[Nsaved];
+    Loc *calleesave[Nreg];
+    size_t nsaved;
 
     /* register allocator state */
 
--- a/6/isel.c
+++ b/6/isel.c
@@ -852,7 +852,6 @@
                 return;
             break;
         case Imov:
-            assert(!isfloatmode(insn->args[1]->mode));
             if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
                 break;
             if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
@@ -924,12 +923,12 @@
     }
 }
 
+/* %rax is for int returns, %xmm0d is for floating returns */
 Reg savedregs[] = {
     Rrcx, Rrdx, Rrbx, Rrsi, Rrdi, Rr8, Rr9, Rr10, Rr11, Rr12, Rr13, Rr14, Rr15,
-    /*
-    Rxmm0d, Rxmm1d, Rxmm2d, Rxmm3d, Rxmm4d, Rxmm5d, Rxmm6d, Rxmm7d,
+    Rxmm1d, Rxmm2d, Rxmm3d, Rxmm4d, Rxmm5d, Rxmm6d, Rxmm7d,
     Rxmm8d, Rxmm9d, Rxmm10d, Rxmm11d, Rxmm12d, Rxmm13d, Rxmm14d, Rxmm15d,
-    */
+    Rnone
 };
 
 static void prologue(Isel *s, size_t sz)
@@ -937,6 +936,7 @@
     Loc *rsp;
     Loc *rbp;
     Loc *stksz;
+    Loc *phys;
     size_t i;
 
     rsp = locphysreg(Rrsp);
@@ -947,10 +947,12 @@
     g(s, Imov, rsp, rbp, NULL);
     g(s, Isub, stksz, rsp, NULL);
     /* save registers */
-    for (i = 0; i < sizeof(savedregs)/sizeof(savedregs[0]); i++) {
-        s->calleesave[i] = locreg(ModeQ);
-        g(s, Imov, locphysreg(savedregs[i]), s->calleesave[i], NULL);
+    for (i = 0; savedregs[i] != Rnone; i++) {
+        phys = locphysreg(savedregs[i]);
+        s->calleesave[i] = locreg(phys->mode);
+        g(s, Imov, phys, s->calleesave[i], NULL);
     }
+    s->nsaved = i;
     s->stksz = stksz; /* need to update if we spill */
 }
 
@@ -970,7 +972,7 @@
             g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
     }
     /* restore registers */
-    for (i = 0; i < Nsaved; i++)
+    for (i = 0; savedregs[i] != Rnone; i++)
         g(s, Imov, s->calleesave[i], locphysreg(savedregs[i]), NULL);
     /* leave function */
     g(s, Imov, rbp, rsp, NULL);
--- a/6/ra.c
+++ b/6/ra.c
@@ -42,22 +42,23 @@
 /* A map of which registers interfere */
 #define Northogonal 32
 Reg regmap[Northogonal][Nmode] = {
-    [0]  = {Rnone, Ral, Rax, Reax, Rrax},
-    [1]  = {Rnone, Rcl, Rcx, Recx, Rrcx},
-    [2]  = {Rnone, Rdl, Rdx, Redx, Rrdx},
-    [3]  = {Rnone, Rbl, Rbx, Rebx, Rrbx},
-    [4]  = {Rnone, Rsil, Rsi, Resi, Rrsi},
-    [5]  = {Rnone, Rdil, Rdi, Redi, Rrdi},
-    [6]  = {Rnone, Rr8b, Rr8w, Rr8d, Rr8},
-    [7]  = {Rnone, Rr9b, Rr9w, Rr9d, Rr9},
-    [8]  = {Rnone, Rr10b, Rr10w, Rr10d, Rr10},
-    [9]  = {Rnone, Rr11b, Rr11w, Rr11d, Rr11},
-    [10]  = {Rnone, Rr12b, Rr12w, Rr12d, Rr12},
-    [11]  = {Rnone, Rr13b, Rr13w, Rr13d, Rr13},
-    [12]  = {Rnone, Rr14b, Rr14w, Rr14d, Rr14},
-    [13]  = {Rnone, Rr15b, Rr15w, Rr15d, Rr15},
-    [14]  = {Rnone, Rnone, Rnone, Rnone, Rnone},
-    [15]  = {Rnone, Rnone, Rnone, Rnone, Rnone},
+        /* None,   ModeB, ModeW, ModeL, ModeQ, ModeF, ModeD */
+    [0]  = {Rnone, Ral,   Rax,   Reax,  Rrax,  Rnone,  Rnone},
+    [1]  = {Rnone, Rcl,   Rcx,   Recx,  Rrcx,  Rnone,  Rnone},
+    [2]  = {Rnone, Rdl,   Rdx,   Redx,  Rrdx,  Rnone,  Rnone},
+    [3]  = {Rnone, Rbl,   Rbx,   Rebx,  Rrbx,  Rnone,  Rnone},
+    [4]  = {Rnone, Rsil,  Rsi,   Resi,  Rrsi,  Rnone,  Rnone},
+    [5]  = {Rnone, Rdil,  Rdi,   Redi,  Rrdi,  Rnone,  Rnone},
+    [6]  = {Rnone, Rr8b,  Rr8w,  Rr8d,  Rr8,   Rnone,  Rnone},
+    [7]  = {Rnone, Rr9b,  Rr9w,  Rr9d,  Rr9,   Rnone,  Rnone},
+    [8]  = {Rnone, Rr10b, Rr10w, Rr10d, Rr10,  Rnone,  Rnone},
+    [9]  = {Rnone, Rr11b, Rr11w, Rr11d, Rr11,  Rnone,  Rnone},
+    [10] = {Rnone, Rr12b, Rr12w, Rr12d, Rr12,  Rnone,  Rnone},
+    [11] = {Rnone, Rr13b, Rr13w, Rr13d, Rr13,  Rnone,  Rnone},
+    [12] = {Rnone, Rr14b, Rr14w, Rr14d, Rr14,  Rnone,  Rnone},
+    [13] = {Rnone, Rr15b, Rr15w, Rr15d, Rr15,  Rnone,  Rnone},
+    [14] = {Rnone, Rnone, Rnone, Rnone, Rnone, Rnone,  Rnone},
+    [15] = {Rnone, Rnone, Rnone, Rnone, Rnone, Rnone,  Rnone},
     [16] = {Rnone, Rnone, Rnone, Rnone, Rnone, Rxmm0f, Rxmm0d},
     [17] = {Rnone, Rnone, Rnone, Rnone, Rnone, Rxmm1f, Rxmm1d},
     [18] = {Rnone, Rnone, Rnone, Rnone, Rnone, Rxmm2f, Rxmm2d},
@@ -383,6 +384,8 @@
         return;
     if (v == Rrbp || v == Rrsp || v == Rrip)
         return;
+    if (rclass(locmap[u]) != rclass(locmap[v]))
+        return;
 
     gbputedge(s, u, v);
     gbputedge(s, v, u);
@@ -1202,7 +1205,7 @@
     s->shouldspill = mkbs();
     s->neverspill = mkbs();
     s->initial = mkbs();
-    for (i = 0; i < Nsaved; i++)
+    for (i = 0; i < s->nsaved; i++)
         bsput(s->shouldspill, s->calleesave[i]->reg.id);
     do {
         setup(s);