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
+}