summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-28 10:30:55 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-28 14:57:20 -0400
commit1b4943eb1f2a10837f56070bfe604179d0dc10e0 (patch)
treebc44762647100f8c666e20328acd4e328fe8f93e
parent54d734f6a4f3e13e906e8edb8ce3e10caa4bec25 (diff)
downloadroux-1b4943eb1f2a10837f56070bfe604179d0dc10e0.tar.gz
implement export control
-rw-r--r--minic/minic.y2
-rw-r--r--src/all.h2
-rw-r--r--src/emit.c15
-rw-r--r--src/parse.c40
-rw-r--r--test/abi1.ssa1
-rw-r--r--test/abi2.ssa1
-rw-r--r--test/abi3.ssa1
-rw-r--r--test/abi4.ssa1
-rw-r--r--test/abi5.ssa1
-rw-r--r--test/align.ssa1
-rw-r--r--test/collatz.ssa1
-rw-r--r--test/cprime.ssa1
-rw-r--r--test/cup.ssa1
-rw-r--r--test/dark.ssa1
-rw-r--r--test/double.ssa1
-rw-r--r--test/echo.ssa1
-rw-r--r--test/eucl.ssa1
-rw-r--r--test/euclc.ssa1
-rw-r--r--test/fpcnv.ssa2
-rw-r--r--test/loop.ssa1
-rw-r--r--test/mandel.ssa1
-rw-r--r--test/max.ssa1
-rw-r--r--test/prime.ssa1
-rw-r--r--test/puts10.ssa1
-rw-r--r--test/sum.ssa1
-rwxr-xr-xtools/abifuzz.sh2
-rw-r--r--tools/callgen.ml4
27 files changed, 65 insertions, 22 deletions
diff --git a/minic/minic.y b/minic/minic.y
index 8cb4079..51debca 100644
--- a/minic/minic.y
+++ b/minic/minic.y
@@ -707,7 +707,7 @@ prot: IDENT '(' par0 ')'
 	int t, m;
 
 	varadd($1->u.v, 1, FUNC(INT));
-	fprintf(of, "function w $%s(", $1->u.v);
+	fprintf(of, "export function w $%s(", $1->u.v);
 	n = $3;
 	if (n)
 		for (;;) {
diff --git a/src/all.h b/src/all.h
index 03661ad..40c80f6 100644
--- a/src/all.h
+++ b/src/all.h
@@ -426,6 +426,7 @@ struct Fn {
 	Blk **rpo;
 	bits reg;
 	int slot;
+	char export;
 	char name[NString];
 };
 
@@ -466,6 +467,7 @@ struct Dat {
 	} u;
 	char isref;
 	char isstr;
+	char export;
 };
 
 
diff --git a/src/emit.c b/src/emit.c
index df96afd..9b2975d 100644
--- a/src/emit.c
+++ b/src/emit.c
@@ -497,13 +497,14 @@ emitfn(Fn *fn, FILE *f)
 	Ins *i, itmp;
 	int *r, c, fs;
 
+	fprintf(f, ".text\n");
+	if (fn->export)
+		fprintf(f, ".globl %s%s\n", symprefix, fn->name);
 	fprintf(f,
-		".text\n"
-		".globl %s%s\n"
 		"%s%s:\n"
 		"\tpush %%rbp\n"
 		"\tmov %%rsp, %%rbp\n",
-		symprefix, fn->name, symprefix, fn->name
+		symprefix, fn->name
 	);
 	fs = framesz(fn);
 	if (fs)
@@ -575,11 +576,9 @@ emitdat(Dat *d, FILE *f)
 	case DName:
 		if (!align)
 			fprintf(f, ".align 8\n");
-		fprintf(f,
-			".globl %s%s\n"
-			"%s%s:\n",
-			symprefix, d->u.str, symprefix, d->u.str
-		);
+		if (d->export)
+			fprintf(f, ".globl %s%s\n", symprefix, d->u.str);
+		fprintf(f, "%s%s:\n", symprefix, d->u.str);
 		break;
 	case DZ:
 		fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num);
