6c, 8c: fix "DI botch" evacuating DI/SI/CX registers to ".save" variables
This commit is contained in:
parent
8547defe70
commit
19dc7c2097
2 changed files with 146 additions and 141 deletions
|
@ -1396,7 +1396,7 @@ sugen(Node *n, Node *nn, long w)
|
||||||
Prog *p1;
|
Prog *p1;
|
||||||
Node nod0, nod1, nod2, nod3, nod4, *l, *r;
|
Node nod0, nod1, nod2, nod3, nod4, *l, *r;
|
||||||
Type *t;
|
Type *t;
|
||||||
int c, mt, mo;
|
int v, c, mt, mo;
|
||||||
vlong o0, o1;
|
vlong o0, o1;
|
||||||
|
|
||||||
if(n == Z || n->type == T)
|
if(n == Z || n->type == T)
|
||||||
|
@ -1615,8 +1615,8 @@ copy:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = cursafe;
|
||||||
if(w <= 32) {
|
if(w <= 32) {
|
||||||
c = cursafe;
|
|
||||||
if(n->left != Z && n->left->complex >= FNX
|
if(n->left != Z && n->left->complex >= FNX
|
||||||
&& n->right != Z && n->right->complex >= FNX) {
|
&& n->right != Z && n->right->complex >= FNX) {
|
||||||
regsalloc(&nod1, n->right);
|
regsalloc(&nod1, n->right);
|
||||||
|
@ -1696,77 +1696,84 @@ copy:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* botch, need to save in .safe */
|
t = n->type;
|
||||||
c = 0;
|
if(t != types[TIND]){
|
||||||
if(n->complex > nn->complex) {
|
|
||||||
t = n->type;
|
|
||||||
n->type = types[TIND];
|
n->type = types[TIND];
|
||||||
nodreg(&nod1, n, D_SI);
|
sugen(n, nn, w);
|
||||||
if(reg[D_SI]) {
|
|
||||||
gins(APUSHQ, &nod1, Z);
|
|
||||||
c |= 1;
|
|
||||||
reg[D_SI]++;
|
|
||||||
}
|
|
||||||
lcgen(n, &nod1);
|
|
||||||
n->type = t;
|
n->type = t;
|
||||||
|
return;
|
||||||
t = nn->type;
|
}
|
||||||
|
t = nn->type;
|
||||||
|
if(t != types[TIND]){
|
||||||
nn->type = types[TIND];
|
nn->type = types[TIND];
|
||||||
nodreg(&nod2, nn, D_DI);
|
sugen(n, nn, w);
|
||||||
if(reg[D_DI]) {
|
|
||||||
warn(Z, "DI botch");
|
|
||||||
gins(APUSHQ, &nod2, Z);
|
|
||||||
c |= 2;
|
|
||||||
reg[D_DI]++;
|
|
||||||
}
|
|
||||||
lcgen(nn, &nod2);
|
|
||||||
nn->type = t;
|
nn->type = t;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nodreg(&nod1, n, D_SI)) {
|
||||||
|
regsalloc(&nod4, &nod1);
|
||||||
|
gmove(&nod1, &nod4);
|
||||||
|
v = reg[D_SI];
|
||||||
|
reg[D_SI] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_SI] = v;
|
||||||
|
gmove(&nod4, &nod1);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nodreg(&nod2, nn, D_DI)) {
|
||||||
|
regsalloc(&nod4, &nod2);
|
||||||
|
gmove(&nod2, &nod4);
|
||||||
|
v = reg[D_DI];
|
||||||
|
reg[D_DI] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_DI] = v;
|
||||||
|
gmove(&nod4, &nod2);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nodreg(&nod3, Z, D_CX)) {
|
||||||
|
regsalloc(&nod4, &nod3);
|
||||||
|
gmove(&nod3, &nod4);
|
||||||
|
v = reg[D_CX];
|
||||||
|
reg[D_CX] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_CX] = v;
|
||||||
|
gmove(&nod4, &nod3);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n->complex > nn->complex){
|
||||||
|
reg[nod1.reg]++;
|
||||||
|
lcgen(n, &nod1);
|
||||||
|
|
||||||
|
reg[nod2.reg]++;
|
||||||
|
lcgen(nn, &nod2);
|
||||||
} else {
|
} else {
|
||||||
t = nn->type;
|
reg[nod2.reg]++;
|
||||||
nn->type = types[TIND];
|
|
||||||
nodreg(&nod2, nn, D_DI);
|
|
||||||
if(reg[D_DI]) {
|
|
||||||
warn(Z, "DI botch");
|
|
||||||
gins(APUSHQ, &nod2, Z);
|
|
||||||
c |= 2;
|
|
||||||
reg[D_DI]++;
|
|
||||||
}
|
|
||||||
lcgen(nn, &nod2);
|
lcgen(nn, &nod2);
|
||||||
nn->type = t;
|
|
||||||
|
|
||||||
t = n->type;
|
reg[nod1.reg]++;
|
||||||
n->type = types[TIND];
|
|
||||||
nodreg(&nod1, n, D_SI);
|
|
||||||
if(reg[D_SI]) {
|
|
||||||
gins(APUSHQ, &nod1, Z);
|
|
||||||
c |= 1;
|
|
||||||
reg[D_SI]++;
|
|
||||||
}
|
|
||||||
lcgen(n, &nod1);
|
lcgen(n, &nod1);
|
||||||
n->type = t;
|
|
||||||
}
|
}
|
||||||
nodreg(&nod3, n, D_CX);
|
reg[nod3.reg]++;
|
||||||
if(reg[D_CX]) {
|
|
||||||
gins(APUSHQ, &nod3, Z);
|
gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
|
||||||
c |= 4;
|
|
||||||
reg[D_CX]++;
|
|
||||||
}
|
|
||||||
gins(AMOVL, nodconst(w/SZ_INT), &nod3);
|
|
||||||
gins(ACLD, Z, Z);
|
gins(ACLD, Z, Z);
|
||||||
gins(AREP, Z, Z);
|
gins(AREP, Z, Z);
|
||||||
gins(AMOVSL, Z, Z);
|
gins(AMOVSL, Z, Z);
|
||||||
if(c & 4) {
|
if(w & (SZ_LONG-1)) {
|
||||||
gins(APOPQ, Z, &nod3);
|
/* odd length of packed structure */
|
||||||
reg[D_CX]--;
|
gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
|
||||||
}
|
gins(AREP, Z, Z);
|
||||||
if(c & 2) {
|
gins(AMOVSB, Z, Z);
|
||||||
gins(APOPQ, Z, &nod2);
|
|
||||||
reg[nod2.reg]--;
|
|
||||||
}
|
|
||||||
if(c & 1) {
|
|
||||||
gins(APOPQ, Z, &nod1);
|
|
||||||
reg[nod1.reg]--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg[nod3.reg]--;
|
||||||
|
reg[nod2.reg]--;
|
||||||
|
reg[nod1.reg]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1687,11 +1687,10 @@ copy:
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
v = w == 8;
|
v = w == 8;
|
||||||
|
c = cursafe;
|
||||||
if(v) {
|
if(v) {
|
||||||
c = cursafe;
|
|
||||||
if(n->left != Z && n->left->complex >= FNX
|
if(n->left != Z && n->left->complex >= FNX
|
||||||
&& n->right != Z && n->right->complex >= FNX) {
|
&& n->right != Z && n->right->complex >= FNX) {
|
||||||
// warn(n, "toughie");
|
|
||||||
regsalloc(&nod1, n->right);
|
regsalloc(&nod1, n->right);
|
||||||
cgen(n->right, &nod1);
|
cgen(n->right, &nod1);
|
||||||
nod2 = *n;
|
nod2 = *n;
|
||||||
|
@ -1708,14 +1707,10 @@ copy:
|
||||||
n = n->left;
|
n = n->left;
|
||||||
x = 1;
|
x = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* botch, need to save in .safe */
|
if(n->complex > nn->complex){
|
||||||
c = 0;
|
t = n->type;
|
||||||
if(n->complex > nn->complex) {
|
n->type = types[TLONG];
|
||||||
t = n->type;
|
|
||||||
n->type = types[TLONG];
|
|
||||||
if(v) {
|
|
||||||
regalloc(&nod0, n, Z);
|
regalloc(&nod0, n, Z);
|
||||||
if(!vaddr(n, 0)) {
|
if(!vaddr(n, 0)) {
|
||||||
reglcgen(&nod1, n, Z);
|
reglcgen(&nod1, n, Z);
|
||||||
|
@ -1724,21 +1719,9 @@ copy:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
n->type = t;
|
n->type = t;
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodreg(&nod1, n, D_SI);
|
|
||||||
if(reg[D_SI]) {
|
|
||||||
gins(APUSHL, &nod1, Z);
|
|
||||||
c |= 1;
|
|
||||||
reg[D_SI]++;
|
|
||||||
}
|
|
||||||
lcgen(n, &nod1);
|
|
||||||
n->type = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = nn->type;
|
t = nn->type;
|
||||||
nn->type = types[TLONG];
|
nn->type = types[TLONG];
|
||||||
if(v) {
|
|
||||||
if(!vaddr(nn, 0)) {
|
if(!vaddr(nn, 0)) {
|
||||||
reglcgen(&nod2, nn, Z);
|
reglcgen(&nod2, nn, Z);
|
||||||
nn->type = t;
|
nn->type = t;
|
||||||
|
@ -1746,21 +1729,9 @@ copy:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nn->type = t;
|
nn->type = t;
|
||||||
}
|
} else {
|
||||||
else {
|
t = nn->type;
|
||||||
nodreg(&nod2, nn, D_DI);
|
nn->type = types[TLONG];
|
||||||
if(reg[D_DI]) {
|
|
||||||
gins(APUSHL, &nod2, Z);
|
|
||||||
c |= 2;
|
|
||||||
reg[D_DI]++;
|
|
||||||
}
|
|
||||||
lcgen(nn, &nod2);
|
|
||||||
nn->type = t;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t = nn->type;
|
|
||||||
nn->type = types[TLONG];
|
|
||||||
if(v) {
|
|
||||||
regalloc(&nod0, nn, Z);
|
regalloc(&nod0, nn, Z);
|
||||||
if(!vaddr(nn, 0)) {
|
if(!vaddr(nn, 0)) {
|
||||||
reglcgen(&nod2, nn, Z);
|
reglcgen(&nod2, nn, Z);
|
||||||
|
@ -1769,21 +1740,9 @@ copy:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nn->type = t;
|
nn->type = t;
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodreg(&nod2, nn, D_DI);
|
|
||||||
if(reg[D_DI]) {
|
|
||||||
gins(APUSHL, &nod2, Z);
|
|
||||||
c |= 2;
|
|
||||||
reg[D_DI]++;
|
|
||||||
}
|
|
||||||
lcgen(nn, &nod2);
|
|
||||||
nn->type = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = n->type;
|
t = n->type;
|
||||||
n->type = types[TLONG];
|
n->type = types[TLONG];
|
||||||
if(v) {
|
|
||||||
if(!vaddr(n, 0)) {
|
if(!vaddr(n, 0)) {
|
||||||
reglcgen(&nod1, n, Z);
|
reglcgen(&nod1, n, Z);
|
||||||
n->type = t;
|
n->type = t;
|
||||||
|
@ -1792,18 +1751,6 @@ copy:
|
||||||
else
|
else
|
||||||
n->type = t;
|
n->type = t;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
nodreg(&nod1, n, D_SI);
|
|
||||||
if(reg[D_SI]) {
|
|
||||||
gins(APUSHL, &nod1, Z);
|
|
||||||
c |= 1;
|
|
||||||
reg[D_SI]++;
|
|
||||||
}
|
|
||||||
lcgen(n, &nod1);
|
|
||||||
n->type = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(v) {
|
|
||||||
gins(AMOVL, n, &nod0);
|
gins(AMOVL, n, &nod0);
|
||||||
if(x)
|
if(x)
|
||||||
gins(ANOTL, Z, &nod0);
|
gins(ANOTL, Z, &nod0);
|
||||||
|
@ -1823,12 +1770,71 @@ copy:
|
||||||
regfree(&nod0);
|
regfree(&nod0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nodreg(&nod3, n, D_CX);
|
|
||||||
if(reg[D_CX]) {
|
t = n->type;
|
||||||
gins(APUSHL, &nod3, Z);
|
if(t != types[TIND]){
|
||||||
c |= 4;
|
n->type = types[TIND];
|
||||||
reg[D_CX]++;
|
sugen(n, nn, w);
|
||||||
|
n->type = t;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
t = nn->type;
|
||||||
|
if(t != types[TIND]){
|
||||||
|
nn->type = types[TIND];
|
||||||
|
sugen(n, nn, w);
|
||||||
|
nn->type = t;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nodreg(&nod1, n, D_SI)) {
|
||||||
|
regsalloc(&nod4, &nod1);
|
||||||
|
gmove(&nod1, &nod4);
|
||||||
|
v = reg[D_SI];
|
||||||
|
reg[D_SI] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_SI] = v;
|
||||||
|
gmove(&nod4, &nod1);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nodreg(&nod2, nn, D_DI)) {
|
||||||
|
regsalloc(&nod4, &nod2);
|
||||||
|
gmove(&nod2, &nod4);
|
||||||
|
v = reg[D_DI];
|
||||||
|
reg[D_DI] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_DI] = v;
|
||||||
|
gmove(&nod4, &nod2);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(nodreg(&nod3, Z, D_CX)) {
|
||||||
|
regsalloc(&nod4, &nod3);
|
||||||
|
gmove(&nod3, &nod4);
|
||||||
|
v = reg[D_CX];
|
||||||
|
reg[D_CX] = 0;
|
||||||
|
sugen(n, nn, w);
|
||||||
|
reg[D_CX] = v;
|
||||||
|
gmove(&nod4, &nod3);
|
||||||
|
cursafe = c;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n->complex > nn->complex){
|
||||||
|
reg[nod1.reg]++;
|
||||||
|
lcgen(n, &nod1);
|
||||||
|
|
||||||
|
reg[nod2.reg]++;
|
||||||
|
lcgen(nn, &nod2);
|
||||||
|
} else {
|
||||||
|
reg[nod2.reg]++;
|
||||||
|
lcgen(nn, &nod2);
|
||||||
|
|
||||||
|
reg[nod1.reg]++;
|
||||||
|
lcgen(n, &nod1);
|
||||||
|
}
|
||||||
|
reg[nod3.reg]++;
|
||||||
|
|
||||||
gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
|
gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
|
||||||
gins(ACLD, Z, Z);
|
gins(ACLD, Z, Z);
|
||||||
gins(AREP, Z, Z);
|
gins(AREP, Z, Z);
|
||||||
|
@ -1839,16 +1845,8 @@ copy:
|
||||||
gins(AREP, Z, Z);
|
gins(AREP, Z, Z);
|
||||||
gins(AMOVSB, Z, Z);
|
gins(AMOVSB, Z, Z);
|
||||||
}
|
}
|
||||||
if(c & 4) {
|
|
||||||
gins(APOPL, Z, &nod3);
|
reg[nod3.reg]--;
|
||||||
reg[D_CX]--;
|
reg[nod2.reg]--;
|
||||||
}
|
reg[nod1.reg]--;
|
||||||
if(c & 2) {
|
|
||||||
gins(APOPL, Z, &nod2);
|
|
||||||
reg[nod2.reg]--;
|
|
||||||
}
|
|
||||||
if(c & 1) {
|
|
||||||
gins(APOPL, Z, &nod1);
|
|
||||||
reg[nod1.reg]--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue