commit 0b26cd4f5ecff8a01fb3f0adb902c14e043581e9
parent bdaf8d374e5054c7f0a006f6bc038ee08d165fd3
Author: Quentin Carbonneaux <quentin@c9x.me>
Date: Tue, 23 Aug 2022 16:29:31 +0200
parse sb,ub,sh,uh abi types
Diffstat:
M | all.h | | | 7 | ++++--- |
M | ops.h | | | 8 | ++++++++ |
M | parse.c | | | 83 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
M | tools/lexh.c | | | 7 | ++++--- |
4 files changed, 74 insertions(+), 31 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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) {