commit 1b4943eb1f2a10837f56070bfe604179d0dc10e0
parent 54d734f6a4f3e13e906e8edb8ce3e10caa4bec25
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Mon, 28 Mar 2016 10:30:55 -0400
implement export control
Diffstat:
27 files changed, 65 insertions(+), 22 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,3 +1,4 @@
+export
function $test() {
@start
%x =l alloc16 16
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -1,3 +1,4 @@
+export
function $test() {
@start
%x1 =d copy d_0.1
diff --git 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
@@ -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
@@ -1,3 +1,4 @@
+export
function w $test() {
@l0
%a =l alloc4 4
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,3 +1,4 @@
+export
function $main() {
@start
%y =l alloc4 4
diff --git 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
@@ -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
@@ -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;