]> git.lizzy.rs Git - plan9front.git/commitdiff
6c, 8c: fix "DI botch" evacuating DI/SI/CX registers to ".save" variables
authorcinap_lenrek <cinap_lenrek@felloff.net>
Mon, 2 Jan 2017 04:49:18 +0000 (05:49 +0100)
committercinap_lenrek <cinap_lenrek@felloff.net>
Mon, 2 Jan 2017 04:49:18 +0000 (05:49 +0100)
sys/src/cmd/6c/cgen.c
sys/src/cmd/8c/cgen.c

index d43d1d366865f3ff95d4750bc508d88726143557..8bac8370d753f184cba118de5548600b0a8209ab 100644 (file)
@@ -1396,7 +1396,7 @@ sugen(Node *n, Node *nn, long w)
        Prog *p1;
        Node nod0, nod1, nod2, nod3, nod4, *l, *r;
        Type *t;
-       int c, mt, mo;
+       int v, c, mt, mo;
        vlong o0, o1;
 
        if(n == Z || n->type == T)
@@ -1615,8 +1615,8 @@ copy:
                return;
        }
 
+       c = cursafe;
        if(w <= 32) {
-               c = cursafe;
                if(n->left != Z && n->left->complex >= FNX
                && n->right != Z && n->right->complex >= FNX) {
                        regsalloc(&nod1, n->right);
@@ -1696,77 +1696,84 @@ copy:
                return;
        }
 
-       /* botch, need to save in .safe */
-       c = 0;
-       if(n->complex > nn->complex) {
-               t = n->type;
+       t = n->type;
+       if(t != types[TIND]){
                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);
+               sugen(n, nn, w);
                n->type = t;
-
-               t = nn->type;
+               return;
+       }
+       t = nn->type;
+       if(t != types[TIND]){
                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);
+               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 {
-               t = nn->type;
-               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]++;
-               }
+               reg[nod2.reg]++;
                lcgen(nn, &nod2);
-               nn->type = t;
 
-               t = n->type;
-               n->type = types[TIND];
-               nodreg(&nod1, n, D_SI);
-               if(reg[D_SI]) {
-                       gins(APUSHQ, &nod1, Z);
-                       c |= 1;
-                       reg[D_SI]++;
-               }
+               reg[nod1.reg]++;
                lcgen(n, &nod1);
-               n->type = t;
-       }
-       nodreg(&nod3, n, D_CX);
-       if(reg[D_CX]) {
-               gins(APUSHQ, &nod3, Z);
-               c |= 4;
-               reg[D_CX]++;
        }
-       gins(AMOVL, nodconst(w/SZ_INT), &nod3);
+       reg[nod3.reg]++;
+
+       gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
        gins(ACLD, Z, Z);
        gins(AREP, Z, Z);
        gins(AMOVSL, Z, Z);
-       if(c & 4) {
-               gins(APOPQ, Z, &nod3);
-               reg[D_CX]--;
-       }
-       if(c & 2) {
-               gins(APOPQ, Z, &nod2);
-               reg[nod2.reg]--;
-       }
-       if(c & 1) {
-               gins(APOPQ, Z, &nod1);
-               reg[nod1.reg]--;
+       if(w & (SZ_LONG-1)) {
+               /* odd length of packed structure */
+               gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
+               gins(AREP, Z, Z);
+               gins(AMOVSB, Z, Z);
        }
+
+       reg[nod3.reg]--;
+       reg[nod2.reg]--;
+       reg[nod1.reg]--;
 }
 
 /*
index 1900f3cbcf058f5e367abe0b75a9d12c588c291f..3d929ae7cf41be87429d69781508d088da4ad5e4 100644 (file)
@@ -1687,11 +1687,10 @@ copy:
 
        x = 0;
        v = w == 8;
+       c = cursafe;
        if(v) {
-               c = cursafe;
                if(n->left != Z && n->left->complex >= FNX
                && n->right != Z && n->right->complex >= FNX) {
-//                     warn(n, "toughie");
                        regsalloc(&nod1, n->right);
                        cgen(n->right, &nod1);
                        nod2 = *n;
@@ -1708,14 +1707,10 @@ copy:
                        n = n->left;
                        x = 1;
                }
-       }
 
-       /* botch, need to save in .safe */
-       c = 0;
-       if(n->complex > nn->complex) {
-               t = n->type;
-               n->type = types[TLONG];
-               if(v) {
+               if(n->complex > nn->complex){
+                       t = n->type;
+                       n->type = types[TLONG];
                        regalloc(&nod0, n, Z);
                        if(!vaddr(n, 0)) {
                                reglcgen(&nod1, n, Z);
@@ -1724,21 +1719,9 @@ copy:
                        }
                        else
                                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;
-               nn->type = types[TLONG];
-               if(v) {
+                       t = nn->type;
+                       nn->type = types[TLONG];
                        if(!vaddr(nn, 0)) {
                                reglcgen(&nod2, nn, Z);
                                nn->type = t;
@@ -1746,21 +1729,9 @@ copy:
                        }
                        else
                                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;
-               }
-       } else {
-               t = nn->type;
-               nn->type = types[TLONG];
-               if(v) {
+               } else {
+                       t = nn->type;
+                       nn->type = types[TLONG];
                        regalloc(&nod0, nn, Z);
                        if(!vaddr(nn, 0)) {
                                reglcgen(&nod2, nn, Z);
@@ -1769,21 +1740,9 @@ copy:
                        }
                        else
                                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;
-               n->type = types[TLONG];
-               if(v) {
+                       t = n->type;
+                       n->type = types[TLONG];
                        if(!vaddr(n, 0)) {
                                reglcgen(&nod1, n, Z);
                                n->type = t;
@@ -1792,18 +1751,6 @@ copy:
                        else
                                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);
                if(x)
                        gins(ANOTL, Z, &nod0);
@@ -1823,12 +1770,71 @@ copy:
                regfree(&nod0);
                return;
        }
-       nodreg(&nod3, n, D_CX);
-       if(reg[D_CX]) {
-               gins(APUSHL, &nod3, Z);
-               c |= 4;
-               reg[D_CX]++;
+
+       t = n->type;
+       if(t != types[TIND]){
+               n->type = types[TIND];
+               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(ACLD, Z, Z);
        gins(AREP, Z, Z);
@@ -1839,16 +1845,8 @@ copy:
                gins(AREP, Z, Z);
                gins(AMOVSB, Z, Z);
        }
-       if(c & 4) {
-               gins(APOPL, Z, &nod3);
-               reg[D_CX]--;
-       }
-       if(c & 2) {
-               gins(APOPL, Z, &nod2);
-               reg[nod2.reg]--;
-       }
-       if(c & 1) {
-               gins(APOPL, Z, &nod1);
-               reg[nod1.reg]--;
-       }
+
+       reg[nod3.reg]--;
+       reg[nod2.reg]--;
+       reg[nod1.reg]--;
 }