shithub: mc

Download patch

ref: 3065ee64d255b9eca94efd48269cd291960d6c4e
parent: 6e422cdf9d119e0fb96626ef7f7e39611d6655b4
author: Ori Bernstein <[email protected]>
date: Tue Jun 5 20:12:28 EDT 2012

Make simple, zero-arg function calls work.

--- a/8/asm.h
+++ b/8/asm.h
@@ -76,9 +76,11 @@
     size_t nn;
 };
 
-void genasm(Func *fn, Htab *globls);
+/* entry points */
+void genasm(FILE *fd, Func *fn, Htab *globls);
 void gen(Node *file, char *out);
 
+/* location generation */
 Loc *loclbl(Loc *l, Node *lbl);
 Loc *locreg(Loc *l, Reg r);
 Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode);
@@ -85,3 +87,5 @@
 Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode);
 Loc *loclit(Loc *l, long val);
 
+/* useful functions */
+size_t size(Node *n);
--- a/8/insns.def
+++ b/8/insns.def
@@ -43,6 +43,7 @@
 Insn(Isetge,      "\tsetge\n",                  0)
 
 /* branch instructions */
+Insn(Icall,     "\tcall %v\n",                  0)
 Insn(Ijmp,      "\tjmp %v\n",                   0)
 Insn(Ijz,       "\tjz %v\n",                    0)
 Insn(Ijnz,      "\tjnz %v\n",                   0)
--- a/8/isel.c
+++ b/8/isel.c
@@ -92,16 +92,20 @@
 /* forward decls */
 Loc selexpr(Isel *s, Node *n);
 
-
-Loc *loclbl(Loc *l, Node *lbl)
+Loc *locstrlbl(Loc *l, char *lbl)
 {
-    assert(lbl->type = Nlbl);
     l->type = Loclbl;
     l->mode = ModeL;
-    l->lbl = strdup(lbl->lbl.name);
+    l->lbl = strdup(lbl);
     return l;
 }
 
+Loc *loclbl(Loc *l, Node *lbl)
+{
+    assert(lbl->type = Nlbl);
+    return locstrlbl(l, lbl->lbl.name);
+}
+
 Loc *locreg(Loc *l, Reg r)
 {
     l->type = Locreg;
@@ -150,7 +154,7 @@
                 stkoff = (size_t)htget(s->locs, (void*)n->expr.did);
                 locmem(&l, stkoff, Resp, Rnone, ModeL);
             } else if (hthas(s->globls, (void*)n->expr.did)) {
-                loclbl(&l, htget(s->globls, (void*)n->expr.did));
+                locstrlbl(&l, htget(s->globls, (void*)n->expr.did));
             } else {
                 die("%s (id=%ld) not found", namestr(n->expr.args[0]), n->expr.did);
             }
@@ -423,6 +427,45 @@
     return l;
 }
 
