summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-26 23:47:46 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-26 23:47:46 -0700
commitc74b0bc06994e9a4921131696a5714cf83642acc (patch)
tree415b1001ccfc44b55c7fa4d8a2d130ee38907ee2 /6
parentbb4ff654b3f0ce2e067e707f83310af5ebc50679 (diff)
downloadmc-c74b0bc06994e9a4921131696a5714cf83642acc.tar.gz
Separate out the concepts of code and func ptrs.
In order to pass around functions with environments for closures, we need to refer to the type of a function pointer, as well as the type of code. This is ugly. When I rewrite the backend I should change it.
Diffstat (limited to '6')
-rw-r--r--6/asm.h3
-rw-r--r--6/gen.c18
-rw-r--r--6/gengas.c1
-rw-r--r--6/isel.c11
-rw-r--r--6/main.c2
-rw-r--r--6/simp.c54
-rw-r--r--6/typeinfo.c8
7 files changed, 60 insertions, 37 deletions
diff --git a/6/asm.h b/6/asm.h
index 6fdf6aa..4c411a9 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -267,6 +267,7 @@ extern Loc **locmap; /* mapping from reg id => Loc * */
char *genlocallblstr(char *buf, size_t sz);
char *genlblstr(char *buf, size_t sz);
+Type *codetype(Type *ft);
Node *genlbl(Srcloc loc);
Loc *loclbl(Node *lbl);
Loc *locstrlbl(char *lbl);
@@ -303,8 +304,6 @@ size_t tyalign(Type *t);
size_t size(Node *n);
ssize_t tyoffset(Type *ty, Node *memb);
ssize_t offset(Node *aggr, Node *memb);
-int stacktype(Type *t);
-int floattype(Type *t);
int stacknode(Node *n);
int floatnode(Node *n);
void breakhere();
diff --git a/6/gen.c b/6/gen.c
index 19cd863..d50f746 100644
--- a/6/gen.c
+++ b/6/gen.c
@@ -25,6 +25,8 @@ void fillglobls(Stab *st, Htab *globls)
k = htkeys(st->dcl, &nk);
for (i = 0; i < nk; i++) {
s = htget(st->dcl, k[i]);
+ if (isconstfn(s))
+ s->decl.type = codetype(s->decl.type);
htput(globls, s, asmname(s));
}
free(k);
@@ -42,6 +44,18 @@ void fillglobls(Stab *st, Htab *globls)
free(ns);
}
+Type *codetype(Type *ft)
+{
+ ft = tybase(ft);
+ if (ft->type == Tycode)
+ return ft;
+ assert(ft->type == Tyfunc);
+ ft = tydup(ft);
+ ft->type = Tycode;
+ return ft;
+}
+
+
static int islocal(Node *dcl)
{
if (dcl->decl.vis != Visintern)
@@ -70,6 +84,7 @@ char *genlblstr(char *buf, size_t sz)
int isconstfn(Node *n)
{
Node *d;
+ Type *t;
if (n->type == Nexpr) {
if (exprop(n) != Ovar)
@@ -78,8 +93,9 @@ int isconstfn(Node *n)
} else {
d = n;
}
+ t = tybase(decltype(d));
if (d && d->decl.isconst && d->decl.isglobl)
- return tybase(decltype(d))->type == Tyfunc;
+ return t->type == Tyfunc || t->type == Tycode;
return 0;
}
diff --git a/6/gengas.c b/6/gengas.c
index 71f0bf7..9526dd6 100644
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -51,6 +51,7 @@ static void initconsts(Htab *globls)
tyvoid = mktype(Zloc, Tyvoid);
ty = mktyfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid));
+ ty->type = Tycode;
name = mknsname(Zloc, "_rt", "abort_oob");
dcl = mkdecl(Zloc, name, ty);
dcl->decl.isconst = 1;
diff --git a/6/isel.c b/6/isel.c
index b7a5ebb..928ec9d 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -68,7 +68,7 @@ static Mode tymode(Type *t)
case Tyflt32: return ModeF; break;
case Tyflt64: return ModeD; break;
default:
- if (stacktype(t))
+ if (isstacktype(t))
return ModeQ;
switch (tysize(t)) {
case 1: return ModeB; break;
@@ -485,6 +485,7 @@ static void call(Isel *s, Node *n)
if (isconstfn(n)) {
op = Icall;
+ assert(tybase(exprtype(n))->type == Tycode);
f = locmeml(htget(s->globls, n), NULL, NULL, mode(n));
} else {
op = Icallind;
@@ -499,7 +500,7 @@ static size_t countargs(Type *t)
t = tybase(t);
nargs = t->nsub - 1;
- if (stacktype(t->sub[0]))
+ if (isstacktype(t->sub[0]))
nargs++;
/* valists are replaced with hidden type parameter,
* which we want on the stack for ease of ABI */
@@ -521,10 +522,10 @@ static Loc *gencall(Isel *s, Node *n)
rsp = locphysreg(Rrsp);
t = exprtype(n);
- if (tybase(t)->type == Tyvoid || stacktype(t)) {
+ if (tybase(t)->type == Tyvoid || isstacktype(t)) {
retloc = NULL;
ret = NULL;
- } else if (floattype(t)) {
+ } else if (istyfloat(t)) {
retloc = coreg(Rxmm0d, mode(n));
ret = locreg(mode(n));
} else {
@@ -981,7 +982,7 @@ static void epilogue(Isel *s)
rbp = locphysreg(Rrbp);
if (s->ret) {
ret = loc(s, s->ret);
- if (floattype(exprtype(s->ret)))
+ if (istyfloat(exprtype(s->ret)))
g(s, Imovs, ret, coreg(Rxmm0d, ret->mode), NULL);
else
g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
diff --git a/6/main.c b/6/main.c
index ff829c2..1aa1c95 100644
--- a/6/main.c
+++ b/6/main.c
@@ -237,9 +237,9 @@ int main(int argc, char **argv)
} else {
gentemp(buf, sizeof buf, ctx.args[i], ".s");
}
+ genuse(ctx.args[i]);
gen(file, buf);
assemble(buf, ctx.args[i]);
- genuse(ctx.args[i]);
}
return 0;
diff --git a/6/simp.c b/6/simp.c
index 5021494..c9911d6 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -171,33 +171,20 @@ static int addressable(Simp *s, Node *a)
return stacknode(a);
}
-int stacktype(Type *t)
-{
- /* the types are arranged in types.def such that this is true */
- t = tybase(t);
- return t->type >= Tyslice;
-}
-
-int floattype(Type *t)
-{
- t = tybase(t);
- return t->type == Tyflt32 || t->type == Tyflt64;
-}
-
int stacknode(Node *n)
{
if (n->type == Nexpr)
- return stacktype(n->expr.type);
+ return isstacktype(n->expr.type);
else
- return stacktype(n->decl.type);
+ return isstacktype(n->decl.type);
}
int floatnode(Node *n)
{
if (n->type == Nexpr)
- return floattype(n->expr.type);
+ return istyfloat(n->expr.type);
else
- return floattype(n->decl.type);
+ return istyfloat(n->decl.type);
}
static void forcelocal(Simp *s, Node *n)
@@ -226,7 +213,7 @@ static Node *addr(Simp *s, Node *a, Type *bt)
n = mkexpr(a->loc, Oaddr, a, NULL);
if (!addressable(s, a))
- forcelocal(s, a);
+ forcelocal(s, a);
if (!bt)
n->expr.type = mktyptr(a->loc, a->expr.type);
else
@@ -557,6 +544,7 @@ static void matchpattern(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, N
/* Never supported */
case Tyvoid: case Tybad: case Tyvalist: case Tyvar:
case Typaram: case Tyunres: case Tyname: case Ntypes:
+ case Tyfunc: case Tycode:
die("Unsupported type for pattern");
break;
/* only valid for string literals */
@@ -565,7 +553,7 @@ static void matchpattern(Simp *s, Node *pat, Node *val, Type *t, Node *iftrue, N
case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint:
case Tyint64: case Tyuint64:
case Tyflt32: case Tyflt64:
- case Typtr: case Tyfunc:
+ case Typtr:
v = mkexpr(pat->loc, Oeq, pat, val, NULL);
v->expr.type = mktype(pat->loc, Tybool);
cjmp(s, v, iftrue, iffalse);
@@ -925,7 +913,6 @@ static Node *simpcast(Simp *s, Node *val, Type *to)
case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
case Tyuint: case Tychar: case Tybyte:
case Typtr:
- case Tyfunc:
r = intconvert(s, val, to, 0);
break;
case Tyflt32: case Tyflt64:
@@ -1157,7 +1144,7 @@ static Node *simpucon(Simp *s, Node *n, Node *dst)
return tmp;
elt = rval(s, n->expr.args[1], NULL);
u = addk(u, Wordsz);
- if (stacktype(uc->etype)) {
+ if (isstacktype(uc->etype)) {
elt = addr(s, elt, uc->etype);
sz = disp(n->loc, tysize(uc->etype));
r = mkexpr(n->loc, Oblit, u, elt, sz, NULL);
@@ -1341,6 +1328,21 @@ static Node *capture(Simp *s, Node *n, Node *dst)
return f;
}
+static Node *getcode(Simp *s, Node *n)
+{
+ Node *r, *d;
+
+ if (isconstfn(n)) {
+ d = decls[n->expr.did];
+ r = mkexpr(n->loc, Ovar, n->expr.args[0], NULL);
+ r->expr.did = d->decl.did;
+ r->expr.type = codetype(exprtype(n));
+ } else {
+ r = rval(s, n, NULL);
+ }
+ return r;
+}
+
static Node *simpcall(Simp *s, Node *n, Node *dst)
{
size_t i, nargs;
@@ -1351,16 +1353,16 @@ static Node *simpcall(Simp *s, Node *n, Node *dst)
ft = tybase(exprtype(n->expr.args[0]));
if (exprtype(n)->type == Tyvoid)
r = NULL;
- else if (stacktype(exprtype(n)) && dst)
+ else if (isstacktype(exprtype(n)) && dst)
r = dst;
else
r = temp(s, n);
args = NULL;
nargs = 0;
- lappend(&args, &nargs, rval(s, n->expr.args[0], NULL));
+ lappend(&args, &nargs, getcode(s, n->expr.args[0]));
- if (exprtype(n)->type != Tyvoid && stacktype(exprtype(n)))
+ if (exprtype(n)->type != Tyvoid && isstacktype(exprtype(n)))
lappend(&args, &nargs, addr(s, r, exprtype(n)));
for (i = 1; i < n->expr.nargs; i++) {
@@ -1379,7 +1381,7 @@ static Node *simpcall(Simp *s, Node *n, Node *dst)
call = mkexprl(n->loc, Ocall, args, nargs);
call->expr.type = exprtype(n);
- if (r && !stacktype(exprtype(n))) {
+ if (r && !isstacktype(exprtype(n))) {
append(s, set(r, call));
} else {
append(s, call);
@@ -1704,7 +1706,7 @@ static void flatten(Simp *s, Node *f)
/* make a temp for the return type */
ty = f->func.type->sub[0];
- if (stacktype(ty)) {
+ if (isstacktype(ty)) {
s->isbigret = 1;
s->ret = gentemp(s, f->loc, mktyptr(f->loc, ty), &dcl);
declarearg(s, dcl);
diff --git a/6/typeinfo.c b/6/typeinfo.c
index 8af84bf..2a241f7 100644
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -119,7 +119,7 @@ Blob *tydescsub(Type *ty)
lappend(&sub, &nsub, bt);
switch (ty->type) {
case Ntypes: case Tyvar: case Tybad: case Typaram:
- case Tygeneric: case Tyunres:
+ case Tygeneric: case Tycode: case Tyunres:
die("invalid type in tydesc"); break;
/* atomic types -- nothing else to do */
@@ -246,7 +246,7 @@ size_t tysize(Type *t)
case Tychar: /* utf32 */
return 4;
- case Typtr: case Tyfunc:
+ case Typtr:
case Tyvalist: /* ptr to first element of valist */
return Ptrsz;
@@ -260,6 +260,10 @@ size_t tysize(Type *t)
case Tyflt64:
return 8;
+ case Tyfunc:
+ return Ptrsz;
+ case Tycode:
+ return Ptrsz;
case Tyslice:
return 2*Ptrsz; /* len; ptr */
case Tyname: