summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aarch64/main.sail16
-rw-r--r--aarch64/prelude.sail31
-rw-r--r--lib/elf.sail8
-rw-r--r--lib/flow.sail42
-rw-r--r--lib/smt.sail30
-rw-r--r--src/elf_loader.ml6
6 files changed, 96 insertions, 37 deletions
diff --git a/aarch64/main.sail b/aarch64/main.sail
index b48f84d9..eaaf4f7f 100644
--- a/aarch64/main.sail
+++ b/aarch64/main.sail
@@ -1,12 +1,14 @@
-val fetch_and_execute : unit -> unit effect {escape, undef, wreg, rreg, rmem, wmem}
+$include <elf.sail>
-function fetch_and_execute () = while true do {
- let instr = aget_Mem(_PC, 4, AccType_IFETCH);
- decode(instr);
- if __BranchTaken then __BranchTaken = false else _PC = _PC + 4
-}
+// Simple top level fetch and execute loop.
+val fetch_and_execute : unit -> unit effect {escape, undef, wreg, rreg, rmem, wmem}
-val elf_entry = "Elf_loader.elf_entry" : unit -> int
+function fetch_and_execute () =
+ while true do {
+ let instr = aget_Mem(_PC, 4, AccType_IFETCH);
+ decode(instr);
+ if __BranchTaken then __BranchTaken = false else _PC = _PC + 4
+ }
val main : unit -> unit effect {escape, undef, wreg, rreg, rmem, wmem}
diff --git a/aarch64/prelude.sail b/aarch64/prelude.sail
index da98b495..ab916e27 100644
--- a/aarch64/prelude.sail
+++ b/aarch64/prelude.sail
@@ -1,25 +1,12 @@
default Order dec
+$include <smt.sail>
+$include <flow.sail>
+
type bits ('n : Int) = vector('n, dec, bit)
infix 4 ==
-val div = {
- smt : "div",
- lem : "integerDiv"
-} : forall 'n 'm. (atom('n), atom('m)) -> atom(div('n, 'm))
-
-val mod = {
- smt : "mod",
- lem : "integerMod"
-} : forall 'n 'm. (atom('n), atom('m)) -> atom(mod('n, 'm))
-
-val eq_atom = {ocaml: "eq_int", lem: "eq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
-val lteq_atom = "lteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val gteq_atom = "gteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val lt_atom = "lt" : forall 'n 'm. (atom('n), atom('m)) -> bool
-val gt_atom = "gt" : forall 'n 'm. (atom('n), atom('m)) -> bool
-
val eq_int = {ocaml: "eq_int", lem: "eq"} : (int, int) -> bool
val eq_vec = {ocaml: "eq_list", lem: "eq_vec"} : forall 'n. (bits('n), bits('n)) -> bool
@@ -86,16 +73,10 @@ val vector_concat = {ocaml: "append", lem: "append_list"} : forall ('n : Int) ('
overload append = {bitvector_concat, vector_concat}
-val not_bool = "not" : bool -> bool
-
val not_vec = "not_vec" : forall 'n. bits('n) -> bits('n)
overload ~ = {not_bool, not_vec}
-val neq_atom = {lem: "neq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
-
-function neq_atom (x, y) = not_bool(eq_atom(x, y))
-
val neq_int = {lem: "neq"} : (int, int) -> bool
function neq_int (x, y) = not_bool(eq_int(x, y))
@@ -110,8 +91,6 @@ function neq_anything (x, y) = not_bool(x == y)
overload operator != = {neq_atom, neq_int, neq_vec, neq_anything}
-val and_bool = "and_bool" : (bool, bool) -> bool
-
val builtin_and_vec = {ocaml: "and_vec", lem: "Sail_operators.and_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
val and_vec : forall 'n. (bits('n), bits('n)) -> bits('n)
@@ -120,8 +99,6 @@ function and_vec (xs, ys) = builtin_and_vec(xs, ys)
overload operator & = {and_bool, and_vec}
-val or_bool = "or_bool" : (bool, bool) -> bool
-
val builtin_or_vec = {ocaml: "or_vec", lem: "Sail_operators.or_vec"} : forall 'n. (bits('n), bits('n)) -> bits('n)
val or_vec : forall 'n. (bits('n), bits('n)) -> bits('n)
@@ -263,7 +240,7 @@ val abs_int = "abs_int" : int -> int
val abs_real = "abs_real" : real -> real
-overload abs = {abs_int, abs_real}
+overload abs = {abs, abs_int, abs_real}
val quotient_nat = {ocaml: "quotient", lem: "integerDiv"} : (nat, nat) -> nat
diff --git a/lib/elf.sail b/lib/elf.sail
new file mode 100644
index 00000000..f158fbad
--- /dev/null
+++ b/lib/elf.sail
@@ -0,0 +1,8 @@
+$ifndef _ELF
+$define _ELF
+
+val elf_entry = "Elf_loader.elf_entry" : unit -> int
+
+val elf_tohost = "Elf_loader.elf_tohost" : unit -> int
+
+$endif
diff --git a/lib/flow.sail b/lib/flow.sail
new file mode 100644
index 00000000..cb7b1b99
--- /dev/null
+++ b/lib/flow.sail
@@ -0,0 +1,42 @@
+$ifndef _FLOW
+$define _FLOW
+
+val not_bool = "not" : bool -> bool
+val and_bool = "and_bool" : (bool, bool) -> bool
+val or_bool = "or_bool" : (bool, bool) -> bool
+
+val eq_atom = {ocaml: "eq_int", lem: "eq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
+
+val neq_atom = {lem: "neq"} : forall 'n 'm. (atom('n), atom('m)) -> bool
+
+function neq_atom (x, y) = not_bool(eq_atom(x, y))
+
+val lteq_atom = "lteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val gteq_atom = "gteq" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val lt_atom = "lt" : forall 'n 'm. (atom('n), atom('m)) -> bool
+val gt_atom = "gt" : forall 'n 'm. (atom('n), atom('m)) -> bool
+
+val lt_range_atom = "lt" : forall 'n 'm 'o. (range('n, 'm), atom('o)) -> bool
+val lteq_range_atom = "lteq" : forall 'n 'm 'o. (range('n, 'm), atom('o)) -> bool
+val gt_range_atom = "gt" : forall 'n 'm 'o. (range('n, 'm), atom('o)) -> bool
+val gteq_range_atom = "gteq" : forall 'n 'm 'o. (range('n, 'm), atom('o)) -> bool
+val lt_atom_range = "lt" : forall 'n 'm 'o. (atom('n), range('m, 'o)) -> bool
+val lteq_atom_range = "lteq" : forall 'n 'm 'o. (atom('n), range('m, 'o)) -> bool
+val gt_atom_range = "gt" : forall 'n 'm 'o. (atom('n), range('m, 'o)) -> bool
+val gteq_atom_range = "gteq" : forall 'n 'm 'o. (atom('n), range('m, 'o)) -> bool
+
+$ifdef TEST
+
+val __flow_test : forall 'n 'm. (atom('n), atom('m)) -> unit
+
+function __flow_test (x, y) = {
+ if lteq_atom(x, y) then {
+ _prove(constraint('n <= 'm))
+ } else {
+ _prove(constraint('n > 'm))
+ }
+}
+
+$endif
+
+$endif
diff --git a/lib/smt.sail b/lib/smt.sail
new file mode 100644
index 00000000..702b82c6
--- /dev/null
+++ b/lib/smt.sail
@@ -0,0 +1,30 @@
+$ifndef _SMT
+$define _SMT
+
+// see http://smtlib.cs.uiowa.edu/theories-Ints.shtml
+
+val div = {
+ smt: "div",
+ ocaml: "quotient",
+ lem: "integerDiv"
+} : forall 'n 'm. (atom('n), atom('m)) -> {'o, 'o = div('n, 'm). atom('o)}
+
+val mod = {
+ smt: "mod",
+ ocaml: "modulus",
+ lem: "integerMod"
+} : forall 'n 'm. (atom('n), atom('m)) -> {'o, 'o = mod('n, 'm). atom('o)}
+
+val abs = {
+ smt : "abs",
+ ocaml: "abs_int",
+ lem: "abs_int"
+} : forall 'n. atom('n) -> {'o, 'o = abs('n). atom('o)}
+
+$ifdef TEST
+
+let __smt_x : atom(div(4, 2)) = div(8, 4)
+
+$endif
+
+$endif
diff --git a/src/elf_loader.ml b/src/elf_loader.ml
index feacdf3d..83c36821 100644
--- a/src/elf_loader.ml
+++ b/src/elf_loader.ml
@@ -118,9 +118,9 @@ let load_segment seg =
let load_elf name =
let segments, e_entry, symbol_map = read name in
opt_elf_entry := e_entry;
- if List.mem_assoc "tohost" symbol_map then
- let (_, _, tohost_addr, _, _) = List.assoc "tohost" symbol_map in
- opt_elf_tohost := tohost_addr;
+ (if List.mem_assoc "tohost" symbol_map then
+ let (_, _, tohost_addr, _, _) = List.assoc "tohost" symbol_map in
+ opt_elf_tohost := tohost_addr);
List.iter load_segment segments
(* The sail model can access this by externing a unit -> int function