summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c17
-rw-r--r--lisc/isel.c8
-rw-r--r--lisc/lisc.h28
-rw-r--r--lisc/main.c2
-rw-r--r--lisc/parse.c193
5 files changed, 201 insertions, 47 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 52bddd7..449824c 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -143,8 +143,8 @@ eins(Ins i, Fn *fn, FILE *f)
 		[OSext]   = "movsl",
 		[OZext]   = "movzl",
 		[OLoad]   = "mov",
-		[OLoadss] = "movsw",
-		[OLoadus] = "movzw",
+		[OLoadsh] = "movsw",
+		[OLoaduh] = "movzw",
 		[OLoadsb] = "movsb",
 		[OLoadub] = "movzb",
 	};
@@ -214,8 +214,8 @@ eins(Ins i, Fn *fn, FILE *f)
 			i.op - OStorel, i.arg[0], i.arg[1]);
 		break;
 	case OLoad:
-	case OLoadss:
-	case OLoadus:
+	case OLoadsh:
+	case OLoaduh:
 	case OLoadsb:
 	case OLoadub:
 		emitf(fn, f, "\t%s%w %M, %R\n", otoa[i.op],
@@ -298,11 +298,12 @@ emitfn(Fn *fn, FILE *f)
 
 	fprintf(f,
 		".text\n"
-		".globl liscf\n"
-		".type liscf, @function\n"
-		"liscf:\n"
+		".globl %s\n"
+		".type %s, @function\n"
+		"%s:\n"
 		"\tpush %%rbp\n"
-		"\tmov %%rsp, %%rbp\n"
+		"\tmov %%rsp, %%rbp\n",
+		fn->name, fn->name, fn->name
 	);
 	fs = framesz(fn);
 	if (fs)
diff --git a/lisc/isel.c b/lisc/isel.c
index 795380a..6d7e7af 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -178,8 +178,8 @@ sel(Ins i, Fn *fn)
 		n = i.op == OStorel;
 		goto Emit;
 	case OLoad:
-	case OLoadss:
-	case OLoadus:
+	case OLoadsh:
+	case OLoaduh:
 	case OLoadsb:
 	case OLoadub:
 		if (cpy[0].s) {
@@ -264,8 +264,8 @@ flagi(Ins *i0, Ins *i)
 		case OStoreb:
 		case OStores:
 		case OLoad:
-		case OLoadss:
-		case OLoadus:
+		case OLoadsh:
+		case OLoaduh:
 		case OLoadsb:
 		case OLoadub:;
 		}
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 81d3280..71b0f28 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -15,6 +15,7 @@ typedef struct Blk Blk;
 typedef struct Tmp Tmp;
 typedef struct Con Con;
 typedef struct Fn Fn;
+typedef struct Type Type;
 
 typedef enum { U, F, T } B3;
 
@@ -51,6 +52,7 @@ enum {
 	NBlk    = 128,
 	NIns    = 256,
 	NAlign  = 3,
+	NSeg    = 32,
 
 	BITS    = 4,
 	NBit    = 64,
@@ -120,8 +122,8 @@ enum Op {
 	OStores,
 	OStoreb,
 	OLoad,
-	OLoadss,
-	OLoadus,
+	OLoadsh,
+	OLoaduh,
 	OLoadsb,
 	OLoadub,
 	OAlloc,
@@ -197,14 +199,6 @@ struct Blk {
 };
 
 struct Tmp {
-#if 0
-	enum {
-		TUndef,
-		TWord,
-		TLong,
-		TReg,
-	} type;
-#endif
 	char name[NString];
 	uint ndef, nuse;
 	uint cost;
@@ -232,6 +226,18 @@ struct Fn {
 	int nblk;
 	Blk **rpo;
 	int svec[NAlign];
+	char name[NString];
+};
+
+struct Type {
+	int dark;
+	int size;
+	int align;
+
+	struct {
+		uint flt:1;
+		uint len:31;
+	} seg[NSeg];
 };
 
 
@@ -244,7 +250,7 @@ extern OpDesc opdesc[];
 void diag(char *);
 void *alloc(size_t);
 Blk *blocka(void);
-Fn *parsefn(FILE *);
+Fn *parse(FILE *);
 void printfn(Fn *, FILE *);
 
 /* ssa.c */
diff --git a/lisc/main.c b/lisc/main.c
index f4ed6ea..cb2e82e 100644
--- a/lisc/main.c
+++ b/lisc/main.c
@@ -24,7 +24,7 @@ main(int ac, char *av[])
 	int opt, pr;
 	Fn *fn;
 
-	fn = parsefn(stdin);
+	fn = parse(stdin);
 
 	pr = 1;
 	opt = 0;
diff --git a/lisc/parse.c b/lisc/parse.c
index 1508063..43d40bb 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -25,8 +25,8 @@ OpDesc opdesc[NOp] = {
 	[OStores] = { "stores", 2, 0 },
 	[OStoreb] = { "storeb", 2, 0 },
 	[OLoad]   = { "load",   1, 0 },
-	[OLoadss] = { "loadss", 1, 0 },
-	[OLoadus] = { "loadus", 1, 0 },
+	[OLoadsh] = { "loadsh", 1, 0 },
+	[OLoaduh] = { "loaduh", 1, 0 },
 	[OLoadsb] = { "loadsb", 1, 0 },
 	[OLoadub] = { "loadub", 1, 0 },
 	[OCopy]   = { "copy",   1, 1 },
@@ -34,8 +34,8 @@ OpDesc opdesc[NOp] = {
 	[OSwap]   = { "swap",   2, 2 },
 	[OSign]   = { "sign",   1, 0 },
 	[OXDiv]   = { "xdiv",   1, 1 },
-	[OXCmp]   = { "xcmp",  2, 1 },
-	[OXTest]  = { "xtest", 2, 1 },
+	[OXCmp]   = { "xcmp",   2, 1 },
+	[OXTest]  = { "xtest",  2, 1 },
 	[OAddr]   = { "addr",   1, 0 },
 	[OAlloc]   = { "alloc4",  1, 1 },
 	[OAlloc+1] = { "alloc8",  1, 1 },
@@ -62,17 +62,27 @@ enum {
 	TJmp,
 	TJnz,
 	TRet,
-	TW,
+	TFunc,
+	TType,
+	TAlign,
 	TL,
+	TW,
+	TH,
+	TB,
+	TD,
+	TS,
 
 	TNum,
 	TTmp,
 	TLbl,
-	TAddr,
+	TGlo,
+	TTyp,
 	TEq,
 	TComma,
 	TLParen,
 	TRParen,
+	TLBrace,
+	TRBrace,
 	TNL,
 	TEOF,
 };
@@ -140,8 +150,15 @@ lex()
 		{ "jmp", TJmp },
 		{ "jnz", TJnz },
 		{ "ret", TRet },
-		{ "w", TW },
+		{ "function", TFunc },
+		{ "type", TType },
+		{ "align", TAlign },
 		{ "l", TL },
+		{ "w", TW },
+		{ "h", TS },
+		{ "b", TB },
+		{ "d", TD },
+		{ "s", TS },
 		{ 0, TXXX }
 	};
 	static char tok[NString];
@@ -160,19 +177,23 @@ lex()
 		return TLParen;
 	case ')':
 		return TRParen;
+	case '{':
+		return TLBrace;
+	case '}':
+		return TRBrace;
 	case '=':
 		return TEq;
 	case '%':
 		t = TTmp;
-		c = fgetc(inf);
 		goto Alpha;
 	case '@':
 		t = TLbl;
-		c = fgetc(inf);
 		goto Alpha;
 	case '$':
-		t = TAddr;
-		c = fgetc(inf);
+		t = TGlo;
+		goto Alpha;
+	case ':':
+		t = TTyp;
 		goto Alpha;
 	case '#':
 		while (fgetc(inf) != '\n')
@@ -201,7 +222,8 @@ lex()
 		return TNum;
 	}
 	t = TXXX;
-Alpha:
+	if (0)
+Alpha:		c = fgetc(inf);
 	if (!isalpha(c))
 		err("lexing failure");
 	i = 0;
@@ -246,6 +268,17 @@ next()
 	return t;
 }
 
+static int
+nextnl()
+{
+	int t;
+
+	do
+		t = next();
+	while (t == TNL);
+	return t;
+}
+
 Blk *
 blocka()
 {
@@ -288,7 +321,7 @@ parseref()
 		c = (Con){.type = CNum, .val = tokval.num};
 		strcpy(c.label, "");
 	if (0) {
-	case TAddr:
+	case TGlo:
 		c = (Con){.type = CAddr, .val = 0};
 		strcpy(c.label, tokval.str);
 	}
@@ -367,11 +400,9 @@ parseline(PState ps)
 	Blk *b;
 	int t, op, i, w;
 
-	do
-		t = next();
-	while (t == TNL);
-	if (ps == PLbl && t != TLbl && t != TEOF)
-		err("label or end of file expected");
+	t = nextnl();
+	if (ps == PLbl && t != TLbl && t != TRBrace)
+		err("label or } expected");
 	switch (t) {
 	default:
 		if (OStorel <= t && t <= OStoreb) {
@@ -381,7 +412,7 @@ parseline(PState ps)
 			goto DoOp;
 		}
 		err("label, instruction or jump expected");
-	case TEOF:
+	case TRBrace:
 		return PEnd;
 	case TTmp:
 		break;
@@ -492,15 +523,17 @@ DoOp:
 	}
 }
 
-Fn *
-parsefn(FILE *f)
+static Fn *
+parsefn()
 {
 	int i;
 	PState ps;
 	Fn *fn;
 
-	inf = f;
-	thead = TXXX;
+	if (next() != TGlo)
+		err("function name expected");
+	if (nextnl() != TLBrace)
+		err("function must start with {");
 	for (i=0; i<NBlk; i++)
 		bmap[i] = 0;
 	for (i=Tmp0; i<NTmp; i++)
@@ -512,6 +545,7 @@ parsefn(FILE *f)
 	lnum = 1;
 	nblk = 0;
 	fn = alloc(sizeof *fn);
+	strcpy(fn->name, tokval.str);
 	blink = &fn->start;
 	ps = PLbl;
 	do
@@ -533,6 +567,119 @@ parsefn(FILE *f)
 }
 
 static void
+parsety()
+{
+	Type *ty;
+	int t, n, sz, al, s, a, c, flt;
+
+	ty = alloc(sizeof *ty);
+	ty->align = -1;
+	if (nextnl() != TTyp ||  nextnl() != TEq)
+		err("type name, then = expected");
+	t = nextnl();
+	if (t == TAlign) {
+		if (nextnl() != TNum)
+			err("alignment value expected");
+		for (al=0; tokval.num /= 2; al++)
+			;
+		ty->align = al;
+		t = nextnl();
+	}
+	if (t != TLBrace)
+		err("type body must start with {");
+	t = nextnl();
+	if (t == TNum) {
+		ty->dark = 1;
+		ty->size = tokval.num;
+		if (ty->align == -1)
+			err("dark types need alignment");
+		t = nextnl();
+	} else {
+		ty->dark = 0;
+		n = -1;
+		sz = 0;
+		al = 0;
+		do {
+			flt = 0;
+			switch (nextnl()) {
+			default: err("invalid size specifier");
+			case TD: flt = 1;
+			case TL: s = 8; a = 3; break;
+			case TS: flt = 1;
+			case TW: s = 4; a = 2; break;
+			case TH: s = 2; a = 1; break;
+			case TB: s = 1; a = 0; break;
+			}
+			if (a > al)
+				al = a;
+			if ((a = sz & s-1)) {
+				a = s - a;
+				if (++n < NSeg) {
+					/* padding segment */
+					ty->seg[n].flt = 0;
+					ty->seg[n].len = a;
+				}
+			}
+			t = nextnl();
+			if (t == TNum) {
+				c = tokval.num;
+				t = nextnl();
+			} else
+				c = 1;
+			while (c-- > 0) {
+				if (flt && ++n < NSeg) {
+					/* floating point segment */
+					ty->seg[n].flt = 1;
+					ty->seg[n].len = s;
+				}
+				sz += a + s;
+			}
+		} while (t == TComma);
+		if (++n >= NSeg)
+			ty->dark = 1;
+		else
+			ty->seg[n].len = 0;
+		if (ty->align == -1)
+			ty->align = al;
+		else
+			al = ty->align;
+		a = (1 << al) - 1;
+		ty->size = (sz + a) & ~a;
+	}
+	if (t != TLBrace)
+		err("expected closing }");
+}
+
+Fn *
+parse(FILE *f)
+{
+	Fn *fn;
+
+	fn = 0;
+	inf = f;
+	thead = TXXX;
+	for (;;)
+		switch (nextnl()) {
+		case TFunc:
+			if (fn)
+				/* todo, support multiple
+				 * functions per file
+				 */
+				diag("too many functions");
+			fn = parsefn();
+			break;
+		case TType:
+			parsety();
+			break;
+		case TEOF:
+			return fn;
+		default:
+			err("top-level definition expected");
+			break;
+		}
+}
+
+static void
 printref(Ref r, Fn *fn, FILE *f)
 {
 	switch (r.type) {