summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c24
-rw-r--r--lisc/isel.c2
-rw-r--r--lisc/lisc.h18
-rw-r--r--lisc/parse.c40
-rw-r--r--lisc/rega.c5
-rw-r--r--lisc/ssa.c2
-rw-r--r--lisc/test/alt.ssa20
-rw-r--r--lisc/test/eucl.ssa6
-rw-r--r--lisc/test/fix1.ssa8
-rw-r--r--lisc/test/fix2.ssa8
-rw-r--r--lisc/test/live.ssa8
-rw-r--r--lisc/test/loop.ssa8
-rw-r--r--lisc/test/spill.ssa14
-rw-r--r--lisc/test/spill1.ssa32
14 files changed, 114 insertions, 81 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index a006c12..4d2bb42 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -57,15 +57,12 @@ eins(Ins i, Fn *fn, FILE *f)
 	switch (i.op) {
 	case OAdd:
 	case OSub:
-		if (req(i.to, i.arg[1]))
-			switch (opdesc[i.op].comm) {
-			case T:
-				i.arg[1] = i.arg[0];
-				i.arg[0] = i.to;
-				break;
-			default:
-				diag("emit: instruction can't be encoded");
-			}
+		if (req(i.to, i.arg[1])) {
+			if (!opdesc[i.op].comm)
+				diag("emit: unhandled instruction (1)");
+			i.arg[1] = i.arg[0];
+			i.arg[0] = i.to;
+		}
 		if (!req(i.to, i.arg[0]))
 			eop("mov", i.arg[0], i.to, fn, f);
 		eop(opi[i.op], i.arg[1], i.to, fn, f);
@@ -81,8 +78,11 @@ eins(Ins i, Fn *fn, FILE *f)
 	case OSwap:
 		eop("xchg", i.arg[0], i.arg[1], fn, f);
 		break;
-	case OXCltd:
-		fprintf(f, "\tcltd\n");
+	case OSign:
+		if (!req(i.to, SYM(RDX))
+		|| !req(i.arg[0], SYM(RAX)))
+			diag("emit: unhandled instruction (2)");
+		fprintf(f, "\tcqto\n");
 		break;
 	case OXDiv:
 		eop("idiv", i.arg[0], R, fn, f);
@@ -90,7 +90,7 @@ eins(Ins i, Fn *fn, FILE *f)
 	case ONop:
 		break;
 	default:
-		diag("emit: unhandled instruction");
+		diag("emit: unhandled instruction (3)");
 	}
 }
 
diff --git a/lisc/isel.c b/lisc/isel.c
index 3ea935f..8585703 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -50,7 +50,7 @@ sel(Ins *i, Fn *fn)
 		} else
 			r0 = i->arg[1];
 		emit(OXDiv, R, r0, R);
-		emit(OXCltd, SYM(RDX), R, R);
+		emit(OSign, SYM(RDX), SYM(RAX), R);
 		emit(OCopy, SYM(RAX), i->arg[0], R);
 		if (rtype(i->arg[1]) == RCons)
 			emit(OCopy, r0, i->arg[1], R);
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 374dcd3..d8ef273 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -19,22 +19,25 @@ typedef struct Fn Fn;
 typedef enum { U, F, T } B3;
 
 enum {
-	RAX = 1,
+	RAX = 1, /* caller-save */
 	RCX,
 	RDX,
 	RSI,
 	RDI,
-	RBX,
 	R8,
 	R9,
 	R10,
 	R11,
+
+	RBX, /* callee-save */
 	R12,
 	R13,
 	R14,
 	R15,
-	RSP, /* reserved */
+
 	RBP, /* reserved */
+	RSP,
+
 	// NReg = R15 - RAX + 1
 	NReg = 3 /* for test purposes */
 };
