shithub: mc

Download patch

ref: 5d32b4d66a0065bec228c9bbd61835e11718827c
parent: 4b2947c3f828c6895ab15eb83814321d112d3c1a
parent: 8e1b91f8c81e73d60294cbb2f90449c38343d878
author: Ori Bernstein <[email protected]>
date: Tue Jun 19 17:10:36 EDT 2012

Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc2

--- a/8/asm.h
+++ b/8/asm.h
@@ -187,6 +187,7 @@
 
 
 /* useful functions */
+size_t tysize(Type *t);
 size_t size(Node *n);
 void breakhere();
 void dumpasm(Isel *s, FILE *fd);
--- a/8/isel.c
+++ b/8/isel.c
@@ -323,13 +323,41 @@
     return l;
 }
 
-static Loc *gencall(Isel *s, Node *n)
+static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz)
 {
-    int argsz, argoff;
     size_t i;
+    Loc *sp, *dp; /* pointers to src, dst */
+    Loc *tmp, *src, *dst; /* source memory, dst memory */
+
+    sp = inr(s, from);
+    dp = inr(s, to);
+
+    /* Slightly funny loop condition: We might have trailing bytes
+     * that we can't blit word-wise. */
+    tmp = locreg(ModeL);
+    for (i = 0; i < sz/4; i++) {
+        src = locmem(i*4 + srcoff, sp, NULL, ModeL);
+        dst = locmem(i*4 + dstoff, dp, NULL, ModeL);
+        g(s, Imov, src, tmp, NULL);
+        g(s, Imov, tmp, dst, NULL);
+    }
+    /* now, the trailing bytes */
+    tmp = locreg(ModeB);
+    for (; i < sz%4; i++) {
+        src = locmem(i, sp, NULL, ModeB);
+        dst = locmem(i, dp, NULL, ModeB);
+        g(s, Imov, src, tmp, NULL);
+        g(s, Imov, tmp, dst, NULL);
+    }
+}
+
+static Loc *gencall(Isel *s, Node *n)
+{
+    Loc *src, *dst, *arg, *fn;   /* values we reduced */
     Loc *eax, *esp;       /* hard-coded registers */
     Loc *stkbump;        /* calculated stack offset */
-    Loc *dst, *arg, *fn;   /* values we reduced */
+    int argsz, argoff;
+    size_t i;
 
     esp = locphysreg(Resp);
     eax = locphysreg(Reax);
@@ -350,9 +378,16 @@
     argoff = 0;
     for (i = 1; i < n->expr.nargs; i++) {
         arg = selexpr(s, n->expr.args[i]);
-        arg = inri(s, arg);
-        dst = locmem(argoff, esp, NULL, arg->mode);
-        stor(s, arg, dst);
+        if (size(n->expr.args[i]) > 4) {
+            dst = locreg(ModeL);
+            src = locreg(ModeL);
+            g(s, Ilea, arg, src, NULL);
+            blit(s, esp, src, argoff, 0, size(n->expr.args[i]));
+        } else {
+            dst = locmem(argoff, esp, NULL, arg->mode);
+            arg = inri(s, arg);
+            stor(s, arg, dst);
+        }
         argoff += size(n->expr.args[i]);
     }
     fn = selexpr(s, n->expr.args[0]);
@@ -362,34 +397,6 @@
     return eax;
 }
 