+Loc gencall(Isel *s, Node *n)
+{
+    int argsz;
+    int i;
+    Loc eax, esp;       /* hard-coded registers */
+    Loc stkbump;        /* calculated stack offset */
+    Loc dst, arg, fn;   /* values we reduced */
+
+    locreg(&esp, Resp);
+    locreg(&eax, Reax);
+    argsz = 0;
+    /* Have to calculate the amount to bump the stack
+     * pointer by in one pass first, otherwise if we push
+     * one at a time, we evaluate the args in reverse order.
+     * Not good.
+     *
+     * We skip the first operand, since it's the function itself */
+    for (i = 1; i < n->expr.nargs; i++)
+        argsz += size(n->expr.args[i]);
+    loclit(&stkbump, argsz);
+    if (argsz)
+        g(s, Isub, &stkbump, &esp, NULL);
+
+    /* Now, we can evaluate the arguments */
+    argsz = 0;
+    for (i = 1; i < n->expr.nargs; i++) {
+        argsz += size(n->expr.args[i]);
+        arg = selexpr(s, n->expr.args[i]);
+        arg = inri(s, arg);
+        locmem(&dst, argsz, Resp, Rnone, arg.mode);
+        stor(s, &arg, &dst);
+    }
+    fn = selexpr(s, n->expr.args[0]);
+    g(s, Icall, &fn, NULL);
+    if (argsz)
+        g(s, Iadd, &stkbump, &esp, NULL);
+    return eax;
+}
+
 Loc selexpr(Isel *s, Node *n)
 {
     Loc a, b, c, r;
@@ -489,7 +532,9 @@
             g(s, Imov, &b, &r, NULL);
             break;
 
-        case Ocall: die("Unimplemented op %s", opstr(exprop(n))); break;
+        case Ocall:
+            r = gencall(s, n);
+            break;
         case Ocast: die("Unimplemented op %s", opstr(exprop(n))); break;
         case Ojmp:
             g(s, Ijmp, loclbl(&a, args[0]), NULL);
@@ -675,11 +720,10 @@
 /* genasm requires all nodes in 'nl' to map cleanly to operations that are
  * natively supported, as promised in the output of reduce().  No 64-bit
  * operations on x32, no structures, and so on. */
-void genasm(Func *fn, Htab *globls)
+void genasm(FILE *fd, Func *fn, Htab *globls)
 {
     struct Isel is = {0,};
     int i;
-    FILE *fd;
 
     is.locs = fn->locs;
     is.globls = globls;
@@ -695,7 +739,5 @@
     if (debug)
       writeasm(fn, &is, stdout);
 
-    fd = fopen("a.s", "w");
     writeasm(fn, &is, fd);
-    fclose(fd);
 }
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -522,7 +522,7 @@
     append(s, s->endlbl);
 }
 
-static void lowerfn(char *name, Node *n, Htab *globls)
+static void lowerfn(char *name, Node *n, Htab *globls, FILE *fd)
 {
     int i;
     Simp s = {0,};
@@ -547,7 +547,7 @@
     fn.ret = s.ret;
     fn.nl = s.stmts;
     fn.nn = s.nstmts;
-    genasm(&fn, globls);
+    genasm(fd, &fn, globls);
 }
 
 void blobdump(Blob *b, FILE *fd)
@@ -566,11 +566,12 @@
 
 void gen(Node *file, char *out)
 {
+    FILE *fd;
     Node **n;
     int nn, i;
-    Sym *s;
     char *name;
     Htab *globls;
+    Sym *s;
 
     n = file->file.stmts;
     nn = file->file.nstmts;
@@ -581,6 +582,9 @@
         if (n[i]->type == Ndecl)
             htput(globls, (void*)n[i]->decl.sym->id, asmname(n[i]->decl.sym->name));
 
+    fd = fopen(out, "w");
+    if (!fd)
+        die("Couldn't open fd %s", out);
     for (i = 0; i < nn; i++) {
         switch (n[i]->type) {
             case Nuse: /* nothing to do */ 
@@ -589,7 +593,7 @@
                 s = n[i]->decl.sym;
                 name = asmname(s->name);
                 if (isconstfn(s)) {
-                    lowerfn(name, n[i]->decl.init, globls);
+                    lowerfn(name, n[i]->decl.init, globls, fd);
                     free(name);
                 } else {
                     die("We don't lower globls yet...");
@@ -600,4 +604,6 @@
                 break;
         }
     }
+    if (fd)
+        fclose(fd);
 }
--- a/parse/util.c
+++ b/parse/util.c
@@ -80,8 +80,9 @@
 {
     char *ret;
 
-    ret = xalloc(len);
+    ret = xalloc(len + 1);
     memcpy(ret, s, len);
+    ret[len] = '\0';
     return ret;
 }
 
--- a/test/build.sh
+++ b/test/build.sh
@@ -15,6 +15,7 @@
 build struct_oneval
 build struct
 build array
+build call
 build fib
 
 exit 0
--- a/test/test.sh
+++ b/test/test.sh
@@ -23,4 +23,5 @@
 returns struct_oneval 12
 returns struct 42
 returns array 7
+returns call 42
 returns fib 8