shithub: riscv

Download patch

ref: 37e65b331bdf98f409be1bd2fbb55aec158c7877
parent: 0c6fd079ce51181e32e6625fdc85d07567991f37
author: Jacob Moody <[email protected]>
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)