]> git.lizzy.rs Git - plan9front.git/commitdiff
8c: apply charles forsyth's 8c-cgen64-mul-savereg patch (from sources)
authorcinap_lenrek <cinap_lenrek@gmx.de>
Sat, 1 Jun 2013 16:51:47 +0000 (18:51 +0200)
committercinap_lenrek <cinap_lenrek@gmx.de>
Sat, 1 Jun 2013 16:51:47 +0000 (18:51 +0200)
If 64-bit multiply has to save both AX and DX, it could load the wrong value
into DX; also, biggen shouldn't allocate either AX or DX as temporaries
when using the template for MUL.

sys/src/cmd/8c/cgen64.c

index 6c4be5aa9f38f3ecc5efe8ae5599ca1322df33a8..3077dad04f6fe4b7e8925b072066a1cbefd92325 100644 (file)
@@ -127,6 +127,7 @@ static void
 zapreg(Node *n)
 {
        if(n->reg != D_NONE) {
+               //prtree(n, "zapreg");
                regfree(n);
                n->reg = D_NONE;
        }
@@ -2224,6 +2225,7 @@ twoop:
                        t = nn;
                else
                        t = regpair(Z, n);
+               //print("dr=%d ", dr); prtree(t, "t");
                c = Z;
                d = Z;
                if(!nodreg(&nod1, t->left, D_AX)) {
@@ -2240,10 +2242,12 @@ twoop:
                        }else if(reg[D_DX] == 0)
                                fatal(Z, "vlong mul DX botch");
                }
+               //prtree(t, "t1"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
                if(m)
                        sugen(l, t, 8);
                else
                        loadpair(l, t);
+               //prtree(t, "t2"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
                if(t->left->reg != D_AX) {
                        c = &nod3;
                        regsalloc(c, t->left);
@@ -2251,11 +2255,16 @@ twoop:
                        gmove(t->left, &nod1);
                        zapreg(t->left);
                }
+               //print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
                if(t->right->reg != D_DX) {
                        d = &nod4;
                        regsalloc(d, t->right);
                        gmove(&nod2, d);
-                       gmove(t->right, &nod2);
+                       if(t->right->reg == D_AX && c != nil){
+                               /* need previous value of AX in DX */
+                               gmove(c, &nod2);
+                       }else
+                               gmove(t->right, &nod2);
                        zapreg(t->right);
                }
                if(c != Z || d != Z) {
@@ -2265,6 +2274,8 @@ twoop:
                }
                else
                        s = t;
+               reg[D_AX]++;    /* don't allow biggen to allocate AX or DX (smashed by MUL) as temp */
+               reg[D_DX]++;
                if(r->op == OCONST) {
                        if(hi64v(r) == 0)
                                biggen(s, r, Z, 0, mulc32, nil);
@@ -2274,6 +2285,8 @@ twoop:
                else
                        biggen(s, r, Z, 0, mull, nil);
                instpair(t, Z);
+               reg[D_AX]--;
+               reg[D_DX]--;
                if(c != Z) {
                        gmove(&nod1, t->left);
                        gmove(&nod3, &nod1);
@@ -2282,12 +2295,14 @@ twoop:
                        gmove(&nod2, t->right);
                        gmove(&nod4, &nod2);
                }
+
                if(r->op == OREGPAIR)
                        freepair(r);
                if(!m)
                        storepair(t, l, 0);
                if(l == &nod5)
                        regfree(l);
+
                if(!dr) {
                        if(nn != Z)
                                storepair(t, nn, 1);