summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2018-01-20 13:07:34 -0500
committerOri Bernstein <ori@eigenstate.org>2018-01-21 14:29:38 -0800
commit720cc29f19477550800adf5539837fec15296bbc (patch)
tree34efa93381a753b3b0c06090b84116f7cc9e7967 /6
parentd8b909066008d478a8abd30cb329c88d44194730 (diff)
downloadmc-720cc29f19477550800adf5539837fec15296bbc.tar.gz
Cheap enums.
Diffstat (limited to '6')
-rw-r--r--6/isel.c12
-rw-r--r--6/simp.c30
2 files changed, 24 insertions, 18 deletions
diff --git a/6/isel.c b/6/isel.c
index d7ec0c0..e695096 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -63,7 +63,7 @@ static Mode
tymode(Type *t)
{
/* FIXME: What should the mode for, say, structs be when we have no
- * intention of loading /through/ the pointer? For now, we'll just say it'
+ * intention of loading /through/ the pointer? For now, we'll just say it's
* the pointer mode, since we expect to address through the pointer */
t = tybase(t);
switch (t->type) {
@@ -128,6 +128,7 @@ static Loc *
loc(Isel *s, Node *n)
{
Node *v;
+ Ucon *uc;
Loc *l;
if (n->type == Ndecl) {
@@ -137,6 +138,10 @@ loc(Isel *s, Node *n)
case Ovar:
l = varloc(s, n);
break;
+ case Oucon:
+ uc = finducon(exprtype(n), n->expr.args[0]);
+ l = loclit(uc->id, mode(n));
+ break;
case Olit:
v = n->expr.args[0];
switch (v->lit.littype) {
@@ -858,6 +863,9 @@ selexpr(Isel *s, Node *n)
case Ovjmp:
selvjmp(s, n, args);
break;
+ case Oucon:
+ assert(isenum(tybase(exprtype(n))));
+ /* fallthrough */
case Olit:
r = loc(s, n);
break;
@@ -936,7 +944,7 @@ selexpr(Isel *s, Node *n)
case Osubeq: case Omuleq: case Odiveq: case Omodeq: case Oboreq:
case Obandeq: case Obxoreq: case Obsleq: case Obsreq: case Omemb:
case Oslbase: case Osllen: case Ocast: case Outag: case Oudata:
- case Oucon: case Otup: case Oarr: case Ostruct:
+ case Otup: case Oarr: case Ostruct:
case Oslice: case Oidx: case Osize: case Otupget:
case Obreak: case Ocontinue:
case Numops:
diff --git a/6/simp.c b/6/simp.c
index b43a083..0a8e15f 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -338,8 +338,11 @@ uconid(Simp *s, Node *n)
Ucon *uc;
n = rval(s, n, NULL);
- if (exprop(n) != Oucon)
+ if (exprop(n) != Oucon) {
+ if (isenum(tybase(exprtype(n))))
+ return n;
return load(addr(s, n, mktype(n->loc, Tyuint)));
+ }
uc = finducon(exprtype(n), n->expr.args[0]);
return word(uc->loc, uc->id);
@@ -539,12 +542,6 @@ lval(Simp *s, Node *n)
case Ostruct: r = rval(s, n, NULL); break;
case Oucon: r = rval(s, n, NULL); break;
case Oarr: r = rval(s, n, NULL); break;
- case Ogap: r = temp(s, n); break;
-
- /* not actually expressible as lvalues in syntax, but we generate them */
- case Oudata: r = rval(s, n, NULL); break;
- case Outag: r = rval(s, n, NULL); break;
- case Otupget: r = rval(s, n, NULL); break;
default:
fatal(n, "%s cannot be an lvalue", opstr[exprop(n)]);
break;
@@ -840,17 +837,11 @@ simpucon(Simp *s, Node *n, Node *dst)
Node *r;
Type *ty;
Ucon *uc;
- size_t i, o;
+ size_t o;
/* find the ucon we're constructing here */
- ty = tybase(n->expr.type);
- uc = NULL;
- for (i = 0; i < ty->nmemb; i++) {
- if (!strcmp(namestr(n->expr.args[0]), namestr(ty->udecls[i]->name))) {
- uc = ty->udecls[i];
- break;
- }
- }
+ ty = tybase(exprtype(n));
+ uc = finducon(ty, n->expr.args[0]);
if (!uc)
die("Couldn't find union constructor");
@@ -859,6 +850,13 @@ simpucon(Simp *s, Node *n, Node *dst)
else
tmp = temp(s, n);
+ if (isenum(ty)) {
+ /* enums are treated as integers
+ * by the backend */
+ append(s, set(tmp, n));
+ return tmp;
+ }
+
/* Set the tag on the ucon */
u = addr(s, tmp, mktype(n->loc, Tyuint));
tag = mkintlit(n->loc, uc->id);