diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-12-10 23:16:21 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-12-14 23:18:26 +0100 |
commit | 26c1c30b7d96d2170195970a8cdb3b024ba7421a (patch) | |
tree | 79c45ec28d63619fbe2a88ec2195f8fe4a95a8a5 /parse.c | |
parent | 15e25a61b38b250c7543437a093a9efe076cce0a (diff) | |
download | roux-26c1c30b7d96d2170195970a8cdb3b024ba7421a.tar.gz |
new blit instruction
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/parse.c b/parse.c index 0836b9a..68488a2 100644 --- a/parse.c +++ b/parse.c @@ -27,7 +27,7 @@ typedef enum { PEnd, } PState; -enum { +enum Token { Txxx = 0, /* aliases */ @@ -38,6 +38,7 @@ enum { Talloc1, Talloc2, + Tblit, Tcall, Tenv, Tphi, @@ -94,6 +95,7 @@ static char *kwmap[Ntok] = { [Tloadd] = "loadd", [Talloc1] = "alloc1", [Talloc2] = "alloc2", + [Tblit] = "blit", [Tcall] = "call", [Tenv] = "env", [Tphi] = "phi", @@ -481,7 +483,7 @@ parserefl(int arg) expect(Tlparen); while (peek() != Trparen) { if (curi - insb >= NIns) - err("too many instructions (1)"); + err("too many instructions"); if (!arg && vararg) err("no parameters allowed after '...'"); switch (peek()) { @@ -578,6 +580,7 @@ parseline(PState ps) Phi *phi; Ref r; Blk *b; + Con *c; int t, op, i, k, ty; t = nextnl(); @@ -586,6 +589,7 @@ parseline(PState ps) switch (t) { default: if (isstore(t)) { + case Tblit: case Tcall: case Ovastart: /* operations without result */ @@ -657,11 +661,6 @@ parseline(PState ps) k = parsecls(&ty); op = next(); DoOp: - if (op == Tphi) { - if (ps != PPhi || curb == curf->start) - err("unexpected phi instruction"); - op = -1; - } if (op == Tcall) { arg[0] = parseref(); parserefl(1); @@ -686,14 +685,12 @@ DoOp: err("cannot use vastart in non-variadic function"); if (k >= Ksb) err("size class must be w, l, s, or d"); - if (op >= NPubOp) - err("invalid instruction"); i = 0; if (peek() != Tnl) for (;;) { if (i == NPred) err("too many arguments"); - if (op == -1) { + if (op == Tphi) { expect(Tlbl); blk[i] = findblk(tokval.str); } @@ -709,18 +706,10 @@ DoOp: next(); } next(); -Ins: - if (op != -1) { - if (curi - insb >= NIns) - err("too many instructions (2)"); - curi->op = op; - curi->cls = k; - curi->to = r; - curi->arg[0] = arg[0]; - curi->arg[1] = arg[1]; - curi++; - return PIns; - } else { + switch (op) { + case Tphi: + if (ps != PPhi || curb == curf->start) + err("unexpected phi instruction"); phi = alloc(sizeof *phi); phi->to = r; phi->cls = k; @@ -732,6 +721,39 @@ Ins: *plink = phi; plink = &phi->link; return PPhi; + case Tblit: + if (curi - insb >= NIns-1) + err("too many instructions"); + memset(curi, 0, 2 * sizeof(Ins)); + curi->op = Oblit0; + curi->arg[0] = arg[0]; + curi->arg[1] = arg[1]; + curi++; + if (rtype(arg[2]) != RCon) + err("blit size must be constant"); + c = &curf->con[arg[2].val]; + r = INT(c->bits.i); + if (c->type != CBits + || rsval(r) < 0 + || rsval(r) != c->bits.i) + err("invalid blit size"); + curi->op = Oblit1; + curi->arg[0] = r; + curi++; + return PIns; + default: + if (op >= NPubOp) + err("invalid instruction"); + Ins: + if (curi - insb >= NIns) + err("too many instructions"); + curi->op = op; + curi->cls = k; + curi->to = r; + curi->arg[0] = arg[0]; + curi->arg[1] = arg[1]; + curi++; + return PIns; } } @@ -1241,6 +1263,9 @@ printref(Ref r, Fn *fn, FILE *f) } fputc(']', f); break; + case RInt: + fprintf(f, "%d", rsval(r)); + break; } } |