diff options
-rw-r--r-- | all.h | 7 | ||||
-rw-r--r-- | ops.h | 8 | ||||
-rw-r--r-- | parse.c | 83 | ||||
-rw-r--r-- | tools/lexh.c | 7 |
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) { |