summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-27 22:52:17 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-27 22:52:17 -0700
commitc8c4b88ecadf05438561c05f97500e35843218c4 (patch)
tree950afbb15a71d129fdf5bab862ebe8d17eaeac59 /6
parentac306beff772b0a894ca95e0e0d0fe3029c7f8e4 (diff)
downloadmc-c8c4b88ecadf05438561c05f97500e35843218c4.tar.gz
Don't index directly off of %rax.
We use it for function returns. We also use it for environment of called closures. This means we clobbered it. Oops.
Diffstat (limited to '6')
-rw-r--r--6/asm.h7
-rw-r--r--6/gengas.c2
-rw-r--r--6/genp9.c2
-rw-r--r--6/isel.c4
-rw-r--r--6/simp.c8
5 files changed, 19 insertions, 4 deletions
diff --git a/6/asm.h b/6/asm.h
index 811b2b5..dde50a6 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -130,7 +130,6 @@ struct Insn {
struct Func {
char *name; /* function name */
- int isexport; /* is this exported from the asm? */
Type *type; /* type of function */
Node **args; /* argument list */
@@ -140,7 +139,9 @@ struct Func {
size_t stksz; /* stack size */
Node *ret; /* return value */
- Cfg *cfg; /* flow graph */
+ Cfg *cfg; /* flow graph */
+ char isexport; /* is this exported from the asm? */
+ char hasenv; /* do we have an environment? */
};
struct Asmbb {
@@ -173,6 +174,8 @@ struct Isel {
Htab *envoff; /* decl id => int envoff */
Htab *globls; /* decl id => char *globlname */
+ Loc *envp;
+
/* increased when we spill */
Loc *stksz;
Loc *calleesave[Nreg];
diff --git a/6/gengas.c b/6/gengas.c
index 9526dd6..08a2b04 100644
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -351,6 +351,8 @@ static void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
is.globls = globls;
is.ret = fn->ret;
is.cfg = fn->cfg;
+ if (fn->hasenv)
+ is.envp = locreg(ModeQ);
selfunc(&is, fn, globls, strtab);
if (debugopt['i'])
diff --git a/6/genp9.c b/6/genp9.c
index 1d23777..b138cd8 100644
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -371,6 +371,8 @@ static void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
is.globls = globls;
is.ret = fn->ret;
is.cfg = fn->cfg;
+ if (fn->hasenv)
+ is.envp = locreg(ModeQ);
selfunc(&is, fn, globls, strtab);
if (debugopt['i'])
diff --git a/6/isel.c b/6/isel.c
index 0d8637c..7eee71c 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -104,7 +104,7 @@ static Loc *varloc(Isel *s, Node *n)
l = locmeml(htget(s->globls, n), rip, NULL, mode(n));
} else if (hthas(s->envoff, n)) {
off = ptoi(htget(s->envoff, n));
- l = locmem(off, locphysreg(Rrax), NULL, mode(n));
+ l = locmem(off, s->envp, NULL, mode(n));
} else if (hthas(s->stkoff, n)) {
off = ptoi(htget(s->stkoff, n));
l = locmem(-off, locphysreg(Rrbp), NULL, mode(n));
@@ -980,6 +980,8 @@ static void prologue(Isel *s, Func *fn, size_t sz)
g(s, Imov, phys, s->calleesave[i], NULL);
}
}
+ if (s->envp)
+ g(s, Imov, locphysreg(Rrax), s->envp, NULL);
addarglocs(s, fn);
s->nsaved = i;
s->stksz = stksz; /* need to update if we spill */
diff --git a/6/simp.c b/6/simp.c
index dd24384..d4dd168 100644
--- a/6/simp.c
+++ b/6/simp.c
@@ -32,7 +32,8 @@ struct Simp {
/* return handling */
Node *endlbl;
Node *ret;
- int isbigret;
+ int hasenv;
+ int isbigret;
/* pre/postinc handling */
Node **incqueue;
@@ -1821,11 +1822,14 @@ static void collectenv(Simp *s, Node *fn)
size_t off;
env = getclosure(fn->func.scope, &nenv);
+ if (!env)
+ return;
/*
we need these in a deterministic order so that we can
put them in the right place both when we use them and
when we capture them.
*/
+ s->hasenv = 1;
qsort(env, nenv, sizeof(Node*), envcmp);
off = Ptrsz; /* we start with the size of the env */
for (i = 0; i < nenv; i++) {
@@ -1888,6 +1892,7 @@ static Func *simpfn(Simp *s, char *name, Node *dcl)
fn->args = s->args;
fn->nargs = s->nargs;
fn->cfg = cfg;
+ fn->hasenv = s->hasenv;
return fn;
}
@@ -1964,6 +1969,7 @@ void simpglobl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, s
s.globls = globls;
s.blobs = *blob;
s.nblobs = *nblob;
+ s.hasenv = 0;
name = asmname(dcl);
if (dcl->decl.isextern || dcl->decl.isgeneric)