-static void blit(Isel *s, Loc *a, Loc *b, int sz)
-{
-    int i;
-    Loc *sp, *dp; /* pointers to src, dst */
-    Loc *tmp, *src, *dst; /* source memory, dst memory */
-
-    sp = inr(s, a);
-    dp = inr(s, b);
-
-    /* Slightly funny loop condition: We might have trailing bytes
-     * that we can't blit word-wise. */
-    tmp = locreg(ModeL);
-    for (i = 0; i < sz/4; i++) {
-        src = locmem(i, sp, NULL, ModeL);
-        dst = locmem(i, dp, NULL, ModeL);
-        g(s, Imov, src, tmp, NULL);
-        g(s, Imov, tmp, dst, NULL);
-    }
-    /* now, the trailing bytes */
-    tmp = locreg(ModeB);
-    for (; i < sz%4; i++) {
-        src = locmem(i, sp, NULL, ModeB);
-        dst = locmem(i, dp, NULL, ModeB);
-        g(s, Imov, src, tmp, NULL);
-        g(s, Imov, tmp, dst, NULL);
-    }
-}
-
 Loc *selexpr(Isel *s, Node *n)
 {
     Loc *a, *b, *c, *d, *r;
@@ -538,9 +545,9 @@
             r = loclbl(args[0]);
             break;
         case Oblit:
-            b = selexpr(s, args[0]);
-            a = selexpr(s, args[1]);
-            blit(s, a, b, args[2]->expr.args[0]->lit.intval);
+            a = selexpr(s, args[0]);
+            b = selexpr(s, args[1]);
+            blit(s, a, b, 0, 0, args[2]->expr.args[0]->lit.intval);
             r = b;
             break;
 
@@ -727,7 +734,7 @@
     return as;
 }
 
-void writeblob(FILE *fd, char *p, size_t sz)
+static void writeblob(FILE *fd, char *p, size_t sz)
 {
     size_t i;
 
@@ -743,7 +750,7 @@
     }
 }
 
-void writelit(FILE *fd, Node *v)
+static void writelit(FILE *fd, Node *v)
 {
     char lbl[128];
     switch (v->lit.littype) {
@@ -814,4 +821,3 @@
         writeasm(stdout, &is, fn);
     writeasm(fd, &is, fn);
 }
-
--- a/8/main.c
+++ b/8/main.c
@@ -16,6 +16,7 @@
 /* FIXME: move into one place...? */
 Node *file;
 int debug;
+int asmonly;
 char *outfile;
 char **incpaths;
 size_t nincpaths;
@@ -27,29 +28,62 @@
     printf("\t-I path\tAdd 'path' to use search path\n");
     printf("\t-d\tPrint debug dumps\n");
     printf("\t-o\tOutput to outfile\n");
+    printf("\t-S\tGenerate assembly instead of object code\n");
 }
 