@@ -94,12 +97,18 @@ enum {
 	ONop,
 	OCopy,
 	OSwap,
-	OXCltd,
+	OSign,
 	OXDiv,
 	OLast
 };
 
 enum {
+	CXXX,
+	CWord,
+	CLong,
+};
+
+enum {
 	JXXX,
 	JRet,
 	JJmp,
@@ -155,6 +164,7 @@ struct Sym {
 		STmp,
 	} type;
 	char name[NString];
+	int class;
 	uint ndef, nuse;
 	uint cost;
 	uint spill;
diff --git a/lisc/parse.c b/lisc/parse.c
index 79b0c73..8e25b21 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -21,8 +21,8 @@ OpDesc opdesc[OLast] = {
 	[ONop]    = { "nop",   0, U },
 	[OCopy]   = { "copy",  1, U },
 	[OSwap]   = { "swap",  2, T },
-	[OXDiv]   = { "xdiv", 1, U },
-	[OXCltd]  = { "xcltd", 0, U },
+	[OSign]   = { "sign",  1, U },
+	[OXDiv]   = { "xdiv",  1, U },
 };
 
 typedef enum {
@@ -44,6 +44,8 @@ typedef enum {
 	TJmp,
 	TJez,
 	TRet,
+	TW,
+	TL,
 
 	TNum,
 	TVar,
@@ -142,6 +144,8 @@ lex()
 		{ "jmp", TJmp },
 		{ "jez", TJez },
 		{ "ret", TRet },
+		{ "w", TW },
+		{ "l", TL },
 		{ 0, TXXX }
 	};
 	static char tok[NString];
@@ -418,6 +422,16 @@ parseline(PState ps)
 	r = varref(tokval.str);
 	expect(TEq);
 	switch (next()) {
+	case TW:
+		sym[r.val].class = CWord;
+		break;
+	case TL:
+		sym[r.val].class = CLong;
+		break;
+	default:
+		err("class expected after =");
+	}
+	switch (next()) {
 	case TCopy:
 		op = OCopy;
 		break;
@@ -523,21 +537,26 @@ parsefn(FILE *f)
 	return fn;
 }
 
-static void
+static char *
 printref(Ref r, Fn *fn, FILE *f)
 {
+	static char *ctoa[] = {
+		[CXXX] = "?",
+		[CWord] = "w",
+		[CLong] = "l",
+	};
+
 	switch (r.type) {
 	case RSym:
 		switch (fn->sym[r.val].type) {
 		case STmp:
 			fprintf(f, "%%%s", fn->sym[r.val].name);
-			break;
+			return ctoa[fn->sym[r.val].class];
 		case SReg:
 			fprintf(f, "%s", fn->sym[r.val].name);
 			break;
 		case SUndef:
 			diag("printref: invalid symbol");
-			break;
 		}
 		break;
 	case RCons:
@@ -552,13 +571,13 @@ printref(Ref r, Fn *fn, FILE *f)
 			break;
 		case CUndef:
 			diag("printref: invalid constant");
-			break;
 		}
 		break;
 	case RSlot:
 		fprintf(f, "$%d", r.val);
 		break;
 	}
+	return "";
 }
 
 void
@@ -568,13 +587,14 @@ printfn(Fn *fn, FILE *f)
 	Phi *p;
 	Ins *i;
 	uint n;
+	char *cl;
 
 	for (b=fn->start; b; b=b->link) {
 		fprintf(f, "@%s\n", b->name);
 		for (p=b->phi; p; p=p->link) {
 			fprintf(f, "\t");
-			printref(p->to, fn, f);
-			fprintf(f, " = phi ");
+			cl = printref(p->to, fn, f);
+			fprintf(f, " =%s phi ", cl);
 			assert(p->narg);
 			for (n=0;; n++) {
 				fprintf(f, "@%s ", p->blk[n]->name);
@@ -589,8 +609,8 @@ printfn(Fn *fn, FILE *f)
 		for (i=b->ins; i-b->ins < b->nins; i++) {
 			fprintf(f, "\t");
 			if (!req(i->to, R)) {
-				printref(i->to, fn, f);
-				fprintf(f, " = ");
+				cl = printref(i->to, fn, f);
+				fprintf(f, " =%s ", cl);
 			}
 			assert(opdesc[i->op].name);
 			fprintf(f, "%s", opdesc[i->op].name);
diff --git a/lisc/rega.c b/lisc/rega.c
index 27d61ee..ac0b2d4 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -62,7 +62,10 @@ ralloc(RMap *m, int t)
 {
 	int r;
 
-	if (BGET(m->bt, t)) {
+	if (sym[t].type == SReg) {
+		assert(BGET(m->br, t));
+		r = t;
+	} else if (BGET(m->bt, t)) {
 		r = rfind(m, t);
 		assert(r > 0);
 	} else {
diff --git a/lisc/ssa.c b/lisc/ssa.c
index 5546190..96d6a34 100644
--- a/lisc/ssa.c
+++ b/lisc/ssa.c
@@ -191,7 +191,7 @@ ssafix(Fn *f, int t)
 	if (!f->sym)
 		diag("ssafix: out of memory");
 	for (t1=t0; t0<f->ntmp; t0++) {
-		f->sym[t0].type = STmp;
+		f->sym[t0] = f->sym[t];
 		snprintf(f->sym[t0].name, NString, "%s%d",
 			f->sym[t].name, t0-t1);
 	}
diff --git a/lisc/test/alt.ssa b/lisc/test/alt.ssa
index 0e4748a..480177a 100644
--- a/lisc/test/alt.ssa
+++ b/lisc/test/alt.ssa
@@ -3,21 +3,21 @@
 # handling of looping constructs
 
 @start
-	%ten = copy 10
-	%dum = copy 0  # dummy live-through temporary
+	%ten =w copy 10
+	%dum =w copy 0  # dummy live-through temporary
 @loop
-	%alt = phi @start 0, @left %alt1, @right %alt1
-	%cnt = phi @start 100, @left %cnt, @right %cnt1
-	%alt1 = sub 1, %alt
+	%alt =w phi @start 0, @left %alt1, @right %alt1
+	%cnt =w phi @start 100, @left %cnt, @right %cnt1
+	%alt1 =w sub 1, %alt
 	jez %alt1, @left, @right
 @left
-	%x = phi @loop 10, @left %x1
-	%x1 = sub %x, 1
-	%z = copy %x
+	%x =w phi @loop 10, @left %x1
+	%x1 =w sub %x, 1
+	%z =w copy %x
 	jez %z, @loop, @left
 @right
-	%cnt1 = sub %cnt, %ten
+	%cnt1 =w sub %cnt, %ten
 	jez %cnt1, @end, @loop
 @end
-	%ret = add %cnt, %dum
+	%ret =w add %cnt, %dum
 	ret
diff --git a/lisc/test/eucl.ssa b/lisc/test/eucl.ssa
index 71725ea..fdbca57 100644
--- a/lisc/test/eucl.ssa
+++ b/lisc/test/eucl.ssa
@@ -6,9 +6,9 @@
 @start
 
 @loop
-	%a = phi @start 380, @loop %r
-	%b = phi @start 747, @loop %a
-	%r = rem %b, %a
+	%a =w phi @start 380, @loop %r
+	%b =w phi @start 747, @loop %a
+	%r =w rem %b, %a
 	jez %r, @end, @loop
 
 @end
diff --git a/lisc/test/fix1.ssa b/lisc/test/fix1.ssa
index 783f6f7..d6250d2 100644
--- a/lisc/test/fix1.ssa
+++ b/lisc/test/fix1.ssa
@@ -1,13 +1,13 @@
 @start
-	%x = copy 1
+	%x =w copy 1
 @loop
 	jez %x, @isz, @noz
 @noz
-	%x = copy 0
+	%x =w copy 0
 	jmp @end
 @isz
-	%x = copy 1
+	%x =w copy 1
 	jmp @loop
 @end
-	%z = add 10, %x
+	%z =w add 10, %x
 	ret
diff --git a/lisc/test/fix2.ssa b/lisc/test/fix2.ssa
index 2b3cf88..0b07584 100644
--- a/lisc/test/fix2.ssa
+++ b/lisc/test/fix2.ssa
@@ -1,13 +1,13 @@
 @start
-	%x = copy 1
+	%x =w copy 1
 @loop
 	jez %x, @isz, @noz
 @noz
-	%x = copy 0
+	%x =w copy 0
 	jez %x, @end, @loop
 @isz
-	%x = copy 1
+	%x =w copy 1
 	jmp @loop
 @end
-	%z = add 10, %x
+	%z =w add 10, %x
 	ret
diff --git a/lisc/test/live.ssa b/lisc/test/live.ssa
index 2d5546d..2e3110d 100644
--- a/lisc/test/live.ssa
+++ b/lisc/test/live.ssa
@@ -6,14 +6,14 @@
 # nothing should ever be live at the entry
 
 @start
-	%b = copy 0
-	%x = copy 10
+	%b =w copy 0
+	%x =w copy 10
 	jez 0, @left, @loop
 @left
 	jmp @inloop
 @loop
-	%x1 = add %x, 1
+	%x1 =w add %x, 1
 @inloop
-	%b1 = add %b, 1
+	%b1 =w add %b, 1
 @endloop
 	jmp @loop
diff --git a/lisc/test/loop.ssa b/lisc/test/loop.ssa
index 39d74e4..1b55e02 100644
--- a/lisc/test/loop.ssa
+++ b/lisc/test/loop.ssa
@@ -4,10 +4,10 @@
 @start
 
 @loop
-	%s  = phi @start 100, @loop %s1
-	%n  = phi @start   0, @loop %n1
-	%n1 = sub %n, 1
-	%s1 = add %s, %n
+	%s  =w phi @start 100, @loop %s1
+	%n  =w phi @start   0, @loop %n1
+	%n1 =w sub %n, 1
+	%s1 =w add %s, %n
 	jez %n1, @end, @loop
 
 @end
diff --git a/lisc/test/spill.ssa b/lisc/test/spill.ssa
index 072a231..a504c52 100644
--- a/lisc/test/spill.ssa
+++ b/lisc/test/spill.ssa
@@ -10,11 +10,11 @@
 #
 
 @start
-	%f = copy 0      # here
-	%b = copy 1
-	%c = copy 2
-	%a = sub %b, %c
-	%d = copy %b
-	%e = copy %f     # and there
-	%g = copy %a
+	%f =w copy 0      # here
+	%b =w copy 1
+	%c =w copy 2
+	%a =w sub %b, %c
+	%d =w copy %b
+	%e =w copy %f     # and there
+	%g =w copy %a
 	ret
diff --git a/lisc/test/spill1.ssa b/lisc/test/spill1.ssa
index 5ebfd8c..9dc5213 100644
--- a/lisc/test/spill1.ssa
+++ b/lisc/test/spill1.ssa
@@ -1,20 +1,20 @@
 # stupid spilling test
 
 @start
-	%x1  = copy 10
-	%x2  = add %x1, %x1
-	%x3  = sub %x2, %x1
-	%x4  = add %x3, %x1
-	%x5  = sub %x4, %x1
-	%x6  = add %x5, %x1
-	%x7  = sub %x6, %x1
-	%x8  = add %x7, %x1
-	%x9  = sub %x8, %x8
-	%x10 = add %x9, %x7
-	%x11 = sub %x10, %x6
-	%x12 = add %x11, %x5
-	%x13 = sub %x12, %x4
-	%x14 = add %x13, %x3
-	%x15 = sub %x14, %x2
-	%x16 = add %x15, %x1
+	%x1  =w copy 10
+	%x2  =w add %x1, %x1
+	%x3  =w sub %x2, %x1
+	%x4  =w add %x3, %x1
+	%x5  =w sub %x4, %x1
+	%x6  =w add %x5, %x1
+	%x7  =w sub %x6, %x1
+	%x8  =w add %x7, %x1
+	%x9  =w sub %x8, %x8
+	%x10 =w add %x9, %x7
+	%x11 =w sub %x10, %x6
+	%x12 =w add %x11, %x5
+	%x13 =w sub %x12, %x4
+	%x14 =w add %x13, %x3
+	%x15 =w sub %x14, %x2
+	%x16 =w add %x15, %x1
 	ret