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);