diff --git a/src/parse.c b/src/parse.c
index 903e909..2590971 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -97,6 +97,7 @@ enum {
 	TJmp,
 	TJnz,
 	TRet,
+	TExport,
 	TFunc,
 	TType,
 	TData,
@@ -184,6 +185,7 @@ lex()
 		{ "jmp", TJmp },
 		{ "jnz", TJnz },
 		{ "ret", TRet },
+		{ "export", TExport },
 		{ "function", TFunc },
 		{ "type", TType },
 		{ "data", TData },
@@ -648,7 +650,7 @@ DoOp:
 }
 
 static Fn *
-parsefn()
+parsefn(int export)
 {
 	PState ps;
 	Fn *fn;
@@ -663,6 +665,7 @@ parsefn()
 	bmap = vnew(nblk, sizeof bmap[0]);
 	con[0].type = CBits;
 	fn = alloc(sizeof *fn);
+	fn->export = export;
 	blink = &fn->start;
 	fn->retty = -1;
 	if (peek() != TGlo)
@@ -809,7 +812,7 @@ parsedatstr(Dat *d)
 }
 
 static void
-parsedat(void cb(Dat *))
+parsedat(void cb(Dat *), int export)
 {
 	char s[NString];
 	int t;
@@ -818,6 +821,7 @@ parsedat(void cb(Dat *))
 	d.type = DStart;
 	d.isstr = 0;
 	d.isref = 0;
+	d.export = export;
 	cb(&d);
 	if (nextnl() != TGlo || nextnl() != TEq)
 		err("data name, then = expected");
@@ -882,28 +886,40 @@ Done:
 void
 parse(FILE *f, char *path, void data(Dat *), void func(Fn *))
 {
+	int t, export;
+
 	inf = f;
 	inpath = path;
 	lnum = 1;
 	thead = TXXX;
 	ntyp = 0;
-	for (;;)
+	for (;;) {
+		export = 0;
 		switch (nextnl()) {
+		default:
+			err("top-level definition expected");
+		case TExport:
+			export = 1;
+			t = nextnl();
+			if (t == TFunc) {
 		case TFunc:
-			func(parsefn());
-			break;
+				func(parsefn(export));
+				break;
+			}
+			else if (t == TData) {
+		case TData:
+				parsedat(data, export);
+				break;
+			}
+			else
+				err("export can only qualify data and function");
 		case TType:
 			parsetyp();
 			break;
-		case TData:
-			parsedat(data);
-			break;
 		case TEOF:
 			return;
-		default:
-			err("top-level definition expected");
-			break;
 		}
+	}
 }
 
 static void
@@ -1009,6 +1025,8 @@ printfn(Fn *fn, FILE *f)
 	Ins *i;
 	uint n;
 
+	if (fn->export)
+		fprintf(f, "export ");
 	fprintf(f, "function $%s() {\n", fn->name);
 	for (b=fn->start; b; b=b->link) {
 		fprintf(f, "@%s\n", b->name);
diff --git a/test/abi1.ssa b/test/abi1.ssa
index 69cce44..049f10e 100644
--- a/test/abi1.ssa
+++ b/test/abi1.ssa
@@ -20,6 +20,7 @@ function $alpha(l %p, w %l, l %n) {
 	ret
 }
 
+export
 function $test() {
 @start
 	%p =l alloc4 17
diff --git a/test/abi2.ssa b/test/abi2.ssa
index b82c80c..42a3bae 100644
--- a/test/abi2.ssa
+++ b/test/abi2.ssa
@@ -1,5 +1,6 @@
 type :fps = { s, b, s }
 
+export
 function s $sum(:fps %p) {
 @start
 	%f1 =s load %p
diff --git a/test/abi3.ssa b/test/abi3.ssa
index 608d1db..35cade8 100644
--- a/test/abi3.ssa
+++ b/test/abi3.ssa
@@ -2,6 +2,7 @@ type :four = {l, b, w}
 
 data $z = { w 0 }
 
+export
 function $test() {
  @start
 	%a  =w loadw $z
diff --git a/test/abi4.ssa b/test/abi4.ssa
index 4c3d89b..844d985 100644
--- a/test/abi4.ssa
+++ b/test/abi4.ssa
@@ -18,6 +18,7 @@ function $alpha(l %p, w %l, l %n) {
 	ret
 }
 
+export
 function :mem $test() {
 @start
 	%p =l alloc4 17
diff --git a/test/abi5.ssa b/test/abi5.ssa
index 4c5eaea..7899035 100644
--- a/test/abi5.ssa
+++ b/test/abi5.ssa
@@ -18,6 +18,7 @@ data $fmt6 = { b "t6: %s\n", b 0 }
 data $fmt7 = { b "t7: %f %f\n", b 0 }
 data $fmt8 = { b "t8: %d %d %d %d\n", b 0 }
 
+export
 function $test() {
 @start
 	%r1 =:st1 call $t1()
diff --git a/test/align.ssa b/test/align.ssa
index 84d1fb9..49f1183 100644
--- a/test/align.ssa
+++ b/test/align.ssa
@@ -1,3 +1,4 @@
+export
 function $test() {
 @start
 	%x =l alloc16 16
diff --git a/test/collatz.ssa b/test/collatz.ssa
index 373ecac..0a593b1 100644
--- a/test/collatz.ssa
+++ b/test/collatz.ssa
@@ -3,6 +3,7 @@
 # we use a fast local array to
 # memoize small collatz numbers
 
+export
 function $test() {
 @start
 	%mem =l alloc4 4000
diff --git a/test/cprime.ssa b/test/cprime.ssa
index 1ca60e1..8fadef3 100644
--- a/test/cprime.ssa
+++ b/test/cprime.ssa
@@ -2,6 +2,7 @@
 # compiler from the C program
 # following in comments
 
+export
 function w $main() {
 @start
 	%v0 =l alloc8 4
diff --git a/test/cup.ssa b/test/cup.ssa
index 013394f..b53c86e 100644
--- a/test/cup.ssa
+++ b/test/cup.ssa
@@ -1,5 +1,6 @@
 # counts up from -1988 to 1991
 
+export
 function $test() {
 @start
 @loop
diff --git a/test/dark.ssa b/test/dark.ssa
index 5046af3..373b1b1 100644
--- a/test/dark.ssa
+++ b/test/dark.ssa
@@ -6,6 +6,7 @@ type :magic = align 1 { 0 }
 
 data $ret = { l 0 }
 
+export
 function $test(:magic %p) {
 @start
 	%av =w loadw $a
diff --git a/test/double.ssa b/test/double.ssa
index d885d28..ac6c4c5 100644
--- a/test/double.ssa
+++ b/test/double.ssa
@@ -1,3 +1,4 @@
+export
 function $test() {
 @start
 	%x1 =d copy d_0.1
diff --git a/test/echo.ssa b/test/echo.ssa
index d3c8a25..6671a6a 100644
--- a/test/echo.ssa
+++ b/test/echo.ssa
@@ -1,3 +1,4 @@
+export
 function w $main(w %argc, l %argv) {
 @start
 	%fmt =l alloc8 8
diff --git a/test/eucl.ssa b/test/eucl.ssa
index f50fd2c..838c1b8 100644
--- a/test/eucl.ssa
+++ b/test/eucl.ssa
@@ -3,6 +3,7 @@
 # ssa program because of the
 # swap of b and a
 
+export
 function $test() {
 @start
 
diff --git a/test/euclc.ssa b/test/euclc.ssa
index c76db2f..3449234 100644
--- a/test/euclc.ssa
+++ b/test/euclc.ssa
@@ -1,3 +1,4 @@
+export
 function w $test() {
 @l0
 	%a =l alloc4 4
diff --git a/test/fpcnv.ssa b/test/fpcnv.ssa
index 5fd3be9..06d2478 100644
--- a/test/fpcnv.ssa
+++ b/test/fpcnv.ssa
@@ -1,5 +1,6 @@
 # floating point casts and conversions
 
+export
 function s $fneg(s %f) {
 @fneg
 	%b0 =w cast %f
@@ -8,6 +9,7 @@ function s $fneg(s %f) {
 	ret %rs
 }
 
+export
 function d $ftrunc(d %f) {
 @ftrunc
 	%l0 =l ftosi %f
diff --git a/test/loop.ssa b/test/loop.ssa
index c8c4ee0..98914d9 100644
--- a/test/loop.ssa
+++ b/test/loop.ssa
@@ -1,6 +1,7 @@
 # simple looping program
 # sums all integers from 100 to 0
 
+export
 function $test() {
 @start
 
diff --git a/test/mandel.ssa b/test/mandel.ssa
index efefeb3..67d960a 100644
--- a/test/mandel.ssa
+++ b/test/mandel.ssa
@@ -29,6 +29,7 @@ function w $mandel(d %x, d %y) {
 	ret 0
 }
 
+export
 function w $main() {
 @main
 @loopy
diff --git a/test/max.ssa b/test/max.ssa
index 547e9d4..27fa8ca 100644
--- a/test/max.ssa
+++ b/test/max.ssa
@@ -6,6 +6,7 @@
 
 data $arr = { b 10, b -60, b 10, b 100, b 200, b 0 }
 
+export
 function $test() {
 @start
 @loop
diff --git a/test/prime.ssa b/test/prime.ssa
index 12d0273..2273e1d 100644
--- a/test/prime.ssa
+++ b/test/prime.ssa
@@ -1,6 +1,7 @@
 # find the 10,001st prime
 # store it in a
 
+export
 function $test() {
 @start
 @loop
diff --git a/test/puts10.ssa b/test/puts10.ssa
index 1dcf227..8c6ed5e 100644
--- a/test/puts10.ssa
+++ b/test/puts10.ssa
@@ -1,3 +1,4 @@
+export
 function $main() {
 @start
 	%y  =l alloc4 4
diff --git a/test/sum.ssa b/test/sum.ssa
index 266054e..08ba8c0 100644
--- a/test/sum.ssa
+++ b/test/sum.ssa
@@ -1,5 +1,6 @@
 # Simple test for addressing modes.
 
+export
 function w $sum(l %arr, w %num) {
 @start
 @loop
diff --git a/tools/abifuzz.sh b/tools/abifuzz.sh
index ef1f26a..57930fb 100755
--- a/tools/abifuzz.sh
+++ b/tools/abifuzz.sh
@@ -63,6 +63,8 @@ while test -n "$1"
 do
 	case "$1" in
 	"-callssa")
+		CALLER=c
+		CALLEE=ssa
 		;;
 	"-callc")
 		CALLER=ssa
diff --git a/tools/callgen.ml b/tools/callgen.ml
index 9a5976c..4679865 100644
--- a/tools/callgen.ml
+++ b/tools/callgen.ml
@@ -439,7 +439,7 @@ module OutIL = struct
       typedef oc (argname i) arg;
     ) args;
     typedef oc "ret" ret;
-    fprintf oc "\nfunction w $main() {\n";
+    fprintf oc "\nexport function w $main() {\n";
     fprintf oc "@start\n";
     fprintf oc "\t%%failcode =l alloc4 4\n";
     let targs = List.mapi (fun i arg ->
@@ -466,7 +466,7 @@ module OutIL = struct
       typedef oc (argname i) arg;
     ) args;
     typedef oc "ret" ret;
-    fprintf oc "\nfunction %s $f(" (ttype "ret" ret);
+    fprintf oc "\nexport function %s $f(" (ttype "ret" ret);
     List.iteri (fun i arg ->
       let a = argname i in
       fprintf oc "%s %%%s" (ttype a arg) a;