+char *outfmt(char *buf, size_t sz, char *infile, char *outfile)
+{
+    char *p, *suffix;
+    size_t len;
+
+    if (outfile) {
+        snprintf(buf, sz, "%s", outfile);
+        return buf;
+    }
+
+    if (asmonly)
+        suffix = ".s";
+    else
+        suffix = ".o";
+
+    p = strrchr(infile, '.');
+    if (p)
+        len = (p - infile);
+    else
+        len = strlen(infile);
+    if (len + strlen(suffix) >= sz)
+        die("Output file name too long");
+    strncpy(buf, infile, len);
+    strcat(buf, suffix);
+
+    return buf;
+}
+
 int main(int argc, char **argv)
 {
     int opt;
     int i;
     Stab *globls;
+    char buf[1024];
 
-    while ((opt = getopt(argc, argv, "dho:I:")) != -1) {
+    while ((opt = getopt(argc, argv, "dhSo:I:")) != -1) {
         switch (opt) {
             case 'o':
                 outfile = optarg;
                 break;
             case 'h':
-		usage(argv[0]);
-		exit(0);
-		break;
+                usage(argv[0]);
+                exit(0);
+                break;
             case 'd':
                 debug++;
                 break;
-	    case 'I':
-		lappend(&incpaths, &nincpaths, optarg);
-		break;
+            case 'S':
+                asmonly++;
+                break;
+            case 'I':
+                lappend(&incpaths, &nincpaths, optarg);
+                break;
             default:
                 usage(argv[0]);
                 exit(0);
@@ -73,7 +107,8 @@
         /* after all processing */
         if (debug)
             dump(file, stdout);
-        gen(file, "a.s");
+
+        gen(file, outfmt(buf, 1024, argv[i], outfile));
     }
 
     return 0;
--- a/8/platform.h
+++ b/8/platform.h
@@ -1,5 +1,9 @@
 #if defined(__APPLE__) && defined(__MACH__)
-#define Fprefix "_"
+/* for OSX */
+#   define Assembler "as -arch i386 -g -o %s -"
+#   define Fprefix "_"
 #else
-#define Fprefix ""
+/* Default to linux */
+#   define Assembler "as --32 -g -o %s -"
+#   define Fprefix ""
 #endif
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -56,14 +56,15 @@
 static Node *zero;
 static Node *ptrsz;
 static Type *tyword;
+static Type *tyvoid;
 
-Type *base(Type *t)
+static Type *base(Type *t)
 {
     assert(t->nsub == 1);
     return t->sub[0];
 }
 
-Node *add(Node *a, Node *b)
+static Node *add(Node *a, Node *b)
 {
     Node *n;
 
@@ -72,7 +73,7 @@
     return n;
 }
 
-Node *sub(Node *a, Node *b)
+static Node *sub(Node *a, Node *b)
 {
     Node *n;
 
@@ -81,7 +82,7 @@
     return n;
 }
 
-Node *mul(Node *a, Node *b)
+static Node *mul(Node *a, Node *b)
 {
     Node *n;
 
@@ -90,7 +91,7 @@
     return n;
 }
 
-Node *addr(Node *a, Type *bt)
+static Node *addr(Node *a, Type *bt)
 {
     Node *n;
 
@@ -102,7 +103,7 @@
     return n;
 }
 
-Node *load(Node *a)
+static Node *load(Node *a)
 {
     Node *n;
 
@@ -112,7 +113,7 @@
     return n;
 }
 
-Node *store(Node *a, Node *b)
+static Node *store(Node *a, Node *b)
 {
     Node *n;
 
@@ -121,7 +122,7 @@
     return n;
 }
 
-Node *word(int line, uint v)
+static Node *word(int line, uint v)
 {
     Node *n;
     n = mkintlit(line, v);
@@ -528,11 +529,27 @@
     return r;
 }
 
+static Node *visit(Simp *s, Node *n)
+{
+    size_t i;
+    Node *r;
+
+    for (i = 0; i < n->expr.nargs; i++)
+        n->expr.args[i] = rval(s, n->expr.args[i]);
+    if (ispure(n)) {
+        r = n;
+    } else {
+        r = temp(s, n);
+        append(s, store(r, n));
+    }
+    return r;
+}
+
 static Node *rval(Simp *s, Node *n)
 {
     Node *r; /* expression result */
     Node *t, *u, *v; /* temporary nodes */
-    size_t i;
+    Type *ty;
     Node **args;
     const Op fusedmap[] = {
         [Oaddeq]        = Oadd,
@@ -658,21 +675,25 @@
             if (size(n) > 4) {
                 t = addr(t, exprtype(n));
                 u = addr(u, exprtype(n));
-		v = word(n->line, size(n));
+                v = word(n->line, size(n));
                 r = mkexpr(n->line, Oblit, t, u, v, NULL);
             } else {
               r = store(t, u);
             }
             break;
-        default:
-            for (i = 0; i < n->expr.nargs; i++)
-                n->expr.args[i] = rval(s, n->expr.args[i]);
-            if (ispure(n)) {
-                r = n;
-            } else {
+        case Ocall:
+            if (size(n) > 4) {
                 r = temp(s, n);
-                append(s, store(r, n));
+                ty = mktyptr(n->line, exprtype(r));
+                linsert(&args[0]->expr.args, &n->expr.nargs, 1, addr(r, ty));
+                linsert(&args[0]->expr.type->sub, &n->expr.type->nsub, 1, ty);
+                args[0]->expr.type->sub[0] = tyvoid;
+                n->expr.type = tyvoid;
             }
+            r = visit(s, n);
+            break;
+        default:
+            r = visit(s, n);
     }
     return r;
 }
@@ -726,7 +747,7 @@
             r = n;
             break;
         case Ndecl:
-	    declarelocal(s, n);
+            declarelocal(s, n);
             if (n->decl.init) {
                 t = mkexpr(n->line, Ovar, n->decl.name, NULL);
                 u = mkexpr(n->line, Oasn, t, n->decl.init, NULL);
@@ -789,18 +810,18 @@
         for (i = 0; i < s->nstmts; i++)
             dump(s->stmts[i], stdout);
     for (i = 0; i < s->nstmts; i++) {
-	if (s->stmts[i]->type != Nexpr)
-	    continue;
-	if (debug) {
-	    printf("FOLD FROM ----------\n");
-	    dump(s->stmts[i], stdout);
-	}
-	s->stmts[i] = fold(s->stmts[i]);
-	if (debug) {
-	    printf("FOLD TO ------------\n");
-	    dump(s->stmts[i], stdout);
-	    printf("END ----------------\n");
-	}
+        if (s->stmts[i]->type != Nexpr)
+            continue;
+        if (debug) {
+            printf("FOLD FROM ----------\n");
+            dump(s->stmts[i], stdout);
+        }
+        s->stmts[i] = fold(s->stmts[i]);
+        if (debug) {
+            printf("FOLD TO ------------\n");
+            dump(s->stmts[i], stdout);
+            printf("END ----------------\n");
+        }
     }
     cfg = mkcfg(s->stmts, s->nstmts);
     if (debug)
@@ -816,7 +837,7 @@
     return fn;
 }
 
-void fillglobls(Stab *st, Htab *globls)
+static void fillglobls(Stab *st, Htab *globls)
 {
     void **k;
     size_t i, nk;
@@ -838,7 +859,7 @@
     free(k);
 }
 
-void lowerdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
+static void lowerdcl(Node *dcl, Htab *globls, Func ***fn, size_t *nfn, Node ***blob, size_t *nblob)
 {
     Simp s = {0,};
     char *name;
@@ -874,9 +895,11 @@
     size_t nn, nfn, nblob;
     size_t i;
     FILE *fd;
+    char cmd[1024];
 
     /* declare useful constants */
     tyword = mkty(-1, Tyint);
+    tyword = mkty(-1, Tyvoid);
     one = word(-1, 1);
     zero = word(-1, 0);
     ptrsz = word(-1, 4);
@@ -892,9 +915,6 @@
     /* We need to define all global variables before use */
     fillglobls(file->file.globls, globls);
 
-    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 */ 
@@ -908,9 +928,21 @@
         }
     }
 
+    sprintf(cmd, Assembler, out);
+    if (asmonly)
+      fd = fopen(out, "w");
+    else
+      fd = popen(cmd, "w");
+    if (!fd)
+        die("Couldn't open fd %s", out);
+
     for (i = 0; i < nblob; i++)
         genblob(fd, blob[i], globls);
     for (i = 0; i < nfn; i++)
         genasm(fd, fn[i], globls);
-    fclose(fd);
+    fflush(fd);
+    if (asmonly)
+      fclose(fd);
+    else
+      pclose(fd);
 }
--- a/opt/fold.c
+++ b/opt/fold.c
@@ -13,7 +13,7 @@
 #include "parse.h"
 #include "opt.h"
 
-int islit(Node *n, vlong *v)
+static int islit(Node *n, vlong *v)
 {
     Node *l;
 
@@ -26,7 +26,7 @@
     return 1;
 }
 
-int isval(Node *n, vlong val)
+static int isval(Node *n, vlong val)
 {
     vlong v;
 
@@ -35,7 +35,7 @@
     return v == val;
 }
 
-Node *val(int line, vlong val)
+static Node *val(int line, vlong val)
 {
     Node *n;
 
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -254,7 +254,7 @@
     settype(n, ft->sub[0]);
 }
 
-void checkns(Node *n, Node **ret)
+static void checkns(Node *n, Node **ret)
 {
     Node *var, *name, *nsname;
     Node **args;
@@ -587,6 +587,7 @@
     Node *memb;
     Node *n;
     Node **nl;
+    Type *t;
     int found;
 
     for (i = 0; i < npostcheck; i++) {
@@ -599,7 +600,8 @@
         memb = postcheck[i]->expr.args[1];
 
         found = 0;
-        if (type(aggr)->type == Tyslice || type(aggr)->type == Tyarray) {
+        t = tf(type(aggr));
+        if (t->type == Tyslice || t->type == Tyarray) {
             if (!strcmp(namestr(memb), "len")) {
                 constrain(type(n), cstrtab[Tcnum]);
                 constrain(type(n), cstrtab[Tcint]);
@@ -607,7 +609,9 @@
                 found = 1;
             }
         } else {
-            nl = aggrmemb(aggr->expr.type, &nn);
+            if (t->type == Typtr)
+                t = tf(t->sub[0]);
+            nl = aggrmemb(t, &nn);
             for (j = 0; j < nn; j++) {
                 if (!strcmp(namestr(memb), declname(nl[j]))) {
                     unify(n, type(n), decltype(nl[j]));
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -361,6 +361,7 @@
 
 /* convenience funcs */
 void lappend(void *l, size_t *len, void *n); /* ugly hack; nl is void* because void*** is incompatible with T*** */
+void linsert(void *l, size_t *len, size_t idx, void *n);
 void *lpop(void *l, size_t *len);
 void ldel(void *l, size_t *len, size_t idx);
 void lfree(void *l, size_t *len);
@@ -379,6 +380,9 @@
 void be32(long v, byte buf[4]);
 long host32(byte buf[4]);
 
+void wrbuf(FILE *fd, void *buf, size_t sz);
+void rdbuf(FILE *fd, void *buf, size_t sz);
+char rdbyte(FILE *fd);
 void wrbyte(FILE *fd, char val);
 char rdbyte(FILE *fd);
 void wrint(FILE *fd, long val);
@@ -392,6 +396,7 @@
 
 /* Options to control the compilation */
 extern int debug;
+extern int asmonly;
 extern char *outfile;
 extern char **incpaths;
 extern size_t nincpaths;
--- a/parse/use.c
+++ b/parse/use.c
@@ -11,7 +11,7 @@
 
 #include "parse.h"
 
-int loaduse(FILE *f, Stab *st)
+static int loaduse(FILE *f, Stab *st)
 {
     char *pkg;
     Stab *s;
--- a/parse/util.c
+++ b/parse/util.c
@@ -129,6 +129,20 @@
     return v;
 }
 
+void linsert(void *p, size_t *len, size_t idx, void *v)
+{
+    void ***pl, **l;
+    size_t i;
+
+    pl = p;
+    *pl = xrealloc(*pl, (*len + 1)*sizeof(void*));
+    l = *pl;
+    for (i = idx; i < *len; i++)
+        l[i + 1] = l[i];
+    l[idx] = v;
+    (*len)++;
+}
+
 void ldel(void *l, size_t *len, size_t idx)
 {
     void ***pl;
--- /dev/null
+++ b/test/callbig.myr
@@ -1,0 +1,15 @@
+type pair = struct
+	a : int
+	b : int
+;;
+
+const f = {s
+	-> s.a  + s.b
+}
+
+const main = {
+	var s : pair
+	s.a = 12
+	s.b = 30
+	-> f(s)
+}
--- /dev/null
+++ b/test/structret.myr
@@ -1,0 +1,19 @@
+type pair = struct
+	a : int
+	b : int
+;;
+
+const f = {
+	var s
+
+	s.a = 12
+	s.b = 30
+	-> s
+}
+
+const main = {
+	var s : pair
+
+	s = f()
+	-> s.a + s.b
+}
--- a/test/test.sh
+++ b/test/test.sh
@@ -2,7 +2,7 @@
 export PATH=.:$PATH
 export MC=../8/8m
 export MU=../util/muse
-export ASOPT="-g"
+export CC=cc
 
 function use {
     rm -f $1
@@ -14,8 +14,7 @@
     rm -f $1
     echo $MC $1.myr && \
     $MC $1.myr && \
-    mv a.s $1.s && \
-    cc $ASOPT -m32 -o $1 $1.s
+    $CC -g -m32 -o $1 $1.o
 }
 
 function prints {
--- a/test/tests
+++ b/test/tests
@@ -21,14 +21,17 @@
 B bsr     	E       5
 B struct1	E	12
 B struct	E	42
+B structasn	E       42
+B structret	E	42
 B array		E	7
 B arraylen	E	12
 B call		E	42
+B voidcall	E	12
+B callbig	E	42
 B loop		E	45
 B fib		E	21
 B slice		E	7
 B float   	E       1
-B structasn	E       42
 B log-and 	E       0
 B log-or  	E       1
 B str   	E       102
--- /dev/null
+++ b/test/voidcall.myr
@@ -1,0 +1,10 @@
+const f = {
+	var a
+
+	a = a + 1
+}
+
+const main = {
+	f()
+	-> 12
+}