summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-12-12 17:36:15 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2022-12-12 22:16:33 +0100
commitc0f25aeae3ef5d5f4b6bc5678f8d8ce40597d673 (patch)
tree26b78f6db8a8fd46005ce94835b0135a6df4eef7
parent2ec355df6adc457303fcf2076b559fefd80ee593 (diff)
downloadroux-c0f25aeae3ef5d5f4b6bc5678f8d8ce40597d673.tar.gz
new rsval() helper for signed Refs
The .val field is signed in RSlot.
Add a new dedicated function to
fetch it as a signed int.
-rw-r--r--all.h5
-rw-r--r--amd64/emit.c23
-rw-r--r--arm64/emit.c12
-rw-r--r--parse.c2
-rw-r--r--rv64/emit.c12
5 files changed, 31 insertions, 23 deletions
diff --git a/all.h b/all.h
index 3ddb944..fe2b56b 100644
--- a/all.h
+++ b/all.h
@@ -110,6 +110,11 @@ static inline int rtype(Ref r)
 	return r.type;
 }
 
+static inline int rsval(Ref r)
+{
+	return ((int32_t)r.val << 3) >> 3;
+}
+
 enum CmpI {
 	Cieq,
 	Cine,
diff --git a/amd64/emit.c b/amd64/emit.c
index 9e5996b..9b8bb5d 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -142,20 +142,19 @@ static char *rname[][4] = {
 
 
 static int
-slot(int s, Fn *fn)
+slot(Ref r, Fn *fn)
 {
-	struct { int i:29; } x;
+	int s;
 
-	/* sign extend s using a bitfield */
-	x.i = s;
-	assert(x.i <= fn->slot);
+	s = rsval(r);
+	assert(s <= fn->slot);
 	/* specific to NAlign == 3 */
-	if (x.i < 0)
-		return -4 * x.i;
+	if (s < 0)
+		return -4 * s;
 	else if (fn->vararg)
-		return -176 + -4 * (fn->slot - x.i);
+		return -176 + -4 * (fn->slot - s);
 	else
-		return -4 * (fn->slot - x.i);
+		return -4 * (fn->slot - s);
 }
 
 static void
@@ -286,14 +285,14 @@ Next:
 			fprintf(f, "%%%s", regtoa(ref.val, sz));
 			break;
 		case RSlot:
-			fprintf(f, "%d(%%rbp)", slot(ref.val, fn));
+			fprintf(f, "%d(%%rbp)", slot(ref, fn));
 			break;
 		case RMem:
 		Mem:
 			m = &fn->mem[ref.val];
 			if (rtype(m->base) == RSlot) {
 				off.type = CBits;
-				off.bits.i = slot(m->base.val, fn);
+				off.bits.i = slot(m->base, fn);
 				addcon(&m->offset, &off);
 				m->base = TMP(RBP);
 			}
@@ -338,7 +337,7 @@ Next:
 		case RMem:
 			goto Mem;
 		case RSlot:
-			fprintf(f, "%d(%%rbp)", slot(ref.val, fn));
+			fprintf(f, "%d(%%rbp)", slot(ref, fn));
 			break;
 		case RCon:
 			off = fn->con[ref.val];
diff --git a/arm64/emit.c b/arm64/emit.c
index 4a0316c..5113c66 100644
--- a/arm64/emit.c
+++ b/arm64/emit.c
@@ -138,9 +138,11 @@ rname(int r, int k)
 }
 
 static uint64_t
-slot(int s, E *e)
+slot(Ref r, E *e)
 {
-	s = ((int32_t)s << 3) >> 3;
+	int s;
+
+	s = rsval(r);
 	if (s == -1)
 		return 16 + e->frame;
 	if (s < 0) {
@@ -234,7 +236,7 @@ emitf(char *s, Ins *i, E *e)
 				fprintf(e->f, "[%s]", rname(r.val, Kl));
 				break;
 			case RSlot:
-				fprintf(e->f, "[x29, %"PRIu64"]", slot(r.val, e));
+				fprintf(e->f, "[x29, %"PRIu64"]", slot(r, e));
 				break;
 			}
 			break;
@@ -333,7 +335,7 @@ fixarg(Ref *pr, int sz, E *e)
 
 	r = *pr;
 	if (rtype(r) == RSlot) {
-		s = slot(r.val, e);
+		s = slot(r, e);
 		if (s > sz * 4095u) {
 			i = &(Ins){Oaddr, Kl, TMP(IP0), {r}};
 			emitins(i, e);
@@ -410,7 +412,7 @@ emitins(Ins *i, E *e)
 	case Oaddr:
 		assert(rtype(i->arg[0]) == RSlot);
 		rn = rname(i->to.val, Kl);
-		s = slot(i->arg[0].val, e);
+		s = slot(i->arg[0], e);
 		if (s <= 4095)
 			fprintf(e->f, "\tadd\t%s, x29, #%"PRIu64"\n", rn, s);
 		else if (s <= 65535)
diff --git a/parse.c b/parse.c
index 849c81d..0836b9a 100644
--- a/parse.c
+++ b/parse.c
@@ -1211,7 +1211,7 @@ printref(Ref r, Fn *fn, FILE *f)
 		printcon(&fn->con[r.val], f);
 		break;
 	case RSlot:
-		fprintf(f, "S%d", (r.val&(1<<28)) ? r.val-(1<<29) : r.val);
+		fprintf(f, "S%d", rsval(r));
 		break;
 	case RCall:
 		fprintf(f, "%04x", r.val);
diff --git a/rv64/emit.c b/rv64/emit.c
index f9e58da..f9df146 100644
--- a/rv64/emit.c
+++ b/rv64/emit.c
@@ -116,9 +116,11 @@ static char *rname[] = {
 };
 
 static int64_t
-slot(int s, Fn *fn)
+slot(Ref r, Fn *fn)
 {
-	s = ((int32_t)s << 3) >> 3;
+	int s;
+
+	s = rsval(r);
 	assert(s <= fn->slot);
 	if (s < 0)
 		return 8 * -s;
@@ -214,7 +216,7 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
 				}
 				break;
 			case RSlot:
-				offset = slot(r.val, fn);
+				offset = slot(r, fn);
 				assert(offset >= -2048 && offset <= 2047);
 				fprintf(f, "%d(fp)", (int)offset);
 				break;
@@ -286,7 +288,7 @@ fixmem(Ref *pr, Fn *fn, FILE *f)
 		}
 	}
 	if (rtype(r) == RSlot) {
-		s = slot(r.val, fn);
+		s = slot(r, fn);
 		if (s < -2048 || s > 2047) {
 			fprintf(f, "\tli t6, %"PRId64"\n", s);
 			fprintf(f, "\tadd t6, fp, t6\n");
@@ -369,7 +371,7 @@ emitins(Ins *i, Fn *fn, FILE *f)
 	case Oaddr:
 		assert(rtype(i->arg[0]) == RSlot);
 		rn = rname[i->to.val];
-		s = slot(i->arg[0].val, fn);
+		s = slot(i->arg[0], fn);
 		if (-s < 2048) {
 			fprintf(f, "\tadd %s, fp, %"PRId64"\n", rn, s);
 		} else {