From 1b4943eb1f2a10837f56070bfe604179d0dc10e0 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Mon, 28 Mar 2016 10:30:55 -0400 Subject: implement export control --- minic/minic.y | 2 +- src/all.h | 2 ++ src/emit.c | 15 +++++++-------- src/parse.c | 40 +++++++++++++++++++++++++++++----------- test/abi1.ssa | 1 + test/abi2.ssa | 1 + test/abi3.ssa | 1 + test/abi4.ssa | 1 + test/abi5.ssa | 1 + test/align.ssa | 1 + test/collatz.ssa | 1 + test/cprime.ssa | 1 + test/cup.ssa | 1 + test/dark.ssa | 1 + test/double.ssa | 1 + test/echo.ssa | 1 + test/eucl.ssa | 1 + test/euclc.ssa | 1 + test/fpcnv.ssa | 2 ++ test/loop.ssa | 1 + test/mandel.ssa | 1 + test/max.ssa | 1 + test/prime.ssa | 1 + test/puts10.ssa | 1 + test/sum.ssa | 1 + tools/abifuzz.sh | 2 ++ tools/callgen.ml | 4 ++-- 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; -- cgit 1.4.1