summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c31
-rw-r--r--lisc/isel.c3
-rw-r--r--lisc/lisc.h35
-rw-r--r--lisc/parse.c20
-rw-r--r--lisc/rega.c2
-rw-r--r--lisc/test/collatz.ssa6
6 files changed, 67 insertions, 30 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 9500dc9..b8365c2 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -37,9 +37,10 @@ emitf(Fn *fn, FILE *f, char *fmt, ...)
 	static char stoa[] = "qlwb";
 	va_list ap;
 	char c, *s, *s1;
-	int i, ty;
+	int i, ty, off;
 	Ref ref;
 	Con *con;
+	struct { int i:AShift; } x;
 
 	va_start(ap, fmt);
 	ty = SWord;
@@ -81,10 +82,9 @@ Next:
 			assert(isreg(ref));
 			fprintf(f, "%%%s", rsub[ref.val][ty]);
 			break;
-		case RSlot:
-		Slot: {
-			int off;
-			struct { int i:14; } x = {ref.val}; /* fixme */
+		case RASlot:
+		Slot:
+			x.i = ref.val & AMask;
 			assert(NAlign == 3);
 			if (x.i < 0)
 				off = -4 * x.i;
@@ -94,7 +94,6 @@ Next:
 			}
 			fprintf(f, "%d(%%rbp)", off);
 			break;
-		}
 		case RCon:
 			fputc('$', f);
 		Con:
