git: 9front

Download patch

ref: 1f83b100a345e2573db8173a16235d94ba4fc82c
parent: 0ef486b8fa59bb0aa15d74fbe817c158cf844a41
author: Jacob Moody <moody@posixcafe.org>
date: Sat Apr 6 20:13:41 EDT 2024

9c/9l: do not have the linker rewrite OSUB to negative OADD

POWER does not provided subtract immediate functions and
instead rely on negative addition. It was such that the linker
was the one who would go through and rewrite these to be negative
but it really should be done in the compiler while we still have
the width information.

--- a/sys/src/cmd/9c/cgen.c
+++ b/sys/src/cmd/9c/cgen.c
@@ -191,8 +191,11 @@
 		}
 		goto usereg;
 
-	case OADD:
 	case OSUB:
+		r->vconst = -r->vconst;
+		o = n->op = OADD;
+
+	case OADD:
 		/*
 		 * signed immediate operands
 		 */
@@ -270,8 +273,11 @@
 		}
 		goto useregas;
 
-	case OASADD:
 	case OASSUB:
+		r->vconst = -r->vconst;
+		o = n->op = OASADD;
+
+	case OASADD:
 		if(l->op == OBIT)
 			goto asbitop;
 		if(r->op == OCONST && issim16(r->vconst))
@@ -1118,7 +1124,7 @@
 	pc1 = pc;
 	layout(&nod1, &nod2, c, 0, Z);
 
-	gopcode(OSUB, nodconst(1L), Z, &nod3);
+	gopcode(OADD, nodconst(-1L), Z, &nod3);
 	nod1.op = OREGISTER;
 	gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
 	nod2.op = OREGISTER;
--- a/sys/src/cmd/9c/swt.c
+++ b/sys/src/cmd/9c/swt.c
@@ -22,7 +22,7 @@
 			if(sval(q->val)) {
 				gopcode(OEQ, n, Z, nodconst(q->val));
 			} else {
-				gopcode(OSUB, nodconst(q->val), n, tn);
+				gopcode(OADD, nodconst(-q->val), n, tn);
 				gopcode(OEQ, tn, Z, nodconst(0));
 			}
 			patch(p, q->label);
@@ -38,7 +38,7 @@
 		gopcode(OGT, n, Z, nodconst(r->val));
 		sp = p;
 	} else {
-		gopcode(OSUB, nodconst(r->val), n, tn);
+		gopcode(OADD, nodconst(-r->val), n, tn);
 		gopcode(OGT, tn, Z, nodconst(0));
 		sp = p;
 	}
--- a/sys/src/cmd/9c/txt.c
+++ b/sys/src/cmd/9c/txt.c
@@ -973,6 +973,18 @@
 		}
 		break;
 	}
+	if(f->op == OCONST)
+		switch(a){
+		case AMOVBZ:
+			f->vconst &= 0xFF;
+			break;
+		case AMOVHZ:
+			f->vconst &= 0xFFFF;
+			break;
+		case AMOVWZ:
+			f->vconst &= 0xFFFFFFFFUL;
+			break;
+		}
 	if(a == AGOK)
 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
 	if(a == AMOVD || (a == AMOVW || a == AMOVWZ) && ewidth[ft] == ewidth[tt] || a == AFMOVS || a == AFMOVD)
--- a/sys/src/cmd/9l/obj.c
+++ b/sys/src/cmd/9l/obj.c
@@ -1005,27 +1005,6 @@
 		}
 		goto casedef;
 
-	case ASUBC:
-		if(p->from.type == D_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADDC;
-		}
-		goto casedef;
-
-	case ASUBCCC:
-		if(p->from.type == D_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADDCCC;
-		}
-		goto casedef;
-
-	case ASUB:
-		if(p->from.type == D_CONST) {
-			p->from.offset = -p->from.offset;
-			p->as = AADD;
-		}
-		goto casedef;
-
 	default:
 	casedef:
 		if(skip)
--