summary refs log tree commit diff
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c83
1 files changed, 58 insertions, 25 deletions
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: