code: plan9front

Download patch

ref: 4e4bd869e97fecee8921ecd8d135de061e73f372
parent: 01e7d784df2e35dc030b8435654d1454687371e5
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jun 1 13:53:20 EDT 2024

9[cl]: correct previous changes

37e65b331bdf98f409be1bd2fbb55aec158c7877
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.

539013042677ddd193cf6c37a53e4f64ed33649a
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.

0c6fd079ce51181e32e6625fdc85d07567991f37
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;