From 62e238a6ef151d56b79e1f076a57463f2e1fb020 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Fri, 25 Mar 2016 14:02:43 -0400 Subject: great renaming campain! --- lisc/tools/abi.ml | 532 ------------------------------------------------------ 1 file changed, 532 deletions(-) delete mode 100644 lisc/tools/abi.ml (limited to 'lisc/tools/abi.ml') diff --git a/lisc/tools/abi.ml b/lisc/tools/abi.ml deleted file mode 100644 index d845c74..0000000 --- a/lisc/tools/abi.ml +++ /dev/null @@ -1,532 +0,0 @@ -(* fuzzer *) - -type _ bty = - | Char: int bty - | Short: int bty - | Int: int bty - | Long: int bty - | Float: float bty - | Double: float bty - -type _ sty = - | Field: 'a bty * 'b sty -> ('a * 'b) sty - | Empty: unit sty - -type _ aty = - | Base: 'a bty -> 'a aty - | Struct: 'a sty -> 'a aty - -type anyb = AB: _ bty -> anyb (* kinda boring... *) -type anys = AS: _ sty -> anys -type anya = AA: _ aty -> anya -type testb = TB: 'a bty * 'a -> testb -type testa = TA: 'a aty * 'a -> testa - - -let align a x = - let m = x mod a in - if m <> 0 then x + (a-m) else x - -let btysize: type a. a bty -> int = function - | Char -> 1 - | Short -> 2 - | Int -> 4 - | Long -> 8 - | Float -> 4 - | Double -> 8 - -let btyalign = btysize - -let styempty: type a. a sty -> bool = function - | Field _ -> false - | Empty -> true - -let stysize s = - let rec f: type a. int -> a sty -> int = - fun sz -> function - | Field (b, s) -> - let a = btyalign b in - f (align a sz + btysize b) s - | Empty -> sz in - f 0 s - -let rec styalign: type a. a sty -> int = function - | Field (b, s) -> max (btyalign b) (styalign s) - | Empty -> 1 - - -(* Generate types and test vectors. *) -module Gen = struct - module R = Random - - let init = function - | None -> - let f = open_in "/dev/urandom" in - let seed = - Char.code (input_char f) lsl 8 + - Char.code (input_char f) in - close_in f; - R.init seed; - seed - | Some seed -> - R.init seed; - seed - - let int sz = - let bound = 1 lsl (8 * min sz 3 - 1) in - let i = R.int bound in - if R.bool () then - i else i - - let float () = - let f = R.float 1000. in - if R.bool () then -. f else f - - let testv: type a. a aty -> a = - let tb: type a. a bty -> a = function (* eh, dry... *) - | Float -> float () - | Double -> float () - | Char -> int (btysize Char) - | Short -> int (btysize Short) - | Int -> int (btysize Int) - | Long -> int (btysize Long) in - let rec ts: type a. a sty -> a = function - | Field (b, s) -> (tb b, ts s) - | Empty -> () in - function - | Base b -> tb b - | Struct s -> ts s - - let b () = (* uniform *) - match R.int 6 with - | 0 -> AB Char - | 1 -> AB Short - | 2 -> AB Int - | 3 -> AB Long - | 4 -> AB Float - | _ -> AB Double - - let smax = 5 (* max elements in structs *) - let structp = 0.3 (* odds of having a struct type *) - let amax = 8 (* max function arguments *) - - let s () = - let rec f n = - if n = 0 then AS Empty else - let AB bt = b () in - let AS st = f (n-1) in - AS (Field (bt, st)) in - f (1 + R.int (smax-1)) - - let a () = - if R.float 1.0 > structp then - let AB bt = b () in - AA (Base bt) - else - let AB bt = b () in - let AS st = s () in - AA (Struct (Field (bt, st))) - - let test () = - let AA ty = a () in - let t = testv ty in - TA (ty, t) - - let tests () = - let rec f n = - if n = 0 then [] else - test () :: f (n-1) in - f (R.int amax) - -end - - -(* Code generation for C *) -module OutC = struct - open Printf - - let ctypelong oc name = - let cb: type a. a bty -> unit = function - | Char -> fprintf oc "char" - | Short -> fprintf oc "short" - | Int -> fprintf oc "int" - | Long -> fprintf oc "long" - | Float -> fprintf oc "float" - | Double -> fprintf oc "double" in - let rec cs: type a. int -> a sty -> unit = - fun i -> function - | Field (b, s) -> - cb b; - fprintf oc " f%d; " i; - cs (i+1) s; - | Empty -> () in - function - | Base b -> - cb b; - | Struct s -> - fprintf oc "struct %s { " name; - cs 1 s; - fprintf oc "}"; - () - - let ctype: type a. out_channel -> string -> a aty -> unit = - fun oc name -> function - | Struct _ -> fprintf oc "struct %s" name - | t -> ctypelong oc "" t - - let base: type a. out_channel -> a bty * a -> unit = - fun oc -> function - | Char, i -> fprintf oc "%d" i - | Short, i -> fprintf oc "%d" i - | Int, i -> fprintf oc "%d" i - | Long, i -> fprintf oc "%d" i - | Float, f -> fprintf oc "%ff" f - | Double, f -> fprintf oc "%f" f - - let init oc name (TA (ty, t)) = - let inits s = - let rec f: type a. a sty * a -> unit = function - | Field (b, s), (tb, ts) -> - base oc (b, tb); - fprintf oc ", "; - f (s, ts) - | Empty, () -> () in - fprintf oc "{ "; - f s; - fprintf oc "}"; in - ctype oc name ty; - fprintf oc " %s = " name; - begin match (ty, t) with - | Base b, tb -> base oc (b, tb) - | Struct s, ts -> inits (s, ts) - end; - fprintf oc ";\n"; - () - - let extension = ".c" - - let comment oc s = - fprintf oc "/* %s */\n" s - - let prelude oc = List.iter (fprintf oc "%s\n") - [ "#include " - ; "#include " - ; "" - ; "static void fail(char *chk)" - ; "{" - ; "\tfprintf(stderr, \"fail: checking %s\\n\", chk);" - ; "\tabort();" - ; "}" - ; "" - ] - - let typedef oc name = function - | TA (Struct ts, _) -> - ctypelong oc name (Struct ts); - fprintf oc ";\n"; - | _ -> () - - let check oc name = - let chkbase: type a. string -> a bty * a -> unit = - fun name t -> - fprintf oc "\tif (%s != " name; - base oc t; - fprintf oc ")\n\t\tfail(%S);\n" name; in - function - | TA (Base b, tb) -> chkbase name (b, tb) - | TA (Struct s, ts) -> - let rec f: type a. int -> a sty * a -> unit = - fun i -> function - | Field (b, s), (tb, ts) -> - chkbase (Printf.sprintf "%s.f%d" name i) (b, tb); - f (i+1) (s, ts); - | Empty, () -> () in - f 1 (s, ts) - - let argname i = "arg" ^ string_of_int (i+1) - - let proto oc (TA (tret, _)) args = - ctype oc "ret" tret; - fprintf oc " f("; - let narg = List.length args in - List.iteri (fun i (TA (targ, _)) -> - ctype oc (argname i) targ; - fprintf oc " %s" (argname i); - if i <> narg-1 then - fprintf oc ", "; - ) args; - fprintf oc ")"; - () - - let caller oc ret args = - let narg = List.length args in - prelude oc; - typedef oc "ret" ret; - List.iteri (fun i arg -> - typedef oc (argname i) arg; - ) args; - proto oc ret args; - fprintf oc ";\n\nint main()\n{\n"; - List.iteri (fun i arg -> - fprintf oc "\t"; - init oc (argname i) arg; - ) args; - fprintf oc "\t"; - let TA (tret, _) = ret in - ctype oc "ret" tret; - fprintf oc " ret;\n\n"; - fprintf oc "\tret = f("; - List.iteri (fun i _ -> - fprintf oc "%s" (argname i); - if i <> narg-1 then - fprintf oc ", "; - ) args; - fprintf oc ");\n"; - check oc "ret" ret; - fprintf oc "\n\treturn 0;\n}\n"; - () - - let callee oc ret args = - prelude oc; - typedef oc "ret" ret; - List.iteri (fun i arg -> - typedef oc (argname i) arg; - ) args; - fprintf oc "\n"; - proto oc ret args; - fprintf oc "\n{\n\t"; - init oc "ret" ret; - fprintf oc "\n"; - List.iteri (fun i arg -> - check oc (argname i) arg; - ) args; - fprintf oc "\n\treturn ret;\n}\n"; - () - -end - -(* Code generation for QBE *) -module OutIL = struct - open Printf - - let comment oc s = - fprintf oc "# %s\n" s - - let tmp, lbl = - let next = ref 0 in - (fun () -> incr next; "%t" ^ (string_of_int !next)), - (fun () -> incr next; "@l" ^ (string_of_int !next)) - - let bvalue: type a. a bty * a -> string = function - | Char, i -> sprintf "%d" i - | Short, i -> sprintf "%d" i - | Int, i -> sprintf "%d" i - | Long, i -> sprintf "%d" i - | Float, f -> sprintf "s_%f" f - | Double, f -> sprintf "d_%f" f - - let btype: type a. a bty -> string = function - | Char -> "w" - | Short -> "w" - | Int -> "w" - | Long -> "l" - | Float -> "s" - | Double -> "d" - - let extension = ".ssa" - - let argname i = "arg" ^ string_of_int (i+1) - - let siter oc base s g = - let rec f: type a. int -> int -> a sty * a -> unit = - fun id off -> function - | Field (b, s), (tb, ts) -> - let off = align (btyalign b) off in - let addr = tmp () in - fprintf oc "\t%s =l add %d, %s\n" addr off base; - g id addr (TB (b, tb)); - f (id + 1) (off + btysize b) (s, ts); - | Empty, () -> () in - f 0 0 s - - let bmemtype b = - if AB b = AB Char then "b" else - if AB b = AB Short then "h" else - btype b - - let init oc = function - | TA (Base b, tb) -> bvalue (b, tb) - | TA (Struct s, ts) -> - let base = tmp () in - fprintf oc "\t%s =l alloc%d %d\n" - base (styalign s) (stysize s); - siter oc base (s, ts) - begin fun _ addr (TB (b, tb)) -> - fprintf oc "\tstore%s %s, %s\n" - (bmemtype b) (bvalue (b, tb)) addr; - end; - base - - let check oc id name = - let bcheck = fun id name (b, tb) -> - let tcmp = tmp () in - let nxtl = lbl () in - fprintf oc "\t%s =w ceq%s %s, %s\n" - tcmp (btype b) name (bvalue (b, tb)); - fprintf oc "\tstorew %d, %%failcode\n" id; - fprintf oc "\tjnz %s, %s, @fail\n" tcmp nxtl; - fprintf oc "%s\n" nxtl; in - function - | TA (Base Char, i) -> - let tval = tmp () in - fprintf oc "\t%s =w extsb %s\n" tval name; - bcheck id tval (Int, i) - | TA (Base Short, i) -> - let tval = tmp () in - fprintf oc "\t%s =w extsh %s\n" tval name; - bcheck id tval (Int, i) - | TA (Base b, tb) -> - bcheck id name (b, tb) - | TA (Struct s, ts) -> - siter oc name (s, ts) - begin fun id' addr (TB (b, tb)) -> - let tval = tmp () in - let lsuffix = - if AB b = AB Char then "sb" else - if AB b = AB Short then "sh" else - "" in - fprintf oc "\t%s =%s load%s %s\n" - tval (btype b) lsuffix addr; - bcheck (100*id + id'+1) tval (b, tb); - end; - () - - let ttype name = function - | TA (Base b, _) -> btype b - | TA (Struct _, _) -> ":" ^ name - - let typedef oc name = - let rec f: type a. a sty -> unit = function - | Field (b, s) -> - fprintf oc "%s" (bmemtype b); - if not (styempty s) then - fprintf oc ", "; - f s; - | Empty -> () in - function - | TA (Struct ts, _) -> - fprintf oc "type :%s = { " name; - f ts; - fprintf oc " }\n"; - | _ -> () - - let postlude oc = List.iter (fprintf oc "%s\n") - [ "@fail" - ; "# failure code" - ; "\t%fcode =w loadw %failcode" - ; "\t%f0 =w call $printf(l $failstr, w %fcode)" - ; "\t%f1 =w call $abort()" - ; "\tret 0" - ; "}" - ; "" - ; "data $failstr = { b \"fail on check %d\\n\", b 0 }" - ] - - let caller oc ret args = - let narg = List.length args in - List.iteri (fun i arg -> - typedef oc (argname i) arg; - ) args; - typedef oc "ret" ret; - fprintf oc "\nfunction w $main() {\n"; - fprintf oc "@start\n"; - fprintf oc "\t%%failcode =l alloc4 4\n"; - let targs = List.mapi (fun i arg -> - comment oc ("define argument " ^ (string_of_int (i+1))); - (ttype (argname i) arg, init oc arg) - ) args in - comment oc "call test function"; - fprintf oc "\t%%ret =%s call $f(" (ttype "ret" ret); - List.iteri (fun i (ty, tmp) -> - fprintf oc "%s %s" ty tmp; - if i <> narg-1 then - fprintf oc ", "; - ) targs; - fprintf oc ")\n"; - comment oc "check the return value"; - check oc 0 "%ret" ret; - fprintf oc "\tret 0\n"; - postlude oc; - () - - let callee oc ret args = - let narg = List.length args in - List.iteri (fun i arg -> - typedef oc (argname i) arg; - ) args; - typedef oc "ret" ret; - fprintf oc "\nfunction %s $f(" (ttype "ret" ret); - List.iteri (fun i arg -> - let a = argname i in - fprintf oc "%s %%%s" (ttype a arg) a; - if i <> narg-1 then - fprintf oc ", "; - ) args; - fprintf oc ") {\n"; - fprintf oc "@start\n"; - fprintf oc "\t%%failcode =l alloc4 4\n"; - List.iteri (fun i arg -> - comment oc ("checking argument " ^ (string_of_int (i+1))); - check oc (i+1) ("%" ^ argname i) arg; - ) args; - comment oc "define the return value"; - let rettmp = init oc ret in - fprintf oc "\tret %s\n" rettmp; - postlude oc; - () - -end - - -module type OUT = sig - val extension: string - val comment: out_channel -> string -> unit - val caller: out_channel -> testa -> testa list -> unit - val callee: out_channel -> testa -> testa list -> unit -end - -let _ = - let usage code = - Printf.eprintf "usage: abi.ml [-s SEED] DIR {c,ssa} {c,ssa}\n"; - exit code in - - let outmod = function - | "c" -> (module OutC : OUT) - | "ssa" -> (module OutIL: OUT) - | _ -> usage 1 in - - let seed, dir, mcaller, mcallee = - match Sys.argv with - | [| _; "-s"; seed; dir; caller; callee |] -> - let seed = - try Some (int_of_string seed) with - Failure _ -> usage 1 in - seed, dir, outmod caller, outmod callee - | [| _; dir; caller; callee |] -> - None, dir, outmod caller, outmod callee - | [| _; "-h" |] -> - usage 0 - | _ -> - usage 1 in - - let seed = Gen.init seed in - let tret = Gen.test () in - let targs = Gen.tests () in - let module OCaller = (val mcaller : OUT) in - let module OCallee = (val mcallee : OUT) in - let ocaller = open_out (dir ^ "/caller" ^ OCaller.extension) in - let ocallee = open_out (dir ^ "/callee" ^ OCallee.extension) in - OCaller.comment ocaller (Printf.sprintf "seed %d" seed); - OCallee.comment ocallee (Printf.sprintf "seed %d" seed); - OCaller.caller ocaller tret targs; - OCallee.callee ocallee tret targs; - () -- cgit 1.4.1