git: 9front

Download patch

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