summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-08-23 16:29:31 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2022-10-03 10:41:03 +0200
commit0b26cd4f5ecff8a01fb3f0adb902c14e043581e9 (patch)
tree5357b1aeffed63d0b08274fee053182941f4f252
parentbdaf8d374e5054c7f0a006f6bc038ee08d165fd3 (diff)
downloadroux-0b26cd4f5ecff8a01fb3f0adb902c14e043581e9.tar.gz
parse sb,ub,sh,uh abi types
-rw-r--r--all.h7
-rw-r--r--ops.h8
-rw-r--r--parse.c83
-rw-r--r--tools/lexh.c7
4 files changed, 74 insertions, 31 deletions
diff --git a/all.h b/all.h
index 1ecea8e..d7b75b5 100644
--- a/all.h
+++ b/all.h
@@ -144,8 +144,9 @@ enum O {
 enum J {
 	Jxxx,
 #define JMPS(X)                                 \
-	X(ret0)   X(retw)   X(retl)   X(rets)   \
-	X(retd)   X(retc)   X(jmp)    X(jnz)    \
+	X(retw)   X(retl)   X(rets)   X(retd)   \
+	X(retsb)  X(retub)  X(retsh)  X(retuh)  \
+	X(retc)   X(ret0)   X(jmp)    X(jnz)    \
 	X(jfieq)  X(jfine)  X(jfisge) X(jfisgt) \
 	X(jfisle) X(jfislt) X(jfiuge) X(jfiugt) \
 	X(jfiule) X(jfiult) X(jffeq)  X(jffge)  \
@@ -181,7 +182,7 @@ enum {
 #define isext(o) INRANGE(o, Oextsb, Oextuw)
 #define ispar(o) INRANGE(o, Opar, Opare)
 #define isarg(o) INRANGE(o, Oarg, Oargv)
-#define isret(j) INRANGE(j, Jret0, Jretc)
+#define isret(j) INRANGE(j, Jretw, Jret0)
 
 enum {
 	Kx = -1, /* "top" class (see usecheck() and clsmerge()) */
diff --git a/ops.h b/ops.h
index 285bc5c..3d65081 100644
--- a/ops.h
+++ b/ops.h
@@ -144,9 +144,17 @@ O(rnez,    T(w,l,e,e, x,x,e,e), 0) X(0, 0, 0) V(0)
 
 /* Arguments, Parameters, and Calls */
 O(par,     T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(parsb,   T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(parub,   T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(parsh,   T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(paruh,   T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
 O(parc,    T(e,x,e,e, e,x,e,e), 0) X(0, 0, 0) V(0)
 O(pare,    T(e,x,e,e, e,x,e,e), 0) X(0, 0, 0) V(0)
 O(arg,     T(w,l,s,d, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(argsb,   T(w,e,e,e, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(argub,   T(w,e,e,e, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(argsh,   T(w,e,e,e, x,x,x,x), 0) X(0, 0, 0) V(0)
+O(arguh,   T(w,e,e,e, x,x,x,x), 0) X(0, 0, 0) V(0)
 O(argc,    T(e,x,e,e, e,l,e,e), 0) X(0, 0, 0) V(0)
 O(arge,    T(e,l,e,e, e,x,e,e), 0) X(0, 0, 0) V(0)
 O(argv,    T(x,x,x,x, x,x,x,x), 0) X(0, 0, 0) V(0)
diff --git a/parse.c b/parse.c
index cfed548..e5ceca8 100644
--- a/parse.c
+++ b/parse.c
@@ -3,8 +3,15 @@
 #include <stdarg.h>
 
 enum {
-	Ke = -2, /* Erroneous mode */
-	Km = Kl, /* Memory pointer */
+	Ksb = 4, /* matches Oarg/Opar/Jret */
+	Kub,
+	Ksh,
+	Kuh,
+	Kc,
+	K0,
+
+	Ke = -2, /* erroneous mode */
+	Km = Kl, /* memory pointer */
 };
 
 Op optab[NOp] = {
@@ -45,7 +52,11 @@ enum {
 	Talign,
 	Tl,
 	Tw,
+	Tsh,
+	Tuh,
 	Th,
+	Tsb,
+	Tub,
 	Tb,
 	Td,
 	Ts,
@@ -93,12 +104,16 @@ static char *kwmap[Ntok] = {
 	[Tdata] = "data",
 	[Tsection] = "section",
 	[Talign] = "align",
-	[Tl] = "l",
-	[Tw] = "w",
-	[Th] = "h",
+	[Tsb] = "sb",
+	[Tub] = "ub",
+	[Tsh] = "sh",
+	[Tuh] = "uh",
 	[Tb] = "b",
-	[Td] = "d",
+	[Th] = "h",
+	[Tw] = "w",
+	[Tl] = "l",
 	[Ts] = "s",
+	[Td] = "d",
 	[Tz] = "z",
 	[Tdots] = "...",
 };
@@ -109,7 +124,7 @@ enum {
 	TMask = 16383, /* for temps hash */
 	BMask = 8191, /* for blocks hash */
 
-	K = 5041217, /* found using tools/lexh.c */
+	K = 9583425, /* found using tools/lexh.c */
 	M = 23,
 };
 
@@ -427,7 +442,15 @@ parsecls(int *tyn)
 		err("invalid class specifier");
 	case Ttyp:
 		*tyn = findtyp(ntyp);
-		return 4;
+		return Kc;
+	case Tsb:
+		return Ksb;
+	case Tub:
+		return Kub;
+	case Tsh:
+		return Ksh;
+	case Tuh:
+		return Kuh;
 	case Tw:
 		return Kw;
 	case Tl:
@@ -482,16 +505,21 @@ parserefl(int arg)
 			err("invalid argument");
 		if (!arg && rtype(r) != RTmp)
 			err("invalid function parameter");
-		if (k == 4)
+		if (env)
+			if (arg)
+				*curi = (Ins){Oarge, k, R, {r}};
+			else
+				*curi = (Ins){Opare, k, r, {R}};
+		else if (k == Kc)
 			if (arg)
 				*curi = (Ins){Oargc, Kl, R, {TYPE(ty), r}};
 			else
 				*curi = (Ins){Oparc, Kl, r, {TYPE(ty)}};
-		else if (env)
+		else if (k >= Ksb)
 			if (arg)
-				*curi = (Ins){Oarge, k, R, {r}};
+				*curi = (Ins){Oargsb+(k-Ksb), Kw, R, {r}};
 			else
-				*curi = (Ins){Opare, k, r, {R}};
+				*curi = (Ins){Oparsb+(k-Ksb), Kw, r, {R}};
 		else
 			if (arg)
 				*curi = (Ins){Oarg, k, R, {r}};
@@ -578,14 +606,10 @@ parseline(PState ps)
 		expect(Tnl);
 		return PPhi;
 	case Tret:
-		curb->jmp.type = (int[]){
-			Jretw, Jretl,
-			Jrets, Jretd,
-			Jretc, Jret0
-		}[rcls];
+		curb->jmp.type = Jretw + rcls;
 		if (peek() == Tnl)
 			curb->jmp.type = Jret0;
-		else if (rcls < 5) {
+		else if (rcls != K0) {
 			r = parseref();
 			if (req(r, R))
 				err("invalid return value");
@@ -632,11 +656,13 @@ DoOp:
 		parserefl(1);
 		op = Ocall;
 		expect(Tnl);
-		if (k == 4) {
+		if (k == Kc) {
 			k = Kl;
 			arg[1] = TYPE(ty);
 		} else
 			arg[1] = R;
+		if (k >= Ksb)
+			k = Kw;
 		goto Ins;
 	}
 	if (op == Tloadw)
@@ -645,7 +671,7 @@ DoOp:
 		op = Oload;
 	if (op == Talloc1 || op == Talloc2)
 		op = Oalloc;
-	if (k == 4)
+	if (k >= Ksb)
 		err("size class must be w, l, s, or d");
 	if (op >= NPubOp)
 		err("invalid instruction");
@@ -774,10 +800,13 @@ typecheck(Fn *fn)
 			}
 		r = b->jmp.arg;
 		if (isret(b->jmp.type)) {
-			if (b->jmp.type == Jretc) {
-				if (!usecheck(r, Kl, fn))
-					goto JErr;
-			} else if (!usecheck(r, b->jmp.type-Jretw, fn))
+			if (b->jmp.type == Jretc)
+				k = Kl;
+			else if (b->jmp.type >= Jretsb)
+				k = Kw;
+			else
+				k = b->jmp.type - Jretw;
+			if (!usecheck(r, k, fn))
 				goto JErr;
 		}
 		if (b->jmp.type == Jjnz && !usecheck(r, Kw, fn))
@@ -818,7 +847,7 @@ parsefn(Lnk *lnk)
 	if (peek() != Tglo)
 		rcls = parsecls(&curf->retty);
 	else
-		rcls = 5;
+		rcls = K0;
 	if (next() != Tglo)
 		err("function name expected");
 	strncpy(curf->name, tokval.str, NString-1);
@@ -1266,6 +1295,10 @@ printfn(Fn *fn, FILE *f)
 		}
 		switch (b->jmp.type) {
 		case Jret0:
+		case Jretsb:
+		case Jretub:
+		case Jretsh:
+		case Jretuh:
 		case Jretw:
 		case Jretl:
 		case Jrets:
diff --git a/tools/lexh.c b/tools/lexh.c
index 8d0af21..1aea3e0 100644
--- a/tools/lexh.c
+++ b/tools/lexh.c
@@ -27,8 +27,9 @@ char *tok[] = {
 
 	"call", "phi", "jmp", "jnz", "ret", "export",
 	"function", "type", "data", "section", "align",
-	"l", "w", "h", "b", "d", "s", "z", "loadw", "loadl",
-	"loads", "loadd", "alloc1", "alloc2",
+	"l", "w", "sh", "uh", "h", "sb", "ub", "b",
+	"d", "s", "z", "loadw", "loadl", "loads", "loadd",
+	"alloc1", "alloc2",
 
 };
 enum {
@@ -69,7 +70,7 @@ main()
 		th[i] = h;
 	}
 
-	for (i=0; 1<<i < Ntok; ++i);
+	for (i=9; 1<<i < Ntok; ++i);
 	M = 32 - i;
 
 	for (;; --M) {