@@ -117,9 +116,9 @@ Next:
 	case 'M':
 		ref = va_arg(ap, Ref);
 		switch (rtype(ref)) {
-		default:    diag("emit: invalid memory reference");
-		case RSlot: goto Slot;
-		case RCon:  goto Con;
+		default:     diag("emit: invalid memory reference");
+		case RASlot: goto Slot;
+		case RCon:   goto Con;
 		case RTmp:
 			assert(isreg(ref));
 			fprintf(f, "(%%%s)", rsub[ref.val][SLong]);
@@ -234,6 +233,20 @@ eins(Ins i, Fn *fn, FILE *f)
 		emitf(fn, f, "%s%w %M, %R", otoa[i.op],
 			i.wide, i.arg[0], i.to);
 		break;
+	case OExt+Tuw:
+		emitf(fn, f, "movl %R, %R", i.arg[0], i.to);
+		break;
+	case OExt+Tsw:
+	case OExt+Tsh:
+	case OExt+Tuh:
+	case OExt+Tsb:
+	case OExt+Tub:
+		emitf(fn, f, "mov%s%t%s %R, %W%R",
+			(i.op-OExt-Tsw)%2 ? "z" : "s",
+			1+(i.op-OExt-Tsw)/2,
+			i.wide ? "q" : "l",
+			i.arg[0], i.wide, i.to);
+		break;
 	case OCall:
 		switch (rtype(i.arg[0])) {
 		default:
diff --git a/lisc/isel.c b/lisc/isel.c
index c3da2cf..6114bdb 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -373,7 +373,8 @@ classify(Ins *i0, Ins *i1, AClass *ac, int op)
 			a->size = 8;
 			a->rty[0] = RInt;
 		} else {
-			aclass(a, &typ[i->arg[0].val]);
+			n = i->arg[0].val & AMask;
+			aclass(a, &typ[n]);
 			if (a->inmem)
 				continue;
 			ni = ns = 0;
diff --git a/lisc/lisc.h b/lisc/lisc.h
index d2f6ef2..a9a53fd 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -75,12 +75,24 @@ struct Ref {
 	uint16_t val:14;
 };
 
+enum Alt {
+	AType,
+	ACall,
+	ASlot,
+
+	AShift = 12,
+	AMask = (1<<AShift) - 1
+};
+
 enum {
 	RTmp,
 	RCon,
-	RSlot,
 	RAlt,
-	RCallm = 0x1000,
+
+	RAType = RAlt + AType,
+	RACall = RAlt + ACall,
+	RASlot = RAlt + ASlot,
+
 	NRef = (1<<14) - 1
 };
 
@@ -88,14 +100,21 @@ 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 TYP(x)   (Ref){RAlt, x}
-#define CALL(x)  (Ref){RAlt, (x)|RCallm}
+#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)})
 
 static inline int req(Ref a, Ref b)
 { return a.type == b.type && a.val == b.val; }
 static inline int rtype(Ref r)
-{ return req(r, R) ? -1 : r.type; }
+{
+	if (req(r, R))
+		return -1;
+	if (r.type == RAlt)
+		return RAlt + (r.val >> AShift);
+	return r.type;
+}
 static inline int isreg(Ref r)
 { return rtype(r) == RTmp && r.val < Tmp0; }
 
@@ -147,6 +166,10 @@ enum Op {
 	OCall,
 
 	/* reserved instructions */
+	OScale1, /* for memory addressing */
+	OScale2,
+	OScale3,
+	OScale4,
 	ONop,
 	OAddr,
 	OSwap,
diff --git a/lisc/parse.c b/lisc/parse.c
index a4cc484..feb11a0 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -388,9 +388,9 @@ parserefl(int arg)
 			err("invalid function parameter");
 		if (w == 2)
 			if (arg)
-				*curi = (Ins){OArgc, 0, R, {TYP(ty), r}};
+				*curi = (Ins){OArgc, 0, R, {TYPE(ty), r}};
 			else
-				*curi = (Ins){OParc, 0, r, {TYP(ty)}};
+				*curi = (Ins){OParc, 0, r, {TYPE(ty)}};
 		else
 			if (arg)
 				*curi = (Ins){OArg, w, R, {r}};
@@ -526,7 +526,7 @@ DoOp:
 		op = OCall;
 		if (w == 2) {
 			w = 0;
-			arg[1] = TYP(ty);
+			arg[1] = TYPE(ty);
 		} else
 			arg[1] = R;
 		goto Ins;
@@ -818,14 +818,14 @@ printref(Ref r, Fn *fn, FILE *f)
 			diag("printref: invalid constant");
 		}
 		break;
-	case RSlot:
-		fprintf(f, "S%d", r.val);
+	case RASlot:
+		fprintf(f, "S%d", r.val & AMask);
 		break;
-	case RAlt:
-		if (r.val & RCallm)
-			fprintf(f, "%x", r.val & (RCallm-1));
-		else
-			fprintf(f, ":%s", typ[r.val].name);
+	case RACall:
+		fprintf(f, "%x", r.val & AMask);
+		break;
+	case RAType:
+		fprintf(f, ":%s", typ[r.val & AMask].name);
 		break;
 	}
 }
diff --git a/lisc/rega.c b/lisc/rega.c
index b0db117..2f6d613 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)==RSlot|| rtype(dst)==RTmp);
+				assert(rtype(dst)==RASlot || rtype(dst)==RTmp);
 				if (rtype(dst) == RTmp) {
 					r = rfind(&beg[s->id], dst.val);
 					if (r == -1)
diff --git a/lisc/test/collatz.ssa b/lisc/test/collatz.ssa
index 8bc80cb..0c79a05 100644
--- a/lisc/test/collatz.ssa
+++ b/lisc/test/collatz.ssa
@@ -31,14 +31,14 @@ function $test() {
 	%n3 =w div %n0, 2
 	jmp @cloop
 @getmemo                     # get the count for n0 in mem
-	%n0l =l sext %n0
+	%n0l =l extsw %n0
 	%idx0 =l mul %n0l, 4
 	%loc0 =l add %idx0, %mem
-	%cn0 =w load %loc0
+	%cn0 =w loadw %loc0
 	%c2 =w add %c0, %cn0
 @endcl                       # store the count for n in mem
 	%c =w phi @getmemo %c2, @cloop %c0
-	%nl =l sext %n
+	%nl =l extsw %n
 	%idx1 =l mul %nl, 4
 	%loc1 =l add %idx1, %mem
 	storew %c, %loc1