summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile7
-rw-r--r--src/_tags11
-rw-r--r--src/c_backend.ml131
-rw-r--r--src/gen_lib/sail_values.lem8
-rw-r--r--src/gen_lib/sail_values.ml1488
-rw-r--r--src/myocamlbuild.ml2
-rw-r--r--src/util.ml7
-rw-r--r--src/util.mli2
-rw-r--r--src/value2.lem99
9 files changed, 210 insertions, 1545 deletions
diff --git a/src/Makefile b/src/Makefile
index 8bf4802a..3e0b9841 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -82,7 +82,7 @@ ast.ml: ast.lem
sed -i -f ast.sed ast.ml
bytecode.ml: bytecode.lem
- lem -ocaml bytecode.lem
+ lem -ocaml bytecode.lem -lib . -lib gen_lib/
sed -i -f ast.sed bytecode.ml
lem_interp/interp_ast.lem: ../language/l2.ott
@@ -234,8 +234,8 @@ _build/%_trimmed.sail: _build/%_all.sail
count: _build/cheri_trimmed.sail _build/mips_trimmed.sail
wc -l $^
-%.ml: %.lem
- $(LEM) -only_changed_output -ocaml -lib lem_interp/ $<
+# %.ml: %.lem
+# $(LEM) -only_changed_output -ocaml -lib lem_interp/ $<
#run_mips.native: _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml interpreter
# env OCAMLRUNPARAM=l=100M ocamlfind ocamlopt $(OCAML_OPTS) -g -package num -package str -package unix -I $(ELFDIR)/contrib/ocaml-uint/_build/lib -I $(LEMLIBOCAML) -I $(ZARITH_DIR) -I _build/lem_interp/ -I $(ELFDIR)/src -I $(ELFDIR)/src/adaptors -I $(ELFDIR)/src/abis/mips64 -I _build -linkpkg $(ZARITH_LIB) $(LEMLIBOCAML)/extract.cmxa $(ELFDIR)/contrib/ocaml-uint/_build/lib/uint.cmxa $(ELFDIR)/src/linksem.cmxa _build/pprint/src/PPrintLib.cmxa _build/lem_interp/extract.cmxa _build/mips.ml _build/mips_extras.ml _build/run_with_elf.ml -o run_mips.native
@@ -280,6 +280,7 @@ clean:
-rm -rf tex-doc
-rm -rf lem lib
-rm -rf sail.docdir
+ -rm -f gen_lib/*.ml
-rm -f ast.ml
-rm -f ast.lem
-rm -f bytecode.ml
diff --git a/src/_tags b/src/_tags
index 1b9be030..c5f4e127 100644
--- a/src/_tags
+++ b/src/_tags
@@ -1,16 +1,15 @@
true: -traverse, debug, use_menhir
<**/*.ml>: bin_annot, annot
-# <lem_interp> or <test>: include
+
<sail.{byte,native}>: package(zarith), package(linksem), package(lem), use_pprint
<isail.{byte,native}>: package(zarith), package(linenoise), package(linksem), package(lem), use_pprint
+
<isail.ml>: package(linenoise)
<elf_loader.ml>: package(linksem)
-<pprint> or <pprint/src>: include
-<*.m{l,li}>: package(lem)
+<**/*.m{l,li}>: package(lem)
-# see http://caml.inria.fr/mantis/view.php?id=4943
-<lem_interp/*> and not <lem_interp/*.cmxa>: package(num), package(lem)
-<test/*> and not <test/*.cmxa>: package(num), package(lem), package(str)
+<gen_lib>: include
+<pprint> or <pprint/src>: include
# disable partial match and unused variable warnings
<**/*.ml>: warn_y
diff --git a/src/c_backend.ml b/src/c_backend.ml
index dc87cfd9..33f6f127 100644
--- a/src/c_backend.ml
+++ b/src/c_backend.ml
@@ -53,6 +53,7 @@ open Ast_util
open Bytecode
open Type_check
open PPrint
+open Value2
module Big_int = Nat_big_num
let c_verbosity = ref 1
@@ -82,10 +83,23 @@ let lvar_typ = function
(* | Union (_, typ) -> typ *)
| _ -> assert false
+let string_of_value = function
+ | V_bits bs -> Sail_values.show_bitlist bs ^ "ul"
+ | V_int i -> Big_int.to_string i ^ "l"
+ | V_bool true -> "true"
+ | V_bool false -> "false"
+ | V_null -> "NULL"
+ | V_unit -> "UNIT"
+ | V_bit Sail_values.B0 -> "0ul"
+ | V_bit Sail_values.B1 -> "1ul"
+ | V_string str -> "\"" ^ str ^ "\""
+ | V_ctor_kind str -> "Kind_" ^ Util.zencode_string str
+ | _ -> failwith "Cannot convert value to string"
+
let rec string_of_fragment ?zencode:(zencode=true) = function
| F_id id when zencode -> Util.zencode_string (string_of_id id)
| F_id id -> string_of_id id
- | F_lit str -> str
+ | F_lit v -> string_of_value v
| F_call (str, frags) ->
Printf.sprintf "%s(%s)" str (Util.string_of_list ", " (string_of_fragment ~zencode:zencode) frags)
| F_field (f, field) ->
@@ -175,7 +189,7 @@ and aval =
let rec frag_rename from_id to_id = function
| F_id id when Id.compare id from_id = 0 -> F_id to_id
| F_id id -> F_id id
- | F_lit str -> F_lit str
+ | F_lit v -> F_lit v
| F_have_exception -> F_have_exception
| F_current_exception -> F_current_exception
| F_call (call, frags) -> F_call (call, List.map (frag_rename from_id to_id) frags)
@@ -829,16 +843,39 @@ let ctor_bindings = List.fold_left (fun map (id, ctyp) -> Bindings.add id ctyp m
(* 3. Optimization of primitives and literals *)
(**************************************************************************)
+let hex_char =
+ let open Sail_values in
+ function
+ | '0' -> [B0; B0; B0; B0]
+ | '1' -> [B0; B0; B0; B1]
+ | '2' -> [B0; B0; B1; B0]
+ | '3' -> [B0; B0; B1; B1]
+ | '4' -> [B0; B1; B0; B0]
+ | '5' -> [B0; B1; B0; B1]
+ | '6' -> [B0; B1; B1; B0]
+ | '7' -> [B0; B1; B1; B1]
+ | '8' -> [B1; B0; B0; B0]
+ | '9' -> [B1; B0; B0; B1]
+ | 'A' | 'a' -> [B1; B0; B1; B0]
+ | 'B' | 'b' -> [B1; B0; B1; B1]
+ | 'C' | 'c' -> [B1; B1; B0; B0]
+ | 'D' | 'd' -> [B1; B1; B0; B1]
+ | 'E' | 'e' -> [B1; B1; B1; B0]
+ | 'F' | 'f' -> [B1; B1; B1; B1]
+ | _ -> failwith "Invalid hex character"
+
let literal_to_fragment (L_aux (l_aux, _) as lit) =
match l_aux with
| L_num n when Big_int.less_equal min_int64 n && Big_int.less_equal n max_int64 ->
- Some (F_lit (Big_int.to_string n ^ "L"))
+ Some (F_lit (V_int n))
| L_hex str when String.length str <= 16 ->
let padding = 16 - String.length str in
- Some (F_lit ("0x" ^ String.make padding '0' ^ str ^ "ul"))
- | L_unit -> Some (F_lit "UNIT")
- | L_true -> Some (F_lit "true")
- | L_false -> Some (F_lit "false")
+ let padding = Util.list_init padding (fun _ -> Sail_values.B0) in
+ let content = Util.string_to_list str |> List.map hex_char |> List.concat in
+ Some (F_lit (V_bits (padding @ content)))
+ | L_unit -> Some (F_lit V_unit)
+ | L_true -> Some (F_lit (V_bool true))
+ | L_false -> Some (F_lit (V_bool false))
| _ -> None
let c_literals ctx =
@@ -869,9 +906,9 @@ let rec is_bitvector = function
| AV_lit (L_aux (L_one, _), _) :: avals -> is_bitvector avals
| _ :: _ -> false
-let rec string_of_aval_bit = function
- | AV_lit (L_aux (L_zero, _), _) -> "0"
- | AV_lit (L_aux (L_one, _), _) -> "1"
+let rec value_of_aval_bit = function
+ | AV_lit (L_aux (L_zero, _), _) -> Sail_values.B0
+ | AV_lit (L_aux (L_one, _), _) -> Sail_values.B1
| _ -> assert false
let rec c_aval ctx = function
@@ -893,7 +930,7 @@ let rec c_aval ctx = function
| _ -> v
end
| AV_vector (v, typ) when is_bitvector v && List.length v <= 64 ->
- let bitstring = F_lit ("0b" ^ String.concat "" (List.map string_of_aval_bit v) ^ "ul") in
+ let bitstring = F_lit (V_bits (List.map value_of_aval_bit v)) in
AV_C_fragment (bitstring, typ)
| AV_tuple avals -> AV_tuple (List.map (c_aval ctx) avals)
| aval -> aval
@@ -912,31 +949,33 @@ let analyze_primop' ctx id args typ =
let extern = if Env.is_extern id ctx.tc_env "c" then Env.get_extern id ctx.tc_env "c" else failwith "Not extern" in
(* prerr_endline ("Analysing: " ^ string_of_typ typ ^ " " ^ extern ^ Pretty_print_sail.to_string (separate_map (string ", ") pp_aval args)); *)
+ let v_one = F_lit (V_int (Big_int.of_int 1)) in
+
match extern, args with
| "eq_bits", [AV_C_fragment (v1, typ1); AV_C_fragment (v2, typ2)] ->
AE_val (AV_C_fragment (F_op (v1, "==", v2), typ))
| "vector_subrange", [AV_C_fragment (vec, _); AV_C_fragment (f, _); AV_C_fragment (t, _)] ->
- let len = F_op (f, "-", F_op (t, "-", F_lit "1L")) in
- AE_val (AV_C_fragment (F_op (F_op (F_op (F_lit "1L", "<<", len), "-", F_lit "1L"), "&", F_op (vec, ">>", t)), typ))
+ let len = F_op (f, "-", F_op (t, "-", v_one)) in
+ AE_val (AV_C_fragment (F_op (F_op (F_op (v_one, "<<", len), "-", v_one), "&", F_op (vec, ">>", t)), typ))
| "vector_access", [AV_C_fragment (vec, _); AV_C_fragment (n, _)] ->
- AE_val (AV_C_fragment (F_op (F_lit "1L", "&", F_op (vec, ">>", n)), typ))
+ AE_val (AV_C_fragment (F_op (v_one, "&", F_op (vec, ">>", n)), typ))
| "eq_bit", [AV_C_fragment (a, _); AV_C_fragment (b, _)] ->
AE_val (AV_C_fragment (F_op (a, "==", b), typ))
| "slice", [AV_C_fragment (vec, _); AV_C_fragment (start, _); AV_C_fragment (len, _)] ->
- AE_val (AV_C_fragment (F_op (F_op (F_op (F_lit "1L", "<<", len), "-", F_lit "1L"), "&", F_op (vec, ">>", start)), typ))
+ AE_val (AV_C_fragment (F_op (F_op (F_op (v_one, "<<", len), "-", v_one), "&", F_op (vec, ">>", start)), typ))
| "undefined_bit", _ ->
- AE_val (AV_C_fragment (F_lit "0ul", typ))
+ AE_val (AV_C_fragment (F_lit (V_bit Sail_values.B0), typ))
| "undefined_vector", [AV_C_fragment (len, _); _] ->
begin match destruct_vector ctx.tc_env typ with
| Some (Nexp_aux (Nexp_constant n, _), _, Typ_aux (Typ_id id, _))
when string_of_id id = "bit" && Big_int.less_equal n (Big_int.of_int 64) ->
- AE_val (AV_C_fragment (F_lit "0ul", typ))
+ AE_val (AV_C_fragment (F_lit (V_bit Sail_values.B0), typ))
| _ -> no_change
end
@@ -953,12 +992,12 @@ let analyze_primop' ctx id args typ =
begin match destruct_vector ctx.tc_env typ, destruct_vector ctx.tc_env vtyp with
| Some (Nexp_aux (Nexp_constant n, _), _, _), Some (Nexp_aux (Nexp_constant m, _), _, _)
when Big_int.less_equal n (Big_int.of_int 64) ->
- AE_val (AV_C_fragment (F_call ("fast_replicate_bits", [F_lit (Big_int.to_string m); vec; times]), typ))
+ AE_val (AV_C_fragment (F_call ("fast_replicate_bits", [F_lit (V_int m); vec; times]), typ))
| _ -> no_change
end
| "undefined_bool", _ ->
- AE_val (AV_C_fragment (F_lit "false", typ))
+ AE_val (AV_C_fragment (F_lit (V_bool false), typ))
| _, _ -> no_change
@@ -1261,32 +1300,32 @@ let rec compile_aval ctx = function
[], (F_id id, ctyp_of_typ ctx (lvar_typ typ)), []
| AV_lit (L_aux (L_string str, _), typ) ->
- [], (F_lit ("\"" ^ String.escaped str ^ "\""), ctyp_of_typ ctx typ), []
+ [], (F_lit (V_string (String.escaped str)), ctyp_of_typ ctx typ), []
| AV_lit (L_aux (L_num n, _), typ) when Big_int.less_equal min_int64 n && Big_int.less_equal n max_int64 ->
let gs = gensym () in
[idecl CT_mpz gs;
- iinit CT_mpz gs (F_lit (Big_int.to_string n ^ "l"), CT_int64)],
+ iinit CT_mpz gs (F_lit (V_int n), CT_int64)],
(F_id gs, CT_mpz),
[iclear CT_mpz gs]
| AV_lit (L_aux (L_num n, _), typ) ->
let gs = gensym () in
[idecl CT_mpz gs;
- iinit CT_mpz gs (F_lit ("\"" ^ Big_int.to_string n ^ "\""), CT_string)],
+ iinit CT_mpz gs (F_lit (V_string (Big_int.to_string n)), CT_string)],
(F_id gs, CT_mpz),
[iclear CT_mpz gs]
- | AV_lit (L_aux (L_zero, _), _) -> [], (F_lit "0", CT_bit), []
- | AV_lit (L_aux (L_one, _), _) -> [], (F_lit "1", CT_bit), []
+ | AV_lit (L_aux (L_zero, _), _) -> [], (F_lit (V_bit Sail_values.B0), CT_bit), []
+ | AV_lit (L_aux (L_one, _), _) -> [], (F_lit (V_bit Sail_values.B1), CT_bit), []
- | AV_lit (L_aux (L_true, _), _) -> [], (F_lit "true", CT_bool), []
- | AV_lit (L_aux (L_false, _), _) -> [], (F_lit "false", CT_bool), []
+ | AV_lit (L_aux (L_true, _), _) -> [], (F_lit (V_bool true), CT_bool), []
+ | AV_lit (L_aux (L_false, _), _) -> [], (F_lit (V_bool false), CT_bool), []
| AV_lit (L_aux (L_real str, _), _) ->
let gs = gensym () in
[idecl CT_real gs;
- iinit CT_real gs (F_lit ("\"" ^ str ^ "\""), CT_string)],
+ iinit CT_real gs (F_lit (V_string str), CT_string)],
(F_id gs, CT_real),
[iclear CT_real gs]
@@ -1331,7 +1370,7 @@ let rec compile_aval ctx = function
(* Convert a small bitvector to a uint64_t literal. *)
| AV_vector (avals, typ) when is_bitvector avals && List.length avals <= 64 ->
begin
- let bitstring = F_lit ("0b" ^ String.concat "" (List.map string_of_aval_bit avals) ^ "ul") in
+ let bitstring = F_lit (V_bits (List.map value_of_aval_bit avals)) in
let len = List.length avals in
match destruct_vector ctx.tc_env typ with
| Some (_, Ord_aux (Ord_inc, _), _) ->
@@ -1348,7 +1387,7 @@ let rec compile_aval ctx = function
variable size bitvector, converting it in 64-bit chunks. *)
| AV_vector (avals, typ) when is_bitvector avals ->
let len = List.length avals in
- let bitstring avals = F_lit ("0b" ^ String.concat "" (List.map string_of_aval_bit avals) ^ "ul") in
+ let bitstring avals = F_lit (V_bits (List.map value_of_aval_bit avals)) in
let first_chunk = bitstring (Util.take (len mod 64) avals) in
let chunks = Util.drop (len mod 64) avals |> chunkify 64 |> List.map bitstring in
let gs = gensym () in
@@ -1372,18 +1411,18 @@ let rec compile_aval ctx = function
in
let gs = gensym () in
let ctyp = CT_uint64 (len, direction) in
- let mask i = "0b" ^ String.make (63 - i) '0' ^ "1" ^ String.make i '0' ^ "ul" in
+ let mask i = V_bits (Util.list_init (63 - i) (fun _ -> Sail_values.B0) @ [Sail_values.B1] @ Util.list_init i (fun _ -> Sail_values.B0)) in
let aval_mask i aval =
let setup, cval, cleanup = compile_aval ctx aval in
match cval with
- | (F_lit "0", _) -> []
- | (F_lit "1", _) ->
+ | (F_lit (V_bit Sail_values.B0), _) -> []
+ | (F_lit (V_bit Sail_values.B1), _) ->
[icopy (CL_id gs) (F_op (F_id gs, "|", F_lit (mask i)), ctyp)]
| _ ->
setup @ [iif cval [icopy (CL_id gs) (F_op (F_id gs, "|", F_lit (mask i)), ctyp)] [] CT_unit] @ cleanup
in
[idecl ctyp gs;
- icopy (CL_id gs) (F_lit "0ul", ctyp)]
+ icopy (CL_id gs) (F_lit (V_bits (Util.list_init 64 (fun _ -> Sail_values.B0))), ctyp)]
@ List.concat (List.mapi aval_mask (List.rev avals)),
(F_id gs, ctyp),
[]
@@ -1471,7 +1510,7 @@ let compile_funcall ctx id args typ =
let rec compile_match ctx apat cval case_label =
match apat, cval with
| AP_id pid, (frag, ctyp) when is_ct_variant ctyp ->
- [ijump (F_op (F_field (frag, "kind"), "!=", F_lit ("Kind_" ^ Util.zencode_string (string_of_id pid))), CT_bool) case_label],
+ [ijump (F_op (F_field (frag, "kind"), "!=", F_lit (V_ctor_kind (string_of_id pid))), CT_bool) case_label],
[]
| AP_global (pid, _), _ -> [icopy (CL_id pid) cval], []
| AP_id pid, (frag, ctyp) when is_ct_enum ctyp ->
@@ -1499,10 +1538,10 @@ let rec compile_match ctx apat cval case_label =
| AP_app (ctor, apat), (frag, ctyp) ->
begin match ctyp with
| CT_variant (_, ctors) ->
- let ctor_c_id = Util.zencode_string (string_of_id ctor) in
+ let ctor_c_id = string_of_id ctor in
let ctor_ctyp = Bindings.find ctor (ctor_bindings ctors) in
- let instrs, cleanup = compile_match ctx apat ((F_field (frag, ctor_c_id), ctor_ctyp)) case_label in
- [ijump (F_op (F_field (frag, "kind"), "!=", F_lit ("Kind_" ^ ctor_c_id)), CT_bool) case_label]
+ let instrs, cleanup = compile_match ctx apat ((F_field (frag, Util.zencode_string ctor_c_id), ctor_ctyp)) case_label in
+ [ijump (F_op (F_field (frag, "kind"), "!=", F_lit (V_ctor_kind ctor_c_id)), CT_bool) case_label]
@ instrs,
cleanup
| _ -> failwith "AP_app constructor with non-variant type"
@@ -1512,12 +1551,12 @@ let rec compile_match ctx apat cval case_label =
| AP_cons (hd_apat, tl_apat), (frag, CT_list ctyp) ->
let hd_setup, hd_cleanup = compile_match ctx hd_apat (F_field (F_unary ("*", frag), "hd"), ctyp) case_label in
let tl_setup, tl_cleanup = compile_match ctx tl_apat (F_field (F_unary ("*", frag), "tl"), CT_list ctyp) case_label in
- [ijump (F_op (frag, "==", F_lit "NULL"), CT_bool) case_label] @ hd_setup @ tl_setup, tl_cleanup @ hd_cleanup
+ [ijump (F_op (frag, "==", F_lit V_null), CT_bool) case_label] @ hd_setup @ tl_setup, tl_cleanup @ hd_cleanup
| AP_cons _, (_, _) -> c_error "Tried to pattern match cons on non list type"
- | AP_nil, (frag, _) -> [ijump (F_op (frag, "!=", F_lit "NULL"), CT_bool) case_label], []
+ | AP_nil, (frag, _) -> [ijump (F_op (frag, "!=", F_lit V_null), CT_bool) case_label], []
-let unit_fragment = (F_lit "UNIT", CT_unit)
+let unit_fragment = (F_lit V_unit, CT_unit)
(** GLOBAL: label_counter is used to make sure all labels have unique
names. Like gensym_counter it should be safe to reset between
@@ -1557,7 +1596,7 @@ let rec compile_aexp ctx = function
let compile_case (apat, guard, body) =
let trivial_guard = match guard with
| AE_val (AV_lit (L_aux (L_true, _), _))
- | AE_val (AV_C_fragment (F_lit "true", _)) -> true
+ | AE_val (AV_C_fragment (F_lit (V_bool true), _)) -> true
| _ -> false
in
let case_label = label "case_" in
@@ -1596,7 +1635,7 @@ let rec compile_aexp ctx = function
let compile_case (apat, guard, body) =
let trivial_guard = match guard with
| AE_val (AV_lit (L_aux (L_true, _), _))
- | AE_val (AV_C_fragment (F_lit "true", _)) -> true
+ | AE_val (AV_C_fragment (F_lit (V_bool true), _)) -> true
| _ -> false
in
let try_label = label "try_" in
@@ -1625,7 +1664,7 @@ let rec compile_aexp ctx = function
@ List.concat (List.map compile_case cases)
@ [imatch_failure ()]
@ [ilabel handled_exception_label]
- @ [icopy CL_have_exception (F_lit "false", CT_bool)]
+ @ [icopy CL_have_exception (F_lit (V_bool false), CT_bool)]
| AE_if (aval, then_aexp, else_aexp, if_typ) ->
let if_ctyp = ctyp_of_typ ctx if_typ in
@@ -1671,7 +1710,7 @@ let rec compile_aexp ctx = function
let gs = gensym () in
left_setup
@ [ idecl CT_bool gs;
- iif cval (right_setup @ [call (CL_id gs)] @ right_cleanup) [icopy (CL_id gs) (F_lit "false", CT_bool)] CT_bool ]
+ iif cval (right_setup @ [call (CL_id gs)] @ right_cleanup) [icopy (CL_id gs) (F_lit (V_bool false), CT_bool)] CT_bool ]
@ left_cleanup,
CT_bool,
(fun clexp -> icopy clexp (F_id gs, CT_bool)),
@@ -1682,7 +1721,7 @@ let rec compile_aexp ctx = function
let gs = gensym () in
left_setup
@ [ idecl CT_bool gs;
- iif cval [icopy (CL_id gs) (F_lit "true", CT_bool)] (right_setup @ [call (CL_id gs)] @ right_cleanup) CT_bool ]
+ iif cval [icopy (CL_id gs) (F_lit (V_bool true), CT_bool)] (right_setup @ [call (CL_id gs)] @ right_cleanup) CT_bool ]
@ left_cleanup,
CT_bool,
(fun clexp -> icopy clexp (F_id gs, CT_bool)),
@@ -1996,7 +2035,7 @@ let fix_exception_block ctx instrs =
| before, I_aux (I_throw cval, _) :: after ->
before
@ [icopy CL_current_exception cval;
- icopy CL_have_exception (F_lit "true", CT_bool)]
+ icopy CL_have_exception (F_lit (V_bool true), CT_bool)]
@ generate_cleanup (historic @ before)
@ [igoto end_block_label]
@ rewrite_exception (historic @ before) after
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem
index 4d67cbfc..fce595e0 100644
--- a/src/gen_lib/sail_values.lem
+++ b/src/gen_lib/sail_values.lem
@@ -108,6 +108,12 @@ let showBitU = function
| BU -> "U"
end
+let bitU_char = function
+ | B0 -> #'0'
+ | B1 -> #'1'
+ | BU -> #'?'
+end
+
instance (Show bitU)
let show = showBitU
end
@@ -307,7 +313,7 @@ declare {isabelle} termination_argument hexstring_of_bits = automatic
let show_bitlist bs =
match hexstring_of_bits bs with
| Just s -> toString (#'0' :: #'x' :: s)
- | Nothing -> show bs
+ | Nothing -> toString (#'0' :: #'b' :: map bitU_char bs)
end
(*** List operations *)
diff --git a/src/gen_lib/sail_values.ml b/src/gen_lib/sail_values.ml
deleted file mode 100644
index 213acea1..00000000
--- a/src/gen_lib/sail_values.ml
+++ /dev/null
@@ -1,1488 +0,0 @@
-open Big_int_Z
-open Printf
-
-let trace_writes = ref false
-let tracef = printf
-
-(* only expected to be 0, 1, 2; 2 represents undef *)
-type vbit = Vone | Vzero | Vundef
-type number = Big_int_Z.big_int
-
-type _bool = vbit
-type _string = string
-type _nat = number
-type _int = number
-
-let undef_val = ref Vundef
-
-type value =
- | Vvector of vbit array * int * bool
- | VvectorR of value array * int * bool
- | Vregister of vbit array ref * int * bool * string * (string * (int * int)) list
- | Vbit of vbit (*Mostly for Vundef in place of undefined register place holders*)
-
-exception Sail_exit
-exception Sail_return
-
-let _print s = print_string s
-
-let string_of_bit = function
- | Vone -> "1"
- | Vzero -> "0"
- | Vundef -> "u"
-
-let bit_of_string = function
- | "1" -> Vone
- | "0" -> Vzero
- | "u" -> Vundef
- | _ -> failwith "invalid bit value"
-
-let string_of_bit_array a = Array.fold_left (^) "" (Array.map string_of_bit a)
-
-let string_of_value = function
- | Vvector(bits, start, inc) -> (string_of_int start) ^ (if inc then "inc" else "dec") ^ (string_of_bit_array bits)
- | VvectorR(values, start, inc) -> ""
- | Vregister(bits, start, inc, name, fields) -> "reg" ^ (string_of_int start) ^ (if inc then "inc" else "dec") ^ (string_of_bit_array !bits)
- | Vbit(b) -> string_of_bit b
-
-let to_bool = function
- | Vzero -> false
- | Vone -> true
- | Vundef -> assert false
-
-let is_one i =
- if eq_big_int i unit_big_int
- then Vone
- else Vzero
-
-
-let exit _ = raise Sail_exit
-
-
-let is_one_int i =
- if i = 1 then Vone else Vzero
-
-let get_barray = function
- | Vvector(a,_,_) -> a
- | Vregister(a,_,_,_,_) -> !a
- | _ -> assert false
-
-let get_varray = function
- | VvectorR(a,_,_) -> a
- | _ -> assert false
-
-let get_ord = function
- | Vvector(_,_,o) | Vregister(_,_,o,_,_) | VvectorR(_,_,o) -> o
- | _ -> assert false
-
-let get_start = function
- | Vvector(_,s,o) | Vregister(_,s,o,_,_) | VvectorR(_,s,o) -> s
- | _ -> assert false
-
-let set_start i = function
- | Vvector(a,start,dir) -> Vvector(a,i,dir)
- | Vregister(bits,start,dir,name,regfields) -> Vregister(bits,i,dir,name,regfields)
- | VvectorR(a,start,dir) -> VvectorR(a,i,dir)
- | _ -> assert false
-
-let length_int = function
- | Vvector(array,_,_) -> Array.length array
- | Vregister(array,_,_,_,_) -> Array.length !array
- | VvectorR(array,_,_) -> Array.length array
- | _ -> assert false
-
-let set_start_to_length v = set_start ((length_int v)-1) v (* XXX should take account of direction? *)
-
-let length_big v = big_int_of_int (length_int v)
-let length = length_big
-
-let read_register = function
- | Vregister(a,start,inc,_,_) -> Vvector(!a,start,inc)
- | v -> v
-
-let vector_access_int v n =
- match v with
- | VvectorR(array,start,is_inc) ->
- if is_inc
- then (array.(n-start))
- else (array.(start-n))
- | _ -> assert false
-
-let vector_access_big v n = vector_access_int v (int_of_big_int n)
-
-let vector_access = vector_access_big
-
-let bit_vector_access_int v n = match v with
- | Vvector(array,start,is_inc) ->
- if is_inc
- then array.(n-start)
- else array.(start-n)
- | Vregister(array,start,is_inc,_,_) ->
- if is_inc
- then !array.(n-start)
- else !array.(start-n)
- | _ -> assert false
-
-let bit_vector_access_big v n = bit_vector_access_int v (int_of_big_int n)
-let bit_vector_access = bit_vector_access_big
-
-let vector_subrange_int v n m =
- (*Printf.printf "vector_subrange %s %d %d\n" (string_of_value v) n m;*)
- match v with
- | VvectorR(array,start,is_inc) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- VvectorR(Array.sub array offset length,n,is_inc)
- | Vvector(array,start,is_inc) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- Vvector(Array.sub array offset length,n,is_inc)
- | Vregister(array,start,is_inc,name,fields) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- Vvector(Array.sub !array offset length,n,is_inc)
- | _ -> v
-
-let vector_subrange_big v n m = vector_subrange_int v (int_of_big_int n) (int_of_big_int m)
-let vector_subrange = vector_subrange_big
-
-let get_register_field_vec reg field =
- match reg with
- | Vregister(_,_,_,name,fields) ->
- (match List.assoc field fields with
- | (i,j) ->
- if i = j
- then Vbit Vundef
- else vector_subrange_int reg i j)
- | _ -> Vbit Vundef
-
-let get_register_field_bit reg field =
- match reg with
- | Vregister(_,_,_,name,fields) ->
- (match List.assoc field fields with
- | (i,j) ->
- if i = j
- then bit_vector_access_int reg i
- else Vundef)
- | _ -> Vundef
-
-let set_register register value = match register,value with
- | Vregister(a,_,_,name,_), Vregister(new_v,_,_,_,_) ->
- begin
- if !trace_writes then
- tracef "%s <- %s\n" name (string_of_value value);
- a := !new_v
- end
- | Vregister(a,_,_,name,_), Vvector(new_v,_,_) ->
- begin
- if !trace_writes then
- tracef "%s <- %s\n" name (string_of_value value);
- a := new_v
- end
- | _ -> failwith "set_register of non-register"
-
-let set_vector_subrange_vec_int v n m new_v =
- let walker array length offset new_values =
- begin
- for x = 0 to length-1
- do array.(x+offset) <- new_values.(x)
- done;
- end
- in
- match v, new_v with
- | VvectorR(array,start,is_inc),VvectorR(new_v,_,_) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- walker array length offset new_v
- | _ -> ()
-
-let set_vector_subrange_vec_big v n m new_v =
- set_vector_subrange_vec_int v (int_of_big_int n) (int_of_big_int m) new_v
-let set_vector_subrange_vec = set_vector_subrange_vec_big (* or maybe _int *)
-
-let set_vector_subrange_bit_int v n m new_v =
- let walker array length offset new_values =
- begin
- for x = 0 to length-1
- do array.(x+offset) <- new_values.(x)
- done;
- end
- in
- match v,new_v with
- | Vvector(array,start,is_inc),Vvector(new_v,_,_) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- walker array length offset new_v
- | Vregister(array,start,is_inc,name,fields),Vvector(new_v,_,_) ->
- let (length,offset) = if is_inc then (m-n+1,n-start) else (n-m+1,start-n) in
- walker !array length offset new_v
- | _ -> ()
-
-let set_vector_subrange_bit_big v n m new_v =
- set_vector_subrange_bit_int v (int_of_big_int n) (int_of_big_int m) new_v
-let set_vector_subrange_bit = set_vector_subrange_bit_big
-
-let set_register_bit_int reg n v =
- match reg with
- | Vregister(array,start,inc,name,fields) ->
- begin
- if !trace_writes then
- tracef "%s[%d] <- %s\n" name n (string_of_bit v);
- (!array).(if inc then (n - start) else (start - n)) <- v
- end
- | _ -> failwith "set_register_bit of non-register"
-let set_register_bit_big reg n v = set_register_bit_int reg (int_of_big_int n) v
-let set_register_bit = set_register_bit_big
-
-let set_register_field_v reg field new_v =
- match reg with
- | Vregister(array,start,dir,name,fields) ->
- begin
- if !trace_writes then
- tracef "%s[%s] <- %s\n" name field (string_of_value new_v);
- (match List.assoc field fields with
- | (i,j) ->
- if i = j
- then ()
- else set_vector_subrange_bit_int reg i j new_v)
- end
- | _ -> ()
-
-let set_register_field_bit reg field new_v =
- match reg with
- | Vregister(array,start,dir,name,fields) ->
- begin
- if !trace_writes then
- tracef "%s.%s <- %s\n" name field (string_of_bit new_v);
- (match List.assoc field fields with
- | (i,j) ->
- if i = j
- then !array.(if dir then i - start else start - i) <- new_v
- else ())
- end
- | _ -> ()
-
-let set_two_reg r1 r2 vec =
- let size = length_int r1 in
- let dir = get_ord r1 in
- let start = get_start vec in
- let vsize = length_int vec in
- let r1_v = vector_subrange_int vec start ((if dir then size - start else start - size) - 1) in
- let r2_v = vector_subrange_int vec (if dir then size - start else start - size)
- (if dir then vsize - start else start - vsize) in
- begin set_register r1 r1_v; set_register r2 r2_v end
-
-
-let make_indexed_v entries default start size dir =
- let default_value = match default with
- | None -> Vbit Vundef
- | Some v -> v in
- let array = Array.make size default_value in
- begin
- List.iter (fun (i,v) -> array.(if dir then start - i else i - start) <- v) entries;
- VvectorR(array, start, dir)
- end
-
-let make_indexed_v_big entries default start size dir =
- make_indexed_v entries default (int_of_big_int start) (int_of_big_int size) dir
-
-let make_indexed_bitv entries default start size dir =
- let default_value = match default with
- | None -> Vundef
- | Some v -> v in
- let array = Array.make size default_value in
- begin
- List.iter (fun (i,v) -> array.(if dir then start - i else i - start) <- v) entries;
- Vvector(array, start, dir)
- end
-
-let make_indexed_bitv_big entries default start size dir =
- make_indexed_bitv entries default (int_of_big_int start) (int_of_big_int size) dir
-
-let vector_concat l r =
- match l,r with
- | Vvector(arrayl,start,ord), Vvector(arrayr,_,_) ->
- Vvector(Array.append arrayl arrayr, start, ord)
- | Vvector(arrayl,start,ord), Vregister(arrayr,_,_,_,_) ->
- Vvector(Array.append arrayl !arrayr, start,ord)
- | Vregister(arrayl,start,ord,_,_), Vvector(arrayr,_,_) ->
- Vvector(Array.append !arrayl arrayr, start, ord)
- | Vregister(arrayl,start,ord,_,_), Vregister(arrayr,_,_,_,_) ->
- Vvector(Array.append !arrayl !arrayr,start,ord)
- | VvectorR(arrayl,start,ord),VvectorR(arrayr,_,_) ->
- VvectorR(Array.append arrayl arrayr, start,ord)
- | _ -> Vbit Vundef
-
-let has_undef = function
- | Vvector(array,_,_) ->
- let rec foreach i = (* XXX ideally would use Array.mem but not in ocaml 4.02.3 *)
- if i < Array.length array
- then
- if array.(i) = Vundef then true
- else foreach (i+1)
- else false in
- foreach 0
- | Vregister(array,_,_,_,_) ->
- let array = !array in
- let rec foreach i =
- if i < Array.length array
- then
- if array.(i) = Vundef then true
- else foreach (i+1)
- else false in
- foreach 0
- | _ -> false
-
-let most_significant = function
- | Vvector(array,_,_) -> array.(0)
- | Vregister(array,_,_,_,_) -> !array.(0)
- | _ -> assert false
-
-let _most_significant = most_significant
-
-let bitwise_not_bit = function
- | Vone -> Vzero
- | Vzero -> Vone
- | _ -> Vundef
-
-let bitwise_not = function
- | Vvector(array,s,d)-> Vvector( Array.map bitwise_not_bit array,s,d)
- | Vregister(array,s,d,_,_) -> Vvector( Array.map bitwise_not_bit !array,s,d)
- | _ -> assert false
-
-let bool_to_bit b = if b then Vone else Vzero
-
-let bitwise_binop_bit op (l,r) =
- match l,r with
- | Vundef,_ | _,Vundef -> Vundef (*Do we want to do this or to respect | of One and & of Zero rules?*)
- | Vone,Vone -> bool_to_bit (op true true)
- | Vone,Vzero -> bool_to_bit (op true false)
- | Vzero,Vone -> bool_to_bit (op false true)
- | Vzero,Vzero -> bool_to_bit (op false false)
-
-let bitwise_and_bit = bitwise_binop_bit (&&)
-let bitwise_or_bit = bitwise_binop_bit (||)
-let bitwise_xor_bit = bitwise_binop_bit (<>)
-
-let bitwise_binop op (l,r) =
- let bop l arrayl arrayr =
- let array = Array.make l Vzero in
- begin
- for i = 0 to (l-1) do
- array.(i) <- bitwise_binop_bit op (arrayl.(i), arrayr.(i))
- done;
- array
- end in
- match l,r with
- | Vvector(arrayl, start, dir), Vvector(arrayr,_,_) ->
- Vvector(bop (Array.length arrayl) arrayl arrayr, start,dir)
- | Vvector(arrayl, start, dir), Vregister(arrayr,_,_,_,_) ->
- Vvector(bop (Array.length arrayl) arrayl !arrayr, start, dir)
- | Vregister(arrayl, start,dir,_,_), Vvector(arrayr,_,_) ->
- Vvector(bop (Array.length arrayr) !arrayl arrayr, start,dir)
- | Vregister(arrayl, start, dir, _, _), Vregister(arrayr,_,_,_,_) ->
- Vvector(bop (Array.length !arrayl) !arrayl !arrayr, start,dir)
- | _ -> Vbit Vundef
-
-let bitwise_and = bitwise_binop (&&)
-let bitwise_or = bitwise_binop (||)
-let bitwise_xor = bitwise_binop (<>)
-
-let rec power_int base raiseto =
- if raiseto = 0
- then 1
- else base * (power_int base (raiseto - 1))
-
-let int_of_bit_array array =
- let acc = ref 0 in
- let len = Array.length array in
- begin
- for i = 0 to len - 1 do
- acc := (!acc) lsl 1;
- match array.(i) with
- | Vone -> acc := succ (!acc)
- | _ -> ()
- done;
- !acc
- end
-
-let unsigned_int = function
- | (Vvector(array,_,_) as v) ->
- if has_undef v
- then assert false
- else int_of_bit_array array
- | (Vregister(array,_,_,_,_) as v)->
- let array = !array in
- if has_undef v
- then assert false
- else int_of_bit_array array
- | _ -> assert false
-
-let big_int_of_bit_array array =
- let acc = ref zero_big_int in
- let len = Array.length array in
- begin
- for i = 0 to len - 1 do
- acc := shift_left_big_int !acc 1;
- match array.(i) with
- | Vone -> acc := succ_big_int !acc
- | _ -> ();
- done;
- !acc
- end
-
-let unsigned_big = function
- | (Vvector(array,_,_) as v) ->
- if has_undef v
- then assert false
- else
- big_int_of_bit_array array
- | (Vregister(array,_,_,_,_) as v)->
- let array = !array in
- if has_undef v
- then assert false
- else
- big_int_of_bit_array array
- | _ -> assert false
-
-let unsigned = unsigned_big
-
-let signed_int v =
- match most_significant v with
- | Vone -> -(1 + (unsigned_int (bitwise_not v)))
- | Vzero -> unsigned_int v
- | _ -> assert false
-
-let signed_big v =
- match most_significant v with
- | Vone -> minus_big_int(add_int_big_int 1 (unsigned_big (bitwise_not v)))
- | Vzero -> unsigned_big v
- | _ -> assert false
-
-let signed = signed_big
-
-let to_num_int sign = if sign then signed_int else unsigned_int
-let to_num_big sign = if sign then signed_big else unsigned_big
-let to_num = to_num_big
-
-let two_big_int = big_int_of_int 2
-let max_64u = pred_big_int (power_big two_big_int (big_int_of_int 64))
-let max_64 = pred_big_int (power_big two_big_int (big_int_of_int 63))
-let min_64 = minus_big_int (power_big two_big_int (big_int_of_int 63))
-let max_32u = big_int_of_int 4294967295
-let max_32 = big_int_of_int 2147483647
-let min_32 = big_int_of_int (-2147483648)
-let max_8 = big_int_of_int 127
-let min_8 = big_int_of_int (-128)
-let max_5 = big_int_of_int 31
-
-let get_max_representable_in sign n =
- match (sign, n) with
- | (true, 64) -> max_64
- | (false, 64) -> max_64u
- | (true, 32) -> max_32
- | (false, 32) -> max_32u
- | (true, 8) -> max_8
- | (false, 5) -> max_5
- | (true, _) -> pred_big_int (power_big two_big_int (big_int_of_int (n-1)))
- | (false, _) -> pred_big_int (power_big two_big_int (big_int_of_int n))
-
-let get_min_representable_in sign n =
- match (sign, n) with
- | (false, _) -> zero_big_int
- | (true, 64) -> min_64
- | (true, 32) -> min_32
- | (true, 8) -> min_8
- | (true, _) -> minus_big_int (power_big two_big_int (big_int_of_int (n-1)))
-
-let to_vec_int ord len n =
- let array = Array.make len Vzero in
- let start = if ord then 0 else len-1 in
- let acc = ref n in
- for i = (len - 1) downto 0 do
- if ((!acc) land 1) = 1 then
- array.(i) <- Vone;
- acc := (!acc) asr 1
- done;
- Vvector(array, start, ord)
-
-let to_vec_big ord len n =
- let len = int_of_big_int len in
- let array = Array.make len Vzero in
- let start = if ord then 0 else len-1 in
- if eq_big_int n zero_big_int
- then Vvector(array, start, ord)
- else
- begin
- for i = 0 to len - 1 do
- if ((extract_big_int n (len - 1 - i) 1) == unit_big_int) then
- array.(i) <- Vone
- done;
- Vvector(array, start, ord)
- end
-
-let to_vec_inc_int (len,n) = to_vec_int true len n
-let to_vec_dec_int (len,n) = to_vec_int false len n
-
-let to_vec_inc_big (len,n) = to_vec_big true len n
-let to_vec_dec_big (len,n) = to_vec_big false len n
-
-let to_vec_inc = to_vec_inc_big
-let to_vec_dec = to_vec_dec_big
-
-let to_vec_undef_int ord len =
- let array = Array.make len !undef_val in
- let start = if ord then 0 else len-1 in
- Vvector(array, start, ord)
-
-let to_vec_undef_big ord len =
- let len = int_of_big_int len in
- let array = Array.make len !undef_val in
- let start = if ord then 0 else len-1 in
- Vvector(array, start, ord)
-
-let to_vec_inc_undef_int len = to_vec_undef_int true len
-let to_vec_dec_undef_int len = to_vec_undef_int false len
-
-let to_vec_inc_undef_big len = to_vec_undef_big true len
-let to_vec_dec_undef_big len = to_vec_undef_big false len
-
-let to_vec_inc_undef = to_vec_inc_undef_big
-let to_vec_dec_undef = to_vec_dec_undef_big
-
-let exts_int (len, vec) =
- let barray = get_barray(vec) in
- let vlen = Array.length barray in
- let arr =
- if (vlen < len) then
- (* copy most significant bit into new bits *)
- Array.append (Array.make (len - vlen) barray.(0)) barray
- else
- (* truncate to least significant bits *)
- Array.sub barray (vlen - len) len in
- let inc = get_ord vec in
- Vvector(arr, (if inc then 0 else (len - 1)), inc)
-
-let extz_int (len, vec) =
- let barray = get_barray(vec) in
- let vlen = Array.length barray in
- let arr =
- if (vlen < len) then
- (* fill new bits with zero *)
- Array.append (Array.make (len - vlen) Vzero) barray
- else
- (* truncate to least significant bits *)
- Array.sub barray (vlen - len) len in
- let inc = get_ord vec in
- Vvector(arr, (if inc then 0 else (len - 1)), inc)
-
-let exts_big (len,vec) = exts_int (int_of_big_int len, vec)
-let extz_big (len,vec) = extz_int (int_of_big_int len, vec)
-
-let exts = exts_big
-let extz = extz_big
-
-let arith_op op (l,r) = op l r
-let add_big = arith_op add_big_int
-let add_signed_big = arith_op add_big_int
-let minus_big = arith_op sub_big_int
-let multiply_big = arith_op mult_big_int
-let min_big = arith_op min_big_int
-let max_big = arith_op max_big_int
-(* NB Z.div is what we want because it does truncation towards zero unlike Big_int_Z.div_big_int == Z.ediv *)
-let quot_big = arith_op (Z.div)
-let modulo_big = arith_op (Z.rem)
-
-let power_big = arith_op power_big
-
-let add_int = arith_op (+)
-let add_signed_int = arith_op (+)
-let minus_int = arith_op (-)
-let multiply_int = arith_op ( * )
-let modulo_int = arith_op (mod)
-let quot_int = arith_op (/)
-
-let power_int = arith_op power_int
-
-let add = add_big
-let add_signed = add_signed_big
-let minus = minus_big
-let multiply = multiply_big
-let modulo = modulo_big
-let quot = quot_big
-let power = power_big
-let min_int = min (* the built-in version *)
-let min = min_big (* is overwritten here *)
-let max_int = max (* likewise *)
-let max = max_big
-let abs_int = abs
-let abs_big = abs_big_int
-let abs = abs_big
-
-let arith_op_vec_big op sign size (l,r) =
- let ord = get_ord l in
- let (l',r') = to_num_big sign l, to_num_big sign r in
- let n = arith_op op (l',r') in
- to_vec_big ord (mult_big_int size (length_big l)) n
-
-let add_vec_big = arith_op_vec_big add_big_int false unit_big_int
-let add_vec_signed_big = arith_op_vec_big add_big_int true unit_big_int
-let minus_vec_big = arith_op_vec_big sub_big_int false unit_big_int
-let multiply_vec_big = arith_op_vec_big mult_big_int false two_big_int
-let multiply_vec_signed_big = arith_op_vec_big mult_big_int true two_big_int
-
-let arith_op_vec_int op sign size (l,r) =
- let ord = get_ord l in
- let (l',r') = to_num_int sign l, to_num_int sign r in
- let n = arith_op op (l',r') in
- to_vec_int ord (size * (length_int l)) n
-
-let add_vec_int = arith_op_vec_int (+) false 1
-let add_vec_signed_int = arith_op_vec_int (+) true 1
-let minus_vec_int = arith_op_vec_int (-) false 1
-let multiply_vec_int = arith_op_vec_int ( * ) false 2
-let multiply_vec_signed_int = arith_op_vec_int ( * ) true 2
-
-let add_vec = add_vec_big
-let add_vec_signed = add_vec_signed_big
-let minus_vec = minus_vec_big
-let multiply_vec = multiply_vec_big
-let multiply_vec_signed = multiply_vec_signed_big
-
-
-let arith_op_vec_range_int op sign size (l,r) =
- let ord = get_ord l in
- arith_op_vec_int op sign size (l, to_vec_int ord (length_int l) r)
-
-let add_vec_range_int = arith_op_vec_range_int (+) false 1
-let add_vec_range_signed_int = arith_op_vec_range_int (+) true 1
-let minus_vec_range_int = arith_op_vec_range_int (-) false 1
-let mult_vec_range_int = arith_op_vec_range_int ( * ) false 2
-let mult_vec_range_signed_int = arith_op_vec_range_int ( * ) true 2
-
-let arith_op_vec_range_big op sign size (l,r) =
- let ord = get_ord l in
- arith_op_vec_big op sign size (l, to_vec_big ord (length_big l) r)
-
-let add_vec_range_big = arith_op_vec_range_big add_big_int false unit_big_int
-let add_vec_range_signed_big = arith_op_vec_range_big add_big_int true unit_big_int
-let minus_vec_range_big = arith_op_vec_range_big sub_big_int false unit_big_int
-let mult_vec_range_big = arith_op_vec_range_big mult_big_int false two_big_int
-let mult_vec_range_signed_big = arith_op_vec_range_big mult_big_int true two_big_int
-
-let add_vec_range = add_vec_range_big
-let add_vec_range_signed = add_vec_range_signed_big
-let minus_vec_range = minus_vec_range_big
-let mult_vec_range = mult_vec_range_big
-let mult_vec_range_signed = mult_vec_range_signed_big
-
-let arith_op_range_vec_int op sign size (l,r) =
- let ord = get_ord r in
- arith_op_vec_int op sign size ((to_vec_int ord (length_int r) l), r)
-
-let add_range_vec_int = arith_op_range_vec_int (+) false 1
-let add_range_vec_signed_int = arith_op_range_vec_int (+) true 1
-let minus_range_vec_int = arith_op_range_vec_int (-) false 1
-let mult_range_vec_int = arith_op_range_vec_int ( * ) false 2
-let mult_range_vec_signed_int = arith_op_range_vec_int ( * ) true 2
-
-let arith_op_range_vec_big op sign size (l,r) =
- let ord = get_ord r in
- arith_op_vec_big op sign size ((to_vec_big ord (length_big r) l), r)
-
-let add_range_vec_big = arith_op_range_vec_big add_big_int false unit_big_int
-let add_range_vec_signed_big = arith_op_range_vec_big add_big_int true unit_big_int
-let minus_range_vec_big = arith_op_range_vec_big sub_big_int false unit_big_int
-let mult_range_vec_big = arith_op_range_vec_big mult_big_int false two_big_int
-let mult_range_vec_signed_big = arith_op_range_vec_big mult_big_int true two_big_int
-
-let add_range_vec = add_range_vec_big
-let add_range_vec_signed = add_range_vec_signed_big
-let minus_range_vec = minus_range_vec_big
-let mult_range_vec = mult_range_vec_big
-let mult_range_vec_signed = mult_range_vec_signed_big
-
-
-let arith_op_range_vec_range_int op sign (l,r) = arith_op op (l, to_num_int sign r)
-
-let add_range_vec_range_int = arith_op_range_vec_range_int (+) false
-let add_range_vec_range_signed_int = arith_op_range_vec_range_int (+) true
-let minus_range_vec_range_int = arith_op_range_vec_range_int (-) false
-
-let arith_op_range_vec_range_big op sign (l,r) = arith_op op (l, to_num_big sign r)
-
-let add_range_vec_range_big = arith_op_range_vec_range_big add_big_int false
-let add_range_vec_range_signed_big = arith_op_range_vec_range_big add_big_int true
-let minus_range_vec_range_big = arith_op_range_vec_range_big sub_big_int false
-
-let add_range_vec_range = add_range_vec_range_big
-let add_range_vec_range_signed = add_range_vec_range_signed_big
-let minus_range_vec_range = minus_range_vec_range_big
-
-let arith_op_vec_range_range_int op sign (l,r) = arith_op op (to_num_int sign l,r)
-
-let add_vec_range_range_int = arith_op_vec_range_range_int (+) false
-let add_vec_range_range_signed_int = arith_op_vec_range_range_int (+) true
-let minus_vec_range_range_int = arith_op_vec_range_range_int (-) false
-
-let arith_op_vec_range_range_big op sign (l,r) = arith_op op (to_num_big sign l,r)
-
-let add_vec_range_range_big = arith_op_vec_range_range_big add_big_int false
-let add_vec_range_range_signed_big = arith_op_vec_range_range_big add_big_int true
-let minus_vec_range_range_big = arith_op_vec_range_range_big sub_big_int false
-
-let add_vec_range_range = add_vec_range_range_big
-let add_vec_range_range_signed = add_vec_range_range_signed_big
-let minus_vec_range_range = minus_vec_range_range_big
-
-
-let arith_op_vec_vec_range_int op sign (l,r) =
- let (l',r') = (to_num_int sign l,to_num_int sign r) in
- arith_op op (l',r')
-
-let add_vec_vec_range_int = arith_op_vec_vec_range_int (+) false
-let add_vec_vec_range_signed_int = arith_op_vec_vec_range_int (+) true
-
-let arith_op_vec_vec_range_big op sign (l,r) =
- let (l',r') = (to_num_big sign l,to_num_big sign r) in
- arith_op op (l',r')
-
-let add_vec_vec_range_big = arith_op_vec_vec_range_big add_big_int false
-let add_vec_vec_range_signed_big = arith_op_vec_vec_range_big add_big_int true
-
-let add_vec_vec_range = add_vec_vec_range_big
-let add_vec_vec_range_signed = add_vec_vec_range_signed_big
-
-let arith_op_vec_bit_int op sign (l,r) =
- let ord = get_ord l in
- let l' = to_num_int sign l in
- let n = arith_op op (l', match r with | Vone -> 1 | _ -> 0) in
- to_vec_int ord (length_int l) n
-
-let add_vec_bit_int = arith_op_vec_bit_int (+) false
-let add_vec_bit_signed_int = arith_op_vec_bit_int (+) true
-let minus_vec_bit_int = arith_op_vec_bit_int (-) true
-
-let arith_op_vec_bit_big op sign (l,r) =
- let ord = get_ord l in
- let l' = to_num_big sign l in
- let n = arith_op op (l', match r with | Vone -> unit_big_int | _ -> zero_big_int) in
- to_vec_big ord (length_big l) n
-
-let add_vec_bit_big = arith_op_vec_bit_big add_big_int false
-let add_vec_bit_signed_big = arith_op_vec_bit_big add_big_int true
-let minus_vec_bit_big = arith_op_vec_bit_big sub_big_int true
-
-let add_vec_bit = add_vec_bit_big
-let add_vec_bit_signed = add_vec_bit_signed_big
-let minus_vec_bit = minus_vec_bit_big
-
-
-let rec arith_op_overflow_vec_int op sign size (l,r) =
- let ord = get_ord l in
- let len = length_int l in
- let act_size = len * size in
- let (l_sign,r_sign) = (to_num_int sign l,to_num_int sign r) in
- let (l_unsign,r_unsign) = (to_num_int false l,to_num_int false r) in
- let n = arith_op op (l_sign,r_sign) in
- let n_unsign = arith_op op (l_unsign,r_unsign) in
- let correct_size_num = to_vec_int ord act_size n in
- let one_more_size_u = to_vec_int ord (act_size +1) n_unsign in
- let overflow = if (n <= (int_of_big_int (get_max_representable_in sign len))) &&
- (n >= (int_of_big_int (get_min_representable_in sign len)))
- then Vzero
- else Vone in
- let c_out = most_significant one_more_size_u in
- (correct_size_num,overflow,c_out)
-
-let add_overflow_vec_int = arith_op_overflow_vec_int (+) false 1
-let add_overflow_vec_signed_int = arith_op_overflow_vec_int (+) true 1
-let minus_overflow_vec_int = arith_op_overflow_vec_int (-) false 1
-let minus_overflow_vec_signed_int = arith_op_overflow_vec_int (-) true 1
-let mult_overflow_vec_int = arith_op_overflow_vec_int ( * ) false 2
-let mult_overflow_vec_signed_int = arith_op_overflow_vec_int ( * ) true 2
-
-let rec arith_op_overflow_vec_big op sign size (l,r) =
- let ord = get_ord l in
- let len = length_big l in
- let act_size = mult_big_int len size in
- let (l_sign,r_sign) = (to_num_big sign l,to_num_big sign r) in
- let (l_unsign,r_unsign) = (to_num_big false l,to_num_big false r) in
- let n = arith_op op (l_sign,r_sign) in
- let n_unsign = arith_op op (l_unsign,r_unsign) in
- let correct_size_num = to_vec_big ord act_size n in
- let one_more_size_u = to_vec_big ord (succ_big_int act_size) n_unsign in
- let overflow = if (le_big_int n (get_max_representable_in sign (int_of_big_int len))) &&
- (ge_big_int n (get_min_representable_in sign (int_of_big_int len)))
- then Vzero
- else Vone in
- let c_out = most_significant one_more_size_u in
- (correct_size_num,overflow,c_out)
-
-let add_overflow_vec_big = arith_op_overflow_vec_big add_big_int false unit_big_int
-let add_overflow_vec_signed_big = arith_op_overflow_vec_big add_big_int true unit_big_int
-let minus_overflow_vec_big = arith_op_overflow_vec_big sub_big_int false unit_big_int
-let minus_overflow_vec_signed_big = arith_op_overflow_vec_big sub_big_int true unit_big_int
-let mult_overflow_vec_big = arith_op_overflow_vec_big mult_big_int false two_big_int
-let mult_overflow_vec_signed_big = arith_op_overflow_vec_big mult_big_int true two_big_int
-
-let add_overflow_vec = add_overflow_vec_big
-let add_overflow_vec_signed = add_overflow_vec_signed_big
-let minus_overflow_vec = minus_overflow_vec_big
-let minus_overflow_vec_signed = minus_overflow_vec_signed_big
-let mult_overflow_vec = mult_overflow_vec_big
-let mult_overflow_vec_signed = mult_overflow_vec_signed_big
-
-let rec arith_op_overflow_vec_bit_int op sign (l,r_bit) =
- let ord = get_ord l in
- let act_size = length_int l in
- let l' = to_num_int sign l in
- let l_u = to_num_int false l in
- let (n,nu,changed) = match r_bit with
- | Vone -> (arith_op op (l',1), arith_op op (l_u,1), true)
- | Vzero -> (l',l_u,false)
- | _ -> assert false
- in
- let correct_size_num = to_vec_int ord act_size n in
- let one_larger = to_vec_int ord (1+ act_size) nu in
- let overflow =
- if changed
- then if (n <= (int_of_big_int (get_max_representable_in sign act_size))) &&
- (n >= (int_of_big_int (get_min_representable_in sign act_size)))
- then Vzero
- else Vone
- else Vone in
- (correct_size_num,overflow,most_significant one_larger)
-
-let add_overflow_vec_bit_signed_int = arith_op_overflow_vec_bit_int (+) true
-let minus_overflow_vec_bit_int = arith_op_overflow_vec_bit_int (-) false
-let minus_overflow_vec_bit_signed_int = arith_op_overflow_vec_bit_int (-) true
-
-let rec arith_op_overflow_vec_bit_big op sign (l,r_bit) =
- let ord = get_ord l in
- let act_size = length_big l in
- let l' = to_num_big sign l in
- let l_u = to_num_big false l in
- let (n,nu,changed) = match r_bit with
- | Vone -> (arith_op op (l',unit_big_int), arith_op op (l_u,unit_big_int), true)
- | Vzero -> (l',l_u,false)
- | _ -> assert false
- in
- let correct_size_num = to_vec_big ord act_size n in
- let one_larger = to_vec_big ord (succ_big_int act_size) nu in
- let overflow =
- if changed
- then if (le_big_int n (get_max_representable_in sign (int_of_big_int act_size))) &&
- (ge_big_int n (get_min_representable_in sign (int_of_big_int act_size)))
- then Vzero
- else Vone
- else Vone in
- (correct_size_num,overflow,most_significant one_larger)
-
-let add_overflow_vec_bit_signed_big = arith_op_overflow_vec_bit_big add_big_int true
-let minus_overflow_vec_bit_big = arith_op_overflow_vec_bit_big sub_big_int false
-let minus_overflow_vec_bit_signed_big = arith_op_overflow_vec_bit_big sub_big_int true
-
-let add_overflow_vec_bit_signed = add_overflow_vec_bit_signed_big
-let minus_overflow_vec_bit = minus_overflow_vec_bit_big
-let minus_overflow_vec_bit_signed = minus_overflow_vec_bit_signed_big
-
-let shift_op_vec_int op (l,r) =
- match l with
- | Vvector(_,start,ord) | Vregister(_,start,ord,_,_) ->
- let array = match l with | Vvector(array,_,_) -> array | Vregister(array,_,_,_,_) -> !array | _ -> assert false in
- let len = Array.length array in
- (match op with
- | "<<" ->
- if (r <= len) then
- let left = Array.sub array r (len - r) in
- let right = Array.make r Vzero in
- let result = Array.append left right in
- Vvector(result, start, ord)
- else
- Vvector(Array.make len Vzero, start, ord)
- | ">>" ->
- if (r <= len) then
- let left = Array.make r Vzero in
- let right = Array.sub array 0 (len - r) in
- let result = Array.append left right in
- Vvector(result, start, ord)
- else
- Vvector(Array.make len Vzero, start, ord)
- | "<<<" ->
- let rmod = r mod len in
- let left = Array.sub array rmod (len - rmod) in
- let right = Array.sub array 0 rmod in
- let result = Array.append left right in
- Vvector(result, start, ord)
- | _ -> assert false)
- | _ -> assert false
-
-let shift_op_vec_big op (l,r) = shift_op_vec_int op (l, int_of_big_int r)
-let bitwise_leftshift_big = shift_op_vec_big "<<"
-let bitwise_rightshift_big = shift_op_vec_big ">>"
-let bitwise_rotate_big = shift_op_vec_big "<<<"
-
-let bitwise_leftshift = bitwise_leftshift_big
-let bitwise_rightshift = bitwise_rightshift_big
-let bitwise_rotate = bitwise_rotate_big
-
-let rec arith_op_no0_big op (l,r) =
- if eq_big_int r zero_big_int
- then None
- else Some (op l r)
-
-let modulo_no0_big = arith_op_no0_big (Z.rem)
-let quot_no0_big = arith_op_no0_big (Z.div)
-
-let rec arith_op_no0_int op (l,r) =
- if r = 0
- then None
- else Some (op l r)
-
-let rec arith_op_vec_no0_int op sign size (l,r) =
- let ord = get_ord l in
- let act_size = ((length_int l) * size) in
- let (l',r') = (to_num_int sign l,to_num_int sign r) in
- let n = arith_op_no0_int op (l',r') in
- let representable,n' =
- match n with
- | Some n' ->
- ((n' <= (int_of_big_int (get_max_representable_in sign act_size))) &&
- (n' >= (int_of_big_int (get_min_representable_in sign act_size)))), n'
- | _ -> false,0 in
- if representable
- then to_vec_int ord act_size n'
- else
- match l with
- | Vvector(_, start, _) | Vregister(_, start, _, _, _) ->
- Vvector((Array.make act_size Vundef), start, ord)
- | _ -> assert false
-
-let mod_vec_int = arith_op_vec_no0_int (mod) false 1
-let quot_vec_int = arith_op_vec_no0_int (/) false 1
-let quot_vec_signed_int = arith_op_vec_no0_int (/) true 1
-
-let rec arith_op_vec_no0_big op sign size (l,r) =
- let ord = get_ord l in
- let act_size = int_of_big_int (mult_int_big_int (length_int l) size) in
- let (l',r') = (to_num_big sign l,to_num_big sign r) in
- let n = arith_op_no0_big op (l',r') in
- let representable,n' =
- match n with
- | Some n' ->
- ((le_big_int n' (get_max_representable_in sign act_size)) &&
- (ge_big_int n' (get_min_representable_in sign act_size))), n'
- | _ -> false,zero_big_int in
- if representable
- then to_vec_big ord (big_int_of_int act_size) n'
- else
- match l with
- | Vvector(_, start, _) | Vregister(_, start, _, _, _) ->
- Vvector((Array.make act_size Vundef), start, ord)
- | _ -> assert false
-
-let mod_vec_big = arith_op_vec_no0_big (Z.rem) false unit_big_int
-let quot_vec_big = arith_op_vec_no0_big (Z.div) false unit_big_int
-let quot_vec_signed_big = arith_op_vec_no0_big (Z.div) true unit_big_int
-
-let mod_vec = mod_vec_big
-let quot_vec = quot_vec_big
-let quot_vec_signed = quot_vec_signed_big
-
-let arith_op_overflow_no0_vec_int op sign size (l,r) =
- let ord = get_ord l in
- let rep_size = (length_int r) * size in
- let act_size = (length_int l) * size in
- let (l',r') = ((to_num_int sign l),(to_num_int sign r)) in
- let (l_u,r_u) = (to_num_int false l,to_num_int false r) in
- let n = arith_op_no0_int op (l',r') in
- let n_u = arith_op_no0_int op (l_u,r_u) in
- let representable,n',n_u' =
- match n, n_u with
- | Some n',Some n_u' ->
- ((n' <= (int_of_big_int (get_max_representable_in sign rep_size))) &&
- (n' >= (int_of_big_int (get_min_representable_in sign rep_size))), n', n_u')
- | _ -> true,0,0 in
- let (correct_size_num,one_more) =
- if representable then
- (to_vec_int ord act_size n',to_vec_int ord (1+act_size) n_u')
- else match l with
- | Vvector(_, start, _) | Vregister(_, start, _, _, _) ->
- Vvector((Array.make act_size Vundef), start, ord),
- Vvector((Array.make (act_size + 1) Vundef), start, ord)
- | _ -> assert false in
- let overflow = if representable then Vzero else Vone in
- (correct_size_num,overflow,most_significant one_more)
-
-let quot_overflow_vec_int = arith_op_overflow_no0_vec_int (/) false 1
-let quot_overflow_vec_signed_int = arith_op_overflow_no0_vec_int (/) true 1
-
-let arith_op_overflow_no0_vec_big op sign size (l,r) =
- let ord = get_ord l in
- let rep_size = mult_big_int (length_big r) size in
- let act_size = mult_big_int (length_big l) size in
- let (l',r') = ((to_num_big sign l),(to_num_big sign r)) in
- let (l_u,r_u) = (to_num_big false l,to_num_big false r) in
- let n = arith_op_no0_big op (l',r') in
- let n_u = arith_op_no0_big op (l_u,r_u) in
- let representable,n',n_u' =
- match n, n_u with
- | Some n',Some n_u' ->
- ((le_big_int n' (get_max_representable_in sign (int_of_big_int rep_size))) &&
- (ge_big_int n' (get_min_representable_in sign (int_of_big_int rep_size))), n', n_u')
- | _ -> true,zero_big_int,zero_big_int in
- let (correct_size_num,one_more) =
- if representable then
- (to_vec_big ord act_size n',to_vec_big ord (succ_big_int act_size) n_u')
- else match l with
- | Vvector(_, start, _) | Vregister(_, start, _, _, _) ->
- Vvector((Array.make (int_of_big_int act_size) Vundef), start, ord),
- Vvector((Array.make ((int_of_big_int act_size) + 1) Vundef), start, ord)
- | _ -> assert false in
- let overflow = if representable then Vzero else Vone in
- (correct_size_num,overflow,most_significant one_more)
-
-let quot_overflow_vec_big = arith_op_overflow_no0_vec_big (Z.div) false unit_big_int
-let quot_overflow_vec_signed_big = arith_op_overflow_no0_vec_big (Z.div) true unit_big_int
-
-let quot_overflow_vec = quot_overflow_vec_big
-let quot_overflow_vec_signed = quot_overflow_vec_signed_big
-
-
-let arith_op_vec_range_no0_int op sign size (l,r) =
- let ord = get_ord l in
- arith_op_vec_no0_int op sign size (l,(to_vec_int ord (length_int l) r))
-
-let mod_vec_range_int = arith_op_vec_range_no0_int (mod) false 1
-
-let arith_op_vec_range_no0_big op sign size (l,r) =
- let ord = get_ord l in
- arith_op_vec_no0_big op sign size (l,(to_vec_big ord (length_big l) r))
-
-let mod_vec_range_big = arith_op_vec_range_no0_big (Z.rem) false unit_big_int
-
-let mod_vec_range = mod_vec_range_big
-
-(* XXX Need to have a default top level direction reference I think*)
-let duplicate_int (bit,length) =
- Vvector((Array.make length bit), (length-1), false)
-
-let duplicate_big (bit,length) =
- duplicate_int (bit, int_of_big_int length)
-
-let duplicate = duplicate_big
-
-let duplicate_bits_big (bits, x) =
- let len = (length_int bits) * (int_of_big_int x) in
- let is_inc = get_ord bits in
- let bits_arr = get_barray bits in
- let arr = Array.concat (Array.to_list(Array.make (int_of_big_int x) bits_arr)) in
- Vvector(arr, (if is_inc then 0 else (len - 1)), is_inc)
-
-let duplicate_bits = duplicate_bits_big
-
-let compare_op op (l,r) =
- if (op l r)
- then Vone
- else Vzero
-
-let lt_big = compare_op lt_big_int
-let gt_big = compare_op gt_big_int
-let lteq_big = compare_op le_big_int
-let gteq_big = compare_op ge_big_int
-let lt_int : (int* int) -> vbit = compare_op (<)
-let gt_int : (int * int) -> vbit = compare_op (>)
-let lteq_int : (int * int) -> vbit = compare_op (<=)
-let gteq_int : (int*int) -> vbit = compare_op (>=)
-
-let lt = lt_big
-let gt = gt_big
-let lteq = lteq_big
-let gteq = gteq_big
-
-let compare_op_vec_int op sign (l,r) =
- let (l',r') = (to_num_int sign l, to_num_int sign r) in
- compare_op op (l',r')
-
-let lt_vec_int = compare_op_vec_int (<) true
-let gt_vec_int = compare_op_vec_int (>) true
-let lteq_vec_int = compare_op_vec_int (<=) true
-let gteq_vec_int = compare_op_vec_int (>=) true
-let lt_vec_signed_int = compare_op_vec_int (<) true
-let gt_vec_signed_int = compare_op_vec_int (>) true
-let lteq_vec_signed_int = compare_op_vec_int (<=) true
-let gteq_vec_signed_int = compare_op_vec_int (>=) true
-let lt_vec_unsigned_int = compare_op_vec_int (<) false
-let gt_vec_unsigned_int = compare_op_vec_int (>) false
-let lteq_vec_unsigned_int = compare_op_vec_int (<=) false
-let gteq_vec_unsigned_int = compare_op_vec_int (>=) false
-
-let compare_op_vec_big op sign (l,r) =
- let (l',r') = (to_num_big sign l, to_num_big sign r) in
- compare_op op (l',r')
-
-let lt_vec_big = compare_op_vec_big lt_big_int true
-let gt_vec_big = compare_op_vec_big gt_big_int true
-let lteq_vec_big = compare_op_vec_big le_big_int true
-let gteq_vec_big = compare_op_vec_big ge_big_int true
-let lt_vec_signed_big = compare_op_vec_big lt_big_int true
-let gt_vec_signed_big = compare_op_vec_big gt_big_int true
-let lteq_vec_signed_big = compare_op_vec_big le_big_int true
-let gteq_vec_signed_big = compare_op_vec_big ge_big_int true
-let lt_vec_unsigned_big = compare_op_vec_big lt_big_int false
-let gt_vec_unsigned_big = compare_op_vec_big gt_big_int false
-let lteq_vec_unsigned_big = compare_op_vec_big le_big_int false
-let gteq_vec_unsigned_big = compare_op_vec_big ge_big_int false
-
-let lt_vec = lt_vec_big
-let gt_vec = gt_vec_big
-let lteq_vec = lteq_vec_big
-let gteq_vec = gteq_vec_big
-let lt_vec_signed = lt_vec_signed_big
-let gt_vec_signed = gt_vec_signed_big
-let lteq_vec_signed = lteq_vec_signed_big
-let gteq_vec_signed = gteq_vec_signed_big
-let lt_vec_unsigned = lt_vec_unsigned_big
-let gt_vec_unsigned = gt_vec_unsigned_big
-let lteq_vec_unsigned = lteq_vec_unsigned_big
-let gteq_vec_unsigned = gteq_vec_unsigned_big
-
-let compare_op_vec_range_int op sign (l,r) =
- compare_op op ((to_num_int sign l),r)
-
-let lt_vec_range_int = compare_op_vec_range_int (<) true
-let gt_vec_range_int = compare_op_vec_range_int (>) true
-let lteq_vec_range_int = compare_op_vec_range_int (<=) true
-let gteq_vec_range_int = compare_op_vec_range_int (>=) true
-
-let compare_op_vec_range_big op sign (l,r) =
- compare_op op ((to_num_big sign l),r)
-
-let lt_vec_range_big = compare_op_vec_range_big lt_big_int true
-let gt_vec_range_big = compare_op_vec_range_big gt_big_int true
-let lteq_vec_range_big = compare_op_vec_range_big le_big_int true
-let gteq_vec_range_big = compare_op_vec_range_big ge_big_int true
-
-let lt_vec_range = lt_vec_range_big
-let gt_vec_range = gt_vec_range_big
-let lteq_vec_range = lteq_vec_range_big
-let gteq_vec_range = gteq_vec_range_big
-
-let compare_op_range_vec_int op sign (l,r) =
- compare_op op (l, (to_num_int sign r))
-
-let lt_range_vec_int = compare_op_range_vec_int (<) true
-let gt_range_vec_int = compare_op_range_vec_int (>) true
-let lteq_range_vec_int = compare_op_range_vec_int (<=) true
-let gteq_range_vec_int = compare_op_range_vec_int (>=) true
-
-let compare_op_range_vec_big op sign (l,r) =
- compare_op op (l, (to_num_big sign r))
-
-let lt_range_vec_big = compare_op_range_vec_big lt_big_int true
-let gt_range_vec_big = compare_op_range_vec_big gt_big_int true
-let lteq_range_vec_big = compare_op_range_vec_big le_big_int true
-let gteq_range_vec_big = compare_op_range_vec_big ge_big_int true
-
-let lt_range_vec = lt_range_vec_big
-let gt_range_vec = gt_range_vec_big
-let lteq_range_vec = lteq_range_vec_big
-let gteq_range_vec = gteq_range_vec_big
-
-let eq (l,r) = if l = r then Vone else Vzero
-let eq_vec_vec (l,r) = eq (to_num_big true l, to_num_big true r)
-let eq_vec (l,r) = eq_vec_vec(l,r)
-let eq_vec_range (l,r) = eq (to_num_big false l,r)
-let eq_range_vec (l,r) = eq (l, to_num_big false r)
-let eq_range = eq
-let eq_bit = bitwise_binop_bit (=)
-
-let neq (l,r) = bitwise_not_bit (eq (l,r))
-let neq_vec (l,r) = bitwise_not_bit (eq_vec_vec(l,r))
-let neq_vec_range (l,r) = bitwise_not_bit (eq_vec_range (l,r))
-let neq_bit (l,r) = bitwise_not_bit (eq_bit(l,r))
-let neq_range = neq
-
-let mask (n,v) =
- let n' = int_of_big_int n in
- match v with
- | Vvector (bits,start,dir) ->
- let current_size = Array.length bits in
- let to_drop = (current_size - n') in
- let bits' = Array.sub bits to_drop n' in
- Vvector (bits',(if dir then 0 else n'-1), dir)
- | Vregister (bits,start,dir,name,fields) ->
- let current_size = Array.length !bits in
- let to_drop = (current_size - n') in
- let bits' = Array.sub !bits to_drop n' in
- Vvector (bits',(if dir then 0 else n'-1), dir)
- | VvectorR _ -> failwith "mask not implemented for VregisterR"
- | Vbit _ -> failwith "mask called for bit"
-
-let slice_raw (v, i, j) =
- let i' = int_of_big_int i in
- let j' = int_of_big_int j in
- match v with
- | Vvector (bs, start, is_inc) ->
- let bits = Array.sub bs i' (j'-i'+1) in
- let len = Array.length bits in
- Vvector (bits, (if is_inc then 0 else len - 1), is_inc)
- | _ -> failwith "slice_raw only implemented for VVector"
-let _slice_raw = slice_raw
-
-(* enough literal big ints to account for most literals found in specs *)
-(* for i = 0 to 257 do Printf.printf "let bi%d = big_int_of_int %d\n" i i done;; *)
-let bi0 = zero_big_int
-let bi1 = unit_big_int
-let bi2 = big_int_of_int 2
-let bi3 = big_int_of_int 3
-let bi4 = big_int_of_int 4
-let bi5 = big_int_of_int 5
-let bi6 = big_int_of_int 6
-let bi7 = big_int_of_int 7
-let bi8 = big_int_of_int 8
-let bi9 = big_int_of_int 9
-let bi10 = big_int_of_int 10
-let bi11 = big_int_of_int 11
-let bi12 = big_int_of_int 12
-let bi13 = big_int_of_int 13
-let bi14 = big_int_of_int 14
-let bi15 = big_int_of_int 15
-let bi16 = big_int_of_int 16
-let bi17 = big_int_of_int 17
-let bi18 = big_int_of_int 18
-let bi19 = big_int_of_int 19
-let bi20 = big_int_of_int 20
-let bi21 = big_int_of_int 21
-let bi22 = big_int_of_int 22
-let bi23 = big_int_of_int 23
-let bi24 = big_int_of_int 24
-let bi25 = big_int_of_int 25
-let bi26 = big_int_of_int 26
-let bi27 = big_int_of_int 27
-let bi28 = big_int_of_int 28
-let bi29 = big_int_of_int 29
-let bi30 = big_int_of_int 30
-let bi31 = big_int_of_int 31
-let bi32 = big_int_of_int 32
-let bi33 = big_int_of_int 33
-let bi34 = big_int_of_int 34
-let bi35 = big_int_of_int 35
-let bi36 = big_int_of_int 36
-let bi37 = big_int_of_int 37
-let bi38 = big_int_of_int 38
-let bi39 = big_int_of_int 39
-let bi40 = big_int_of_int 40
-let bi41 = big_int_of_int 41
-let bi42 = big_int_of_int 42
-let bi43 = big_int_of_int 43
-let bi44 = big_int_of_int 44
-let bi45 = big_int_of_int 45
-let bi46 = big_int_of_int 46
-let bi47 = big_int_of_int 47
-let bi48 = big_int_of_int 48
-let bi49 = big_int_of_int 49
-let bi50 = big_int_of_int 50
-let bi51 = big_int_of_int 51
-let bi52 = big_int_of_int 52
-let bi53 = big_int_of_int 53
-let bi54 = big_int_of_int 54
-let bi55 = big_int_of_int 55
-let bi56 = big_int_of_int 56
-let bi57 = big_int_of_int 57
-let bi58 = big_int_of_int 58
-let bi59 = big_int_of_int 59
-let bi60 = big_int_of_int 60
-let bi61 = big_int_of_int 61
-let bi62 = big_int_of_int 62
-let bi63 = big_int_of_int 63
-let bi64 = big_int_of_int 64
-let bi65 = big_int_of_int 65
-let bi66 = big_int_of_int 66
-let bi67 = big_int_of_int 67
-let bi68 = big_int_of_int 68
-let bi69 = big_int_of_int 69
-let bi70 = big_int_of_int 70
-let bi71 = big_int_of_int 71
-let bi72 = big_int_of_int 72
-let bi73 = big_int_of_int 73
-let bi74 = big_int_of_int 74
-let bi75 = big_int_of_int 75
-let bi76 = big_int_of_int 76
-let bi77 = big_int_of_int 77
-let bi78 = big_int_of_int 78
-let bi79 = big_int_of_int 79
-let bi80 = big_int_of_int 80
-let bi81 = big_int_of_int 81
-let bi82 = big_int_of_int 82
-let bi83 = big_int_of_int 83
-let bi84 = big_int_of_int 84
-let bi85 = big_int_of_int 85
-let bi86 = big_int_of_int 86
-let bi87 = big_int_of_int 87
-let bi88 = big_int_of_int 88
-let bi89 = big_int_of_int 89
-let bi90 = big_int_of_int 90
-let bi91 = big_int_of_int 91
-let bi92 = big_int_of_int 92
-let bi93 = big_int_of_int 93
-let bi94 = big_int_of_int 94
-let bi95 = big_int_of_int 95
-let bi96 = big_int_of_int 96
-let bi97 = big_int_of_int 97
-let bi98 = big_int_of_int 98
-let bi99 = big_int_of_int 99
-let bi100 = big_int_of_int 100
-let bi101 = big_int_of_int 101
-let bi102 = big_int_of_int 102
-let bi103 = big_int_of_int 103
-let bi104 = big_int_of_int 104
-let bi105 = big_int_of_int 105
-let bi106 = big_int_of_int 106
-let bi107 = big_int_of_int 107
-let bi108 = big_int_of_int 108
-let bi109 = big_int_of_int 109
-let bi110 = big_int_of_int 110
-let bi111 = big_int_of_int 111
-let bi112 = big_int_of_int 112
-let bi113 = big_int_of_int 113
-let bi114 = big_int_of_int 114
-let bi115 = big_int_of_int 115
-let bi116 = big_int_of_int 116
-let bi117 = big_int_of_int 117
-let bi118 = big_int_of_int 118
-let bi119 = big_int_of_int 119
-let bi120 = big_int_of_int 120
-let bi121 = big_int_of_int 121
-let bi122 = big_int_of_int 122
-let bi123 = big_int_of_int 123
-let bi124 = big_int_of_int 124
-let bi125 = big_int_of_int 125
-let bi126 = big_int_of_int 126
-let bi127 = big_int_of_int 127
-let bi128 = big_int_of_int 128
-let bi129 = big_int_of_int 129
-let bi130 = big_int_of_int 130
-let bi131 = big_int_of_int 131
-let bi132 = big_int_of_int 132
-let bi133 = big_int_of_int 133
-let bi134 = big_int_of_int 134
-let bi135 = big_int_of_int 135
-let bi136 = big_int_of_int 136
-let bi137 = big_int_of_int 137
-let bi138 = big_int_of_int 138
-let bi139 = big_int_of_int 139
-let bi140 = big_int_of_int 140
-let bi141 = big_int_of_int 141
-let bi142 = big_int_of_int 142
-let bi143 = big_int_of_int 143
-let bi144 = big_int_of_int 144
-let bi145 = big_int_of_int 145
-let bi146 = big_int_of_int 146
-let bi147 = big_int_of_int 147
-let bi148 = big_int_of_int 148
-let bi149 = big_int_of_int 149
-let bi150 = big_int_of_int 150
-let bi151 = big_int_of_int 151
-let bi152 = big_int_of_int 152
-let bi153 = big_int_of_int 153
-let bi154 = big_int_of_int 154
-let bi155 = big_int_of_int 155
-let bi156 = big_int_of_int 156
-let bi157 = big_int_of_int 157
-let bi158 = big_int_of_int 158
-let bi159 = big_int_of_int 159
-let bi160 = big_int_of_int 160
-let bi161 = big_int_of_int 161
-let bi162 = big_int_of_int 162
-let bi163 = big_int_of_int 163
-let bi164 = big_int_of_int 164
-let bi165 = big_int_of_int 165
-let bi166 = big_int_of_int 166
-let bi167 = big_int_of_int 167
-let bi168 = big_int_of_int 168
-let bi169 = big_int_of_int 169
-let bi170 = big_int_of_int 170
-let bi171 = big_int_of_int 171
-let bi172 = big_int_of_int 172
-let bi173 = big_int_of_int 173
-let bi174 = big_int_of_int 174
-let bi175 = big_int_of_int 175
-let bi176 = big_int_of_int 176
-let bi177 = big_int_of_int 177
-let bi178 = big_int_of_int 178
-let bi179 = big_int_of_int 179
-let bi180 = big_int_of_int 180
-let bi181 = big_int_of_int 181
-let bi182 = big_int_of_int 182
-let bi183 = big_int_of_int 183
-let bi184 = big_int_of_int 184
-let bi185 = big_int_of_int 185
-let bi186 = big_int_of_int 186
-let bi187 = big_int_of_int 187
-let bi188 = big_int_of_int 188
-let bi189 = big_int_of_int 189
-let bi190 = big_int_of_int 190
-let bi191 = big_int_of_int 191
-let bi192 = big_int_of_int 192
-let bi193 = big_int_of_int 193
-let bi194 = big_int_of_int 194
-let bi195 = big_int_of_int 195
-let bi196 = big_int_of_int 196
-let bi197 = big_int_of_int 197
-let bi198 = big_int_of_int 198
-let bi199 = big_int_of_int 199
-let bi200 = big_int_of_int 200
-let bi201 = big_int_of_int 201
-let bi202 = big_int_of_int 202
-let bi203 = big_int_of_int 203
-let bi204 = big_int_of_int 204
-let bi205 = big_int_of_int 205
-let bi206 = big_int_of_int 206
-let bi207 = big_int_of_int 207
-let bi208 = big_int_of_int 208
-let bi209 = big_int_of_int 209
-let bi210 = big_int_of_int 210
-let bi211 = big_int_of_int 211
-let bi212 = big_int_of_int 212
-let bi213 = big_int_of_int 213
-let bi214 = big_int_of_int 214
-let bi215 = big_int_of_int 215
-let bi216 = big_int_of_int 216
-let bi217 = big_int_of_int 217
-let bi218 = big_int_of_int 218
-let bi219 = big_int_of_int 219
-let bi220 = big_int_of_int 220
-let bi221 = big_int_of_int 221
-let bi222 = big_int_of_int 222
-let bi223 = big_int_of_int 223
-let bi224 = big_int_of_int 224
-let bi225 = big_int_of_int 225
-let bi226 = big_int_of_int 226
-let bi227 = big_int_of_int 227
-let bi228 = big_int_of_int 228
-let bi229 = big_int_of_int 229
-let bi230 = big_int_of_int 230
-let bi231 = big_int_of_int 231
-let bi232 = big_int_of_int 232
-let bi233 = big_int_of_int 233
-let bi234 = big_int_of_int 234
-let bi235 = big_int_of_int 235
-let bi236 = big_int_of_int 236
-let bi237 = big_int_of_int 237
-let bi238 = big_int_of_int 238
-let bi239 = big_int_of_int 239
-let bi240 = big_int_of_int 240
-let bi241 = big_int_of_int 241
-let bi242 = big_int_of_int 242
-let bi243 = big_int_of_int 243
-let bi244 = big_int_of_int 244
-let bi245 = big_int_of_int 245
-let bi246 = big_int_of_int 246
-let bi247 = big_int_of_int 247
-let bi248 = big_int_of_int 248
-let bi249 = big_int_of_int 249
-let bi250 = big_int_of_int 250
-let bi251 = big_int_of_int 251
-let bi252 = big_int_of_int 252
-let bi253 = big_int_of_int 253
-let bi254 = big_int_of_int 254
-let bi255 = big_int_of_int 255
-let bi256 = big_int_of_int 256
-let bi257 = big_int_of_int 257
diff --git a/src/myocamlbuild.ml b/src/myocamlbuild.ml
index ae58f7b2..6ee0e963 100644
--- a/src/myocamlbuild.ml
+++ b/src/myocamlbuild.ml
@@ -72,7 +72,7 @@ let lem_dir =
let lem = lem_dir / "lem" ;;
(* All -wl ignores should be removed if you want to see the pattern compilation, exhaustive, and unused var warnings *)
-let lem_opts = [A "-lib"; P "../lem_interp";
+let lem_opts = [A "-lib"; P "../gen_lib";
A "-wl_pat_comp"; P "ign";
A "-wl_pat_exh"; P "ign";
A "-wl_pat_fail"; P "ign";
diff --git a/src/util.ml b/src/util.ml
index b44c5dfb..b997005e 100644
--- a/src/util.ml
+++ b/src/util.ml
@@ -394,6 +394,13 @@ let rec drop n xs = match n, xs with
| n, [] -> []
| n, (x :: xs) -> drop (n - 1) xs
+let list_init len f =
+ let rec list_init' len f acc =
+ if acc >= len then []
+ else f acc :: list_init' len f (acc + 1)
+ in
+ list_init' len f 0
+
let termcode n =
if !opt_colors then
"\x1B[" ^ string_of_int n ^ "m"
diff --git a/src/util.mli b/src/util.mli
index b74442a2..596b298d 100644
--- a/src/util.mli
+++ b/src/util.mli
@@ -219,6 +219,8 @@ module ExtraSet : functor (S : Set.S) ->
val list_inter : S.t list -> S.t
end
+val list_init : int -> (int -> 'a) -> 'a list
+
(*Formatting functions*)
val string_of_list : string -> ('a -> string) -> 'a list -> string
diff --git a/src/value2.lem b/src/value2.lem
new file mode 100644
index 00000000..09d74520
--- /dev/null
+++ b/src/value2.lem
@@ -0,0 +1,99 @@
+(**************************************************************************)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* Brian Campbell *)
+(* Thomas Bauereiss *)
+(* Anthony Fox *)
+(* Jon French *)
+(* Dominic Mulligan *)
+(* Stephen Kell *)
+(* Mark Wassell *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(**************************************************************************)
+
+open import Pervasives
+open import Assert_extra
+open Map
+
+open import Sail_values
+
+type vl =
+ | V_vector of list vl
+ | V_list of list vl
+ | V_bits of list bitU
+ | V_bit of bitU
+ | V_tuple of list vl
+ | V_bool of bool
+ | V_nondet (* Special nondeterministic boolean *)
+ | V_unit
+ | V_int of integer
+ | V_string of string
+ | V_ctor of string * list vl
+ | V_ctor_kind of string
+ | V_record of list (string * vl)
+ | V_null (* Used for unitialized values and null pointers in C compilation *)
+
+let string_of_value = function
+ | V_bits bs -> show_bitlist bs ^ "ul"
+ | V_int i -> show i ^ "l"
+ | V_bool true -> "true"
+ | V_bool false -> "false"
+ | V_null -> "NULL"
+ | V_unit -> "UNIT"
+ | V_bit B0 -> "0ul"
+ | V_bit B1 -> "1ul"
+ | V_string str -> "\"" ^ str ^ "\""
+ | _ -> failwith "Cannot convert value to string"
+end
+
+let primops extern args =
+ match (extern, args) with
+ | ("and_bool", [V_bool b1; V_bool b2]) -> V_bool (b1 && b2)
+ | ("and_bool", [V_nondet; V_bool false]) -> V_bool false
+ | ("and_bool", [V_bool false; V_nondet]) -> V_bool false
+ | ("and_bool", _) -> V_nondet
+
+ | ("or_bool", [V_bool b1; V_bool b2]) -> V_bool (b1 || b2)
+ | ("or_bool", [V_nondet; V_bool true]) -> V_bool true
+ | ("or_bool", [V_bool true; V_nondet]) -> V_bool true
+ | ("or_bool", _) -> V_nondet
+
+ | _ -> failwith ("Unimplemented primitive operation " ^ extern)
+ end