git: 9front

Download patch

ref: d37701e87284d9c0258349c359a4dc275ee26a59
parent: 0c3e5940527272770e2f87127bf76b5dbae7a8bd
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jun 1 13:53:20 EDT 2024

9[cl]: correct previous changes

1f83b100a345e2573db8173a16235d94ba4fc82c
Was to adjust the compiler to better match the ISA w.r.t.
subtraction, but was overzelous and rewrote all additions instead of
just those with constants.

8f2658dda5cae63ee65c21b81cdad9f104c807b4
Intended to restrict compiler generated immediate operations to only
those of which can be encodable by the ISA.  However the check for
signed constants was incorrect and resulted in constants that do not
properly encode.

0ef486b8fa59bb0aa15d74fbe817c158cf844a41
Attempted to classify address literals to save on instruction
encoding, but this is actually not possible.  We have to walk the
program first to derive some of the constants (INITDAT depends on
etext) so we can not classify them here.  Instead we should just limit
address literals to 32 bits (with sign extension) as a worst case.  It
would be possible in the future to do a pass over to program later and
find address literals that only need one instruction instead of two
but this works for now.

--- a/sys/src/cmd/9c/cgen.c
+++ b/sys/src/cmd/9c/cgen.c
@@ -1,34 +1,25 @@
 #include "gc.h"
 
-/*
- * POWER only gives us 16 bit immediates and shifted 16 bit immediate with optional sign extension
- */
-
 static int
 issim16(vlong v)
 {
+	/* addi */
 	if((short)v == v)
 		return 1;
-
-	if(v < 0 && (v & 0xFFFFFFFFULL<<32) != 0xFFFFFFFFULL<<32)
-		return 0;
-	else if((v & 0xFFFFFFFFULL<<32) != 0)
-		return 0;
-
-	if((v & 0xFFFF) != 0)
-		return 0;
-	return 1;
+	/* addis */
+	if(v == (long)(v & 0xFFFF0000))
+		return 1;
+	return 0;
 }
 
-
 static int
-isuim16(vlong v)
+isuim16(uvlong v)
 {
+	/* andi */
 	if((ushort)v == v)
 		return 1;
-	if((v & 0xFFFFFFFFULL<<32) != 0)
-		return 0;
-	if((v & 0xFFFF) == 0)
+	/* andis */
+	if(v == (ulong)(v & 0xFFFF0000))
 		return 1;
 	return 0;
 }
@@ -192,8 +183,11 @@
 		goto usereg;
 
 	case OSUB:
-		r->vconst = -r->vconst;
-		o = n->op = OADD;
+		if(r->op == OCONST)
+		if(!typefd[n->type->etype]) {
+			r->vconst = -r->vconst;
+			o = n->op = OADD;
+		}
 
 	case OADD:
 		/*
@@ -274,8 +268,11 @@
 		goto useregas;
 
 	case OASSUB:
-		r->vconst = -r->vconst;
-		o = n->op = OASADD;
+		if(r->op == OCONST)
+		if(!typefd[n->type->etype]) {
+			r->vconst = -r->vconst;
+			o = n->op = OADD;
+		}
 
 	case OASADD:
 		if(l->op == OBIT)
--- a/sys/src/cmd/9l/span.c
+++ b/sys/src/cmd/9l/span.c
@@ -307,7 +307,7 @@
 			}
 			if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
 				instoffset = s->value + a->offset;
-				goto consize;
+				return C_LCON;
 			}
 			if(s->type == SCONST) {
 				instoffset = s->value + a->offset;
@@ -321,9 +321,7 @@
 					return C_SECON;
 			}
 			instoffset = s->value + a->offset + INITDAT;
-			if(dlm)
-				return C_LCON;
-			goto consize;
+			return C_LCON;
 
 		case D_AUTO:
 			instoffset = autosize + a->offset;
--