ref: f44ae2dc9f46a7055bfcc3400c563b1ae8c4d901
parent: b1f933e438397a26a2ea22ce957cc9c05bc9a328
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Jun 1 14:51:47 EDT 2013
8c: apply charles forsyth's 8c-cgen64-mul-savereg patch (from sources) 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.
--- a/sys/src/cmd/8c/cgen64.c
+++ b/sys/src/cmd/8c/cgen64.c
@@ -127,6 +127,7 @@
zapreg(Node *n)
{ if(n->reg != D_NONE) {+ //prtree(n, "zapreg");
regfree(n);
n->reg = D_NONE;
}
@@ -2224,6 +2225,7 @@
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 @@
}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 @@
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 @@
}
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 @@
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,6 +2295,7 @@
gmove(&nod2, t->right);
gmove(&nod4, &nod2);
}
+
if(r->op == OREGPAIR)
freepair(r);
if(!m)
@@ -2288,6 +2302,7 @@
storepair(t, l, 0);
if(l == &nod5)
regfree(l);
+
if(!dr) {if(nn != Z)
storepair(t, nn, 1);
--
⑨