diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-05-09 16:49:09 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-05-09 16:49:09 -0700 |
commit | ed8711e68e441e9884d734932373317834665833 (patch) | |
tree | 08a3f37550af1b6adb1ad912ee6df70fa6c1ceaf | |
parent | bd5fb6d0628831cde25f13e3fe461786d616a06e (diff) | |
download | mc-ed8711e68e441e9884d734932373317834665833.tar.gz |
Refactor code to add jump tables, and prepare to generate them.
-rw-r--r-- | 6/gen.c | 16 | ||||
-rw-r--r-- | 6/gengas.c | 5 | ||||
-rw-r--r-- | 6/genp9.c | 16 | ||||
-rw-r--r-- | 6/isel.c | 12 | ||||
-rw-r--r-- | 6/locs.c | 8 | ||||
-rw-r--r-- | 6/main.c | 4 | ||||
-rw-r--r-- | 6/simp.c | 30 | ||||
-rw-r--r-- | mi/Makefile | 1 | ||||
-rw-r--r-- | mi/match.c | 19 | ||||
-rw-r--r-- | mi/mi.h | 4 | ||||
-rw-r--r-- | parse/dump.c | 7 | ||||
-rw-r--r-- | parse/infer.c | 1 | ||||
-rw-r--r-- | parse/lits.def | 1 | ||||
-rw-r--r-- | parse/node.c | 3 | ||||
-rw-r--r-- | parse/parse.h | 9 | ||||
-rw-r--r-- | parse/specialize.c | 23 | ||||
-rw-r--r-- | parse/use.c | 16 |
17 files changed, 101 insertions, 74 deletions
@@ -24,22 +24,6 @@ static int islocal(Node *dcl) return 1; } -static int nextlbl; -char *genlocallblstr(char *buf, size_t sz) -{ - if (asmsyntax == Plan9) - snprintf(buf, 128, ".L%d<>", nextlbl++); - else - snprintf(buf, 128, ".L%d", nextlbl++); - return buf; -} - -char *genlblstr(char *buf, size_t sz) -{ - snprintf(buf, 128, ".L%d", nextlbl++); - return buf; -} - /* * For x86, the assembly names are generated as follows: * local symbols: .name @@ -298,7 +298,7 @@ static size_t writelit(FILE *fd, Htab *strtab, Node *v, Type *ty) if (hthas(strtab, &v->lit.strval)) { lbl = htget(strtab, &v->lit.strval); } else { - lbl = genlocallblstr(buf, sizeof buf); + lbl = genlblstr(buf, sizeof buf); htput(strtab, &v->lit.strval, strdup(lbl)); } fprintf(fd, "\t.quad %s\n", lbl); @@ -307,6 +307,9 @@ static size_t writelit(FILE *fd, Htab *strtab, Node *v, Type *ty) case Lfunc: die("Generating this shit ain't ready yet "); break; + case Ljtab: + die("jtab as data?"); + break; case Llbl: die("Can't generate literal labels, ffs. They're not data."); break; @@ -265,7 +265,7 @@ static size_t writebytes(FILE *fd, char *name, size_t off, char *p, size_t sz) static size_t writelit(FILE *fd, char *name, size_t off, Htab *strtab, Node *v, Type *ty) { char buf[128]; - char *lbl; + char *lbl, *local; size_t sz; union { float fv; @@ -299,14 +299,17 @@ static size_t writelit(FILE *fd, char *name, size_t off, Htab *strtab, Node *v, if (hthas(strtab, &v->lit.strval)) { lbl = htget(strtab, &v->lit.strval); } else { - lbl = genlocallblstr(buf, sizeof buf); + lbl = genlblstr(buf, sizeof buf); htput(strtab, &v->lit.strval, strdup(lbl)); } + local = ""; + if (*name == '.') + local = "<>"; if (v->lit.strval.len > 0) - fprintf(fd, "DATA %s+%zd(SB)/8,$%s+0(SB)\n", name, off, lbl); + fprintf(fd, "DATA %s%s+%zd(SB)/8,$%s+0(SB)\n", name, local, off, lbl); else - fprintf(fd, "DATA %s+%zd(SB)/8,$0\n", name, off); - fprintf(fd, "DATA %s+%zd(SB)/8,$%zd\n", name, off+8, v->lit.strval.len); + fprintf(fd, "DATA %s%s+%zd(SB)/8,$0\n", name, local, off); + fprintf(fd, "DATA %s%s+%zd(SB)/8,$%zd\n", name, local, off+8, v->lit.strval.len); break; case Lfunc: die("Generating this shit ain't ready yet "); @@ -314,6 +317,9 @@ static size_t writelit(FILE *fd, char *name, size_t off, Htab *strtab, Node *v, case Llbl: die("Can't generate literal labels, ffs. They're not data."); break; + case Ljtab: + die("jump table in data section?"); + break; } return sz; } @@ -524,6 +524,12 @@ static Loc *gencall(Isel *s, Node *n) return ret; } +void seljtab(Isel *s, Node *n, Node **args) +{ + dump(n, stdout); + die("jtab not yet implemented"); +} + Loc *selexpr(Isel *s, Node *n) { Loc *a, *b, *c, *d, *r; @@ -711,9 +717,9 @@ Loc *selexpr(Isel *s, Node *n) case Ocjmp: selcjmp(s, n, args); break; - case Ojtab: - die("jump tables not yet implemented\n"); - break; + case Ojtab: + seljtab(s, n, args); + break; case Olit: /* fall through */ r = loc(s, n); break; @@ -31,14 +31,6 @@ int isfloatmode(Mode m) return m == ModeF || m == ModeD; } -Node *genlbl(Srcloc loc) -{ - char buf[128]; - - genlblstr(buf, 128); - return mklbl(loc, buf); -} - Loc *locstrlbl(char *lbl) { Loc *l; @@ -98,7 +98,7 @@ static void assemble(char *asmsrc, char *path) } } -static char *gentemp(char *buf, size_t bufsz, char *path, char *suffix) +static char *tempfile(char *buf, size_t bufsz, char *path, char *suffix) { char *tmpdir; char *base; @@ -219,7 +219,7 @@ int main(int argc, char **argv) else swapsuffix(buf, sizeof buf, ctx.args[i], ".myr", ".s"); } else { - gentemp(buf, sizeof buf, ctx.args[i], ".s"); + tempfile(buf, sizeof buf, ctx.args[i], ".s"); } gen(file, buf); assemble(buf, ctx.args[i]); @@ -295,29 +295,12 @@ static Node *word(Srcloc loc, uint v) return n; } -static Node *gentemp(Simp *simp, Node *e, Type *ty, Node **dcl) -{ - char buf[128]; - static int nexttmp; - Node *t, *r, *n; - - snprintf(buf, 128, ".t%d", nexttmp++); - n = mkname(e->loc, buf); - t = mkdecl(e->loc, n, ty); - r = mkexpr(e->loc, Ovar, n, NULL); - r->expr.type = t->decl.type; - r->expr.did = t->decl.did; - if (dcl) - *dcl = t; - return r; -} - -static Node *temp(Simp *simp, Node *e) +Node *temp(Simp *simp, Node *e) { Node *t, *dcl; assert(e->type == Nexpr); - t = gentemp(simp, e, e->expr.type, &dcl); + t = gentemp(e, e->expr.type, &dcl); if (stacknode(e)) declarelocal(simp, dcl); return t; @@ -472,7 +455,7 @@ static void simpiter(Simp *s, Node *n) zero->expr.type = tyintptr; seq = rval(s, n->iterstmt.seq, NULL); - idx = gentemp(s, n, tyintptr, &dcl); + idx = gentemp(n, tyintptr, &dcl); declarelocal(s, dcl); /* setup */ @@ -1450,6 +1433,9 @@ static Node *rval(Simp *s, Node *n, Node *dst) case Lfunc: r = simpblob(s, n, &file->file.stmts, &file->file.nstmts); break; + case Ljtab: + die("jump table as lit"); + break; } break; case Ovar: @@ -1643,11 +1629,11 @@ static void flatten(Simp *s, Node *f) ty = f->func.type->sub[0]; if (stacktype(ty)) { s->isbigret = 1; - s->ret = gentemp(s, f, mktyptr(f->loc, ty), &dcl); + s->ret = gentemp(f, mktyptr(f->loc, ty), &dcl); declarearg(s, dcl); } else if (ty->type != Tyvoid) { s->isbigret = 0; - s->ret = gentemp(s, f, ty, &dcl); + s->ret = gentemp(f, ty, &dcl); } for (i = 0; i < f->func.nargs; i++) { diff --git a/mi/Makefile b/mi/Makefile index 3a7cd1b..0351fe3 100644 --- a/mi/Makefile +++ b/mi/Makefile @@ -2,6 +2,7 @@ LIB=libmi.a OBJ=cfg.o \ dfcheck.o \ fold.o \ + genloc.o \ match.o \ reaching.o \ @@ -16,11 +16,12 @@ typedef struct Dtree Dtree; struct Dtree { /* If the values are equal, go to 'sub'. If 'val' is null, anything matches. */ + Node *load; /* expression value being compared */ + Node *patexpr; /* the full pattern for this node */ Node **val; /* pattern values to compare against */ size_t nval; - Node **load; /* expression value being compared */ - size_t nload; + Dtree **sub; /* submatch to use if if equal */ size_t nsub; Dtree *any; /* tree for a wildcard match. */ @@ -227,6 +228,11 @@ static Dtree *addpat(Dtree *t, Node *pat, Node *val, Node ***cap, size_t *ncap) case Ostruct: ret = addstruct(t, pat, val, cap, ncap); break; + /* FIXME: address patterns. + * match ptr + * | &123: if ptr# == 123 + case Oaddr: + **/ default: ret = NULL; fatal(pat, "unsupported pattern %s of type %s", opstr[exprop(pat)], tystr(exprtype(pat))); @@ -298,11 +304,17 @@ static int exhaustivematch(Node *m, Dtree *t, Type *tt) return 1; } -static Node *genmatch(Dtree *dt) +static Node *mkjtab(Dtree *dt, Node *load) { return NULL; } +static Node *genmatch(Dtree *dt) +{ + dtdump(dt, stdout); + return mkjtab(dt, dt->load); +} + Node *gensimpmatch(Node *m) { Dtree *t, *leaf; @@ -357,6 +369,7 @@ void dtdumpnode(Dtree *dt, FILE *f, int depth, int iswild) { Node *e; size_t i; + dump(dt->load, stdout); if (dt->patexpr) { e = dt->patexpr; indentf(depth, "%s%s %s : %s\n", iswild ? "WILDCARD " : "", opstr[exprop(e)], dtnodestr(e), tystr(exprtype(e))); @@ -38,6 +38,10 @@ struct Reaching { /* expression folding */ Node *fold(Node *n, int foldvar); +/* node creation */ +Node *genlbl(Srcloc loc); +Node *gentemp(Node *e, Type *ty, Node **dcl); + /* dataflow analysis */ Reaching *reaching(Cfg *cfg); Node *assignee(Node *n); diff --git a/parse/dump.c b/parse/dump.c index 43b5d31..97622a2 100644 --- a/parse/dump.c +++ b/parse/dump.c @@ -206,6 +206,13 @@ static void outnode(Node *n, FILE *fd, int depth) case Lflt: fprintf(fd, " Lflt %lf\n", n->lit.fltval); break; case Lstr: fprintf(fd, " Lstr %.*s\n", (int)n->lit.strval.len, n->lit.strval.buf); break; case Llbl: fprintf(fd, " Llbl %s\n", n->lit.lblval); break; + case Ljtab: + fprintf(fd, "Ljtab\n"); + for (i = 0; i < n->lit.jtab->nval; i++) { + outnode(n->lit.jtab->val[i], fd, depth+1); + outnode(n->lit.jtab->dst[i], fd, depth+1); + } + break; case Lfunc: fprintf(fd, " Lfunc\n"); outnode(n->lit.fnval, fd, depth+1); diff --git a/parse/infer.c b/parse/infer.c index 937f116..3161a7c 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -528,6 +528,7 @@ static Type *littype(Node *n) case Lstr: t = mktyslice(n->loc, mktype(n->loc, Tybyte)); break; case Llbl: t = mktyptr(n->loc, mktype(n->loc, Tyvoid)); break; case Lfunc: t = n->lit.fnval->func.type; break; + case Ljtab: t = mktype(n->loc, Tyvoid); break; } n->lit.type = t; } diff --git a/parse/lits.def b/parse/lits.def index 2e5342f..9dd2c18 100644 --- a/parse/lits.def +++ b/parse/lits.def @@ -5,3 +5,4 @@ L(Lflt) L(Lstr) L(Lfunc) L(Llbl) +L(Ljtab) diff --git a/parse/node.c b/parse/node.c index ba3cd3c..f33e9ca 100644 --- a/parse/node.c +++ b/parse/node.c @@ -405,6 +405,9 @@ int liteq(Node *a, Node *b) case Llbl: return !strcmp(a->lit.lblval, b->lit.lblval); break; + case Ljtab: + return 0; + break; } return 0; } diff --git a/parse/parse.h b/parse/parse.h index fa7b99e..6070744 100644 --- a/parse/parse.h +++ b/parse/parse.h @@ -23,6 +23,7 @@ typedef struct Tok Tok; typedef struct Node Node; typedef struct Ucon Ucon; typedef struct Stab Stab; +typedef struct Jtab Jtab; typedef struct Type Type; typedef struct Trait Trait; @@ -174,6 +175,13 @@ struct Type { char isreflect; /* Tyname: whether this type has reflection info */ }; +struct Jtab { + Node **val; + size_t nval; + Node **dst; + size_t ndst; +}; + struct Ucon { Srcloc loc; size_t id; /* unique id */ @@ -248,6 +256,7 @@ struct Node { char *lblval; int boolval; Node *fnval; + Jtab *jtab; }; } lit; diff --git a/parse/specialize.c b/parse/specialize.c index 6cf5aa9..f7315e2 100644 --- a/parse/specialize.c +++ b/parse/specialize.c @@ -177,10 +177,18 @@ static void fixup(Node *n) break; case Nlit: switch (n->lit.littype) { - case Lfunc: fixup(n->lit.fnval); break; case Lchr: case Lint: case Lflt: case Lstr: case Llbl: case Lbool: break; + case Lfunc: + fixup(n->lit.fnval); + break; + case Ljtab: + for (i = 0; i < n->lit.jtab->nval; i++) { + fixup(n->lit.jtab->val[i]); + fixup(n->lit.jtab->dst[i]); + } + break; } break; case Nifstmt: @@ -271,12 +279,13 @@ static Node *specializenode(Node *n, Htab *tsmap) r->lit.littype = n->lit.littype; r->lit.type = tysubst(n->expr.type, tsmap); switch (n->lit.littype) { - case Lchr: r->lit.chrval = n->lit.chrval; break; - case Lint: r->lit.intval = n->lit.intval; break; - case Lflt: r->lit.fltval = n->lit.fltval; break; - case Lstr: r->lit.strval = n->lit.strval; break; - case Llbl: r->lit.lblval = n->lit.lblval; break; - case Lbool: r->lit.boolval = n->lit.boolval; break; + case Ljtab: die("jtab in frontend?"); break; + case Lchr: r->lit.chrval = n->lit.chrval; break; + case Lint: r->lit.intval = n->lit.intval; break; + case Lflt: r->lit.fltval = n->lit.fltval; break; + case Lstr: r->lit.strval = n->lit.strval; break; + case Llbl: r->lit.lblval = n->lit.lblval; break; + case Lbool: r->lit.boolval = n->lit.boolval; break; case Lfunc: r->lit.fnval = specializenode(n->lit.fnval, tsmap); break; } break; diff --git a/parse/use.c b/parse/use.c index 546a3cf..e7e2f6b 100644 --- a/parse/use.c +++ b/parse/use.c @@ -484,6 +484,7 @@ static void pickle(FILE *fd, Node *n) case Llbl: wrstr(fd, n->lit.lblval); break; case Lbool: wrbool(fd, n->lit.boolval); break; case Lfunc: pickle(fd, n->lit.fnval); break; + case Ljtab: die("jtab in frontend?"); break; } break; case Nloopstmt: @@ -608,13 +609,14 @@ static Node *unpickle(FILE *fd) rdtype(fd, &n->lit.type); n->lit.nelt = rdint(fd); switch (n->lit.littype) { - case Lchr: n->lit.chrval = rdint(fd); break; - case Lint: n->lit.intval = rdint(fd); break; - case Lflt: n->lit.fltval = rdflt(fd); break; - case Lstr: rdstrbuf(fd, &n->lit.strval); break; - case Llbl: n->lit.lblval = rdstr(fd); break; - case Lbool: n->lit.boolval = rdbool(fd); break; - case Lfunc: n->lit.fnval = unpickle(fd); break; + case Lchr: n->lit.chrval = rdint(fd); break; + case Lint: n->lit.intval = rdint(fd); break; + case Lflt: n->lit.fltval = rdflt(fd); break; + case Lstr: rdstrbuf(fd, &n->lit.strval); break; + case Llbl: n->lit.lblval = rdstr(fd); break; + case Lbool: n->lit.boolval = rdbool(fd); break; + case Lfunc: n->lit.fnval = unpickle(fd); break; + case Ljtab: die("jtab in frontend?"); break; } break; case Nloopstmt: |