summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c15
-rw-r--r--lisc/isel.c20
-rw-r--r--lisc/lisc.h10
-rw-r--r--lisc/live.c14
-rw-r--r--lisc/parse.c7
-rw-r--r--lisc/rega.c2
6 files changed, 48 insertions, 20 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index b8365c2..c4b6356 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -40,7 +40,7 @@ emitf(Fn *fn, FILE *f, char *fmt, ...)
 	int i, ty, off;
 	Ref ref;
 	Con *con;
-	struct { int i:AShift; } x;
+	struct { int i:14; } x;
 
 	va_start(ap, fmt);
 	ty = SWord;
@@ -82,9 +82,9 @@ Next:
 			assert(isreg(ref));
 			fprintf(f, "%%%s", rsub[ref.val][ty]);
 			break;
-		case RASlot:
+		case RSlot:
 		Slot:
-			x.i = ref.val & AMask;
+			x.i = ref.val;
 			assert(NAlign == 3);
 			if (x.i < 0)
 				off = -4 * x.i;
@@ -116,9 +116,12 @@ Next:
 	case 'M':
 		ref = va_arg(ap, Ref);
 		switch (rtype(ref)) {
-		default:     diag("emit: invalid memory reference");
-		case RASlot: goto Slot;
-		case RCon:   goto Con;
+		default:
+			diag("emit: invalid memory reference");
+		case RSlot:
+			goto Slot;
+		case RCon:
+			goto Con;
 		case RTmp:
 			assert(isreg(ref));
 			fprintf(f, "(%%%s)", rsub[ref.val][SLong]);
diff --git a/lisc/isel.c b/lisc/isel.c
index 5bbbab1..bf6fa25 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -19,6 +19,7 @@ typedef struct AClass AClass;
 struct ANum {
 	char n, l, r;
 	Ins *i;
+	Ref mem;
 };
 
 static void amatch(Addr *, Ref, ANum *, Fn *, int);
@@ -75,8 +76,6 @@ rslot(Ref r, Fn *fn)
 static void
 sel(Ins i, ANum *an, Fn *fn)
 {
-	static char logS[] = {[2] = 1, [4] = 2, [8] = 3};
-	Ins *i0;
 	Ref r0, r1;
 	int n, x, s, w;
 	int64_t val;
@@ -133,10 +132,20 @@ sel(Ins i, ANum *an, Fn *fn)
 		}
 		goto Emit;
 	case_OLoad:
-		if (cpy[0].s != -1) {
-			i.arg[0] = SLOT(cpy[0].s);
-			cpy[0].s = -1;
+		r0 = i.arg[0];
+		if (rtype(r0) == RTmp) {
+			r1 = an[r0.val].mem;
+			if (req(r1, R)) {
+				amatch(&a, r0, an, fn, 1);
+				vgrow(&fn->mem, ++fn->nmem);
+				fn->mem[fn->nmem-1] = a;
+				i.arg[0] = MEM(fn->nmem-1);
+				an[r0.val].mem = i.arg[0];
+			} else
+				i.arg[0] = r1;
 		}
+		cpy[0].s = -1;
+		emiti(i);
 		break;
 	case OXPush:
 	case OCall:
@@ -152,6 +161,7 @@ Emit:
 		emiti(i);
 #if 0
 		for (n=0; n<2; n++) {
+			Ins *i0;
 			/* fuse memory loads into arithmetic
 			 * operations when the sizes match
 			 */
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 166c18c..6a8d687 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -80,7 +80,7 @@ struct Ref {
 enum Alt {
 	AType,
 	ACall,
-	ASlot,
+	AMem,
 
 	AShift = 12,
 	AMask = (1<<AShift) - 1
@@ -89,11 +89,12 @@ enum Alt {
 enum {
 	RTmp,
 	RCon,
+	RSlot,
 	RAlt,
 
 	RAType = RAlt + AType,
 	RACall = RAlt + ACall,
-	RASlot = RAlt + ASlot,
+	RAMem  = RAlt + AMem,
 
 	NRef = (1<<14) - 1
 };
@@ -102,10 +103,11 @@ enum {
 #define TMP(x)   (Ref){RTmp, x}
 #define CON(x)   (Ref){RCon, x}
 #define CON_Z    CON(0)          /* reserved zero constant */
+#define SLOT(x)  (Ref){RSlot, x}
 #define TYPE(x)  (Ref){RAlt, (x)|(AType<<AShift)}
 #define CALL(x)  (Ref){RAlt, (x)|(ACall<<AShift)}
-#define SLOT(x)  (assert(x<(1<<(AShift-1)) && "too many slots"), \
-                 (Ref){RAlt, (x)|(ASlot<<AShift)})
+#define MEM(x)   (assert(x<(1<<(AShift-1)) && "too many mems"), \
+                 (Ref){RAlt, (x)|(AMem<<AShift)})
 
 static inline int req(Ref a, Ref b)
 { return a.type == b.type && a.val == b.val; }
diff --git a/lisc/live.c b/lisc/live.c
index b0a4186..ea6414d 100644
--- a/lisc/live.c
+++ b/lisc/live.c
@@ -40,6 +40,7 @@ filllive(Fn *f)
 	Ins *i;
 	int z, m, n, chg, nlv;
 	Bits u, v;
+	Mem *ma;
 
 	assert(f->ntmp <= NBit*BITS);
 	for (b=f->start; b; b=b->link) {
@@ -83,8 +84,17 @@ Again:
 				nlv -= BGET(b->in, i->to.val);
 				BCLR(b->in, i->to.val);
 			}
-			bset(i->arg[0], b, &nlv);
-			bset(i->arg[1], b, &nlv);
+			for (m=0; m<2; m++)
+				switch (rtype(i->arg[m])) {
+				case RAMem:
+					ma = &f->mem[i->arg[m].val & AMask];
+					bset(ma->base, b, &nlv);
+					bset(ma->index, b, &nlv);
+					break;
+				default:
+					bset(i->arg[0], b, &nlv);
+					break;
+				}
 			if (nlv > b->nlive)
 				b->nlive = nlv;
 		}
diff --git a/lisc/parse.c b/lisc/parse.c
index d0ac325..aa311c4 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -820,8 +820,8 @@ printref(Ref r, Fn *fn, FILE *f)
 			diag("printref: invalid constant");
 		}
 		break;
-	case RASlot:
-		fprintf(f, "S%d", r.val & AMask);
+	case RSlot:
+		fprintf(f, "S%d", r.val);
 		break;
 	case RACall:
 		fprintf(f, "%x", r.val & AMask);
@@ -829,6 +829,9 @@ printref(Ref r, Fn *fn, FILE *f)
 	case RAType:
 		fprintf(f, ":%s", typ[r.val & AMask].name);
 		break;
+	case RAMem:
+		fprintf(f, "[]");
+		break;
 	}
 }
 
diff --git a/lisc/rega.c b/lisc/rega.c
index 331fa85..6bd72ef 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -398,7 +398,7 @@ rega(Fn *fn)
 			npm = 0;
 			for (p=s->phi; p; p=p->link) {
 				dst = p->to;
-				assert(rtype(dst)==RASlot || rtype(dst)==RTmp);
+				assert(rtype(dst)==RSlot || rtype(dst)==RTmp);
 				if (rtype(dst) == RTmp) {
 					r = rfind(&beg[s->id], dst.val);
 					if (r == -1)