summaryrefslogtreecommitdiff
path: root/src/gen_lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/gen_lib')
-rw-r--r--src/gen_lib/prompt.lem25
-rw-r--r--src/gen_lib/prompt_monad.lem25
-rw-r--r--src/gen_lib/sail_operators.lem290
-rw-r--r--src/gen_lib/sail_operators_bitlists.lem179
-rw-r--r--src/gen_lib/sail_operators_mwords.lem274
-rw-r--r--src/gen_lib/sail_values.lem428
-rw-r--r--src/gen_lib/state_monad.lem27
7 files changed, 730 insertions, 518 deletions
diff --git a/src/gen_lib/prompt.lem b/src/gen_lib/prompt.lem
index 1d8623df..8cef266e 100644
--- a/src/gen_lib/prompt.lem
+++ b/src/gen_lib/prompt.lem
@@ -30,20 +30,35 @@ end
declare {isabelle} termination_argument foreachM = automatic
-val bool_of_bitU_undef : forall 'rv 'e. bitU -> monad 'rv bool 'e
-let bool_of_bitU_undef = function
+val bool_of_bitU_fail : forall 'rv 'e. bitU -> monad 'rv bool 'e
+let bool_of_bitU_fail = function
+ | B0 -> return false
+ | B1 -> return true
+ | BU -> Fail "bool_of_bitU"
+end
+
+val bool_of_bitU_oracle : forall 'rv 'e. bitU -> monad 'rv bool 'e
+let bool_of_bitU_oracle = function
| B0 -> return false
| B1 -> return true
| BU -> undefined_bool ()
end
-val bools_of_bitUs : forall 'rv 'e. list bitU -> monad 'rv (list bool) 'e
-let bools_of_bitUs bits =
+val bools_of_bits_oracle : forall 'rv 'e. list bitU -> monad 'rv (list bool) 'e
+let bools_of_bits_oracle bits =
foreachM bits []
(fun b bools ->
- bool_of_bitU_undef b >>= (fun b ->
+ bool_of_bitU_oracle b >>= (fun b ->
return (bools ++ [b])))
+val of_bits_oracle : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monad 'rv 'a 'e
+let of_bits_oracle bits =
+ bools_of_bits_oracle bits >>= (fun bs ->
+ return (of_bools bs))
+
+val of_bits_fail : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monad 'rv 'a 'e
+let of_bits_fail bits = maybe_fail "of_bits" (of_bits bits)
+
val whileM : forall 'rv 'vars 'e. 'vars -> ('vars -> monad 'rv bool 'e) ->
('vars -> monad 'rv 'vars 'e) -> monad 'rv 'vars 'e
let rec whileM vars cond body =
diff --git a/src/gen_lib/prompt_monad.lem b/src/gen_lib/prompt_monad.lem
index edbe1f03..92b9ac5e 100644
--- a/src/gen_lib/prompt_monad.lem
+++ b/src/gen_lib/prompt_monad.lem
@@ -127,11 +127,20 @@ let try_catchR m h =
| Right e -> h e
end)
+val maybe_fail : forall 'rv 'a 'e. string -> maybe 'a -> monad 'rv 'a 'e
+let maybe_fail msg = function
+ | Just a -> return a
+ | Nothing -> Fail msg
+end
+
+val read_mem_bytes : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv (list memory_byte) 'e
+let read_mem_bytes rk addr sz =
+ Read_mem rk (bits_of addr) (nat_of_int sz) return
val read_mem : forall 'rv 'a 'b 'e. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monad 'rv 'b 'e
let read_mem rk addr sz =
- let k bytes = Done (bits_of_mem_bytes bytes) in
- Read_mem rk (bits_of addr) (natFromInteger sz) k
+ read_mem_bytes rk addr sz >>= (fun bytes ->
+ maybe_fail "bits_of_mem_bytes" (of_bits (bits_of_mem_bytes bytes)))
val read_tag : forall 'rv 'a 'e. Bitvector 'a => 'a -> monad 'rv bitU 'e
let read_tag addr = Read_tag (bits_of addr) return
@@ -142,7 +151,7 @@ let excl_result () =
Excl_res k
val write_mem_ea : forall 'rv 'a 'e. Bitvector 'a => write_kind -> 'a -> integer -> monad 'rv unit 'e
-let write_mem_ea wk addr sz = Write_ea wk (bits_of addr) (natFromInteger sz) (Done ())
+let write_mem_ea wk addr sz = Write_ea wk (bits_of addr) (nat_of_int sz) (Done ())
val write_mem_val : forall 'rv 'a 'e. Bitvector 'a => 'a -> monad 'rv bool 'e
let write_mem_val v = match mem_bytes_of_bits v with
@@ -166,10 +175,10 @@ let read_reg reg =
(* TODO
val read_reg_range : forall 's 'r 'rv 'a 'e. Bitvector 'a => register_ref 's 'rv 'r -> integer -> integer -> monad 'rv 'a 'e
let read_reg_range reg i j =
- read_reg_aux of_bits (external_reg_slice reg (natFromInteger i,natFromInteger j))
+ read_reg_aux of_bits (external_reg_slice reg (nat_of_int i,nat_of_int j))
let read_reg_bit reg i =
- read_reg_aux (fun v -> v) (external_reg_slice reg (natFromInteger i,natFromInteger i)) >>= fun v ->
+ read_reg_aux (fun v -> v) (external_reg_slice reg (nat_of_int i,nat_of_int i)) >>= fun v ->
return (extract_only_element v)
let read_reg_field reg regfield =
@@ -188,9 +197,9 @@ let write_reg reg v = Write_reg reg.name (reg.regval_of v) (Done ())
let write_reg reg v =
write_reg_aux (external_reg_whole reg) v
let write_reg_range reg i j v =
- write_reg_aux (external_reg_slice reg (natFromInteger i,natFromInteger j)) v
+ write_reg_aux (external_reg_slice reg (nat_of_int i,nat_of_int j)) v
let write_reg_pos reg i v =
- let iN = natFromInteger i in
+ let iN = nat_of_int i in
write_reg_aux (external_reg_slice reg (iN,iN)) [v]
let write_reg_bit = write_reg_pos
let write_reg_field reg regfield v =
@@ -199,7 +208,7 @@ let write_reg_field_bit reg regfield bit =
write_reg_aux (external_reg_field_whole reg regfield.field_name)
(Vector [bit] 0 (is_inc_of_reg reg))
let write_reg_field_range reg regfield i j v =
- write_reg_aux (external_reg_field_slice reg regfield.field_name (natFromInteger i,natFromInteger j)) v
+ write_reg_aux (external_reg_field_slice reg regfield.field_name (nat_of_int i,nat_of_int j)) v
let write_reg_field_pos reg regfield i v =
write_reg_field_range reg regfield i i [v]
let write_reg_field_bit = write_reg_field_pos*)
diff --git a/src/gen_lib/sail_operators.lem b/src/gen_lib/sail_operators.lem
index 9354f9d4..9b0857d9 100644
--- a/src/gen_lib/sail_operators.lem
+++ b/src/gen_lib/sail_operators.lem
@@ -4,20 +4,21 @@ open import Sail_values
(*** Bit vector operations *)
-val concat_bv : forall 'a 'b 'c. Bitvector 'a, Bitvector 'b, Bitvector 'c => 'a -> 'b -> 'c
-let concat_bv l r = of_bits (bits_of l ++ bits_of r)
+val concat_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b => 'a -> 'b -> list bitU
+let concat_bv l r = (bits_of l ++ bits_of r)
-val cons_bv : forall 'a 'b 'c. Bitvector 'a, Bitvector 'b => bitU -> 'a -> 'b
-let cons_bv b v = of_bits (b :: bits_of v)
+val cons_bv : forall 'a. Bitvector 'a => bitU -> 'a -> list bitU
+let cons_bv b v = b :: bits_of v
-let bool_of_bv v = extract_only_element (bits_of v)
-let cast_unit_bv b = of_bits [b]
-let bv_of_bit len b = of_bits (extz_bits len [b])
-let int_of_bv sign = if sign then signed else unsigned
+val cast_unit_bv : bitU -> list bitU
+let cast_unit_bv b = [b]
+
+val bv_of_bit : integer -> bitU -> list bitU
+let bv_of_bit len b = extz_bits len [b]
let most_significant v = match bits_of v with
| b :: _ -> b
- | _ -> failwith "most_significant applied to empty vector"
+ | _ -> B0 (* Treat empty bitvector as all zeros *)
end
let get_max_representable_in sign (n : integer) : integer =
@@ -36,135 +37,106 @@ let get_min_representable_in _ (n : integer) : integer =
else if n = 5 then min_5
else 0 - (integerPow 2 (natFromInteger n))
-val bitwise_binop_bv : forall 'a. Bitvector 'a =>
- (bool -> bool -> bool) -> 'a -> 'a -> 'a
-let bitwise_binop_bv op l r = of_bits (binop_bits op (bits_of l) (bits_of r))
-
-let and_bv = bitwise_binop_bv (&&)
-let or_bv = bitwise_binop_bv (||)
-let xor_bv = bitwise_binop_bv xor
-let not_bv v = of_bits (not_bits (bits_of v))
-
-val arith_op_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> 'b
-let arith_op_bv op sign size l r =
- let (l',r') = (int_of_bv sign l, int_of_bv sign r) in
- let n = op l' r' in
- of_int (size * length l) n
-
-
-let add_bv = arith_op_bv integerAdd false 1
-let sadd_bv = arith_op_bv integerAdd true 1
-let sub_bv = arith_op_bv integerMinus false 1
-let mult_bv = arith_op_bv integerMult false 2
-let smult_bv = arith_op_bv integerMult true 2
-
-let inline add_mword = Machine_word.plus
-let inline sub_mword = Machine_word.minus
-val mult_mword : forall 'a 'b. Size 'b => mword 'a -> mword 'a -> mword 'b
-let mult_mword l r = times (zeroExtend l) (zeroExtend r)
-
-val arith_op_bv_int : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> 'a -> integer -> 'b
-let arith_op_bv_int op sign size l r =
- let l' = int_of_bv sign l in
- let n = op l' r in
- of_int (size * length l) n
-
-let add_bv_int = arith_op_bv_int integerAdd false 1
-let sadd_bv_int = arith_op_bv_int integerAdd true 1
-let sub_bv_int = arith_op_bv_int integerMinus false 1
-let mult_bv_int = arith_op_bv_int integerMult false 2
-let smult_bv_int = arith_op_bv_int integerMult true 2
-
-val arith_op_int_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> integer -> 'a -> 'b
-let arith_op_int_bv op sign size l r =
- let r' = int_of_bv sign r in
- let n = op l r' in
- of_int (size * length r) n
-
-let add_int_bv = arith_op_int_bv integerAdd false 1
-let sadd_int_bv = arith_op_int_bv integerAdd true 1
-let sub_int_bv = arith_op_int_bv integerMinus false 1
-let mult_int_bv = arith_op_int_bv integerMult false 2
-let smult_int_bv = arith_op_int_bv integerMult true 2
-
-let arith_op_bv_bit op sign (size : integer) l r =
- let l' = int_of_bv sign l in
- let n = op l' (match r with | B1 -> (1 : integer) | _ -> 0 end) in
- of_int (size * length l) n
-
-let add_bv_bit = arith_op_bv_bit integerAdd false 1
-let sadd_bv_bit = arith_op_bv_bit integerAdd true 1
-let sub_bv_bit = arith_op_bv_bit integerMinus true 1
-
-val arith_op_overflow_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> ('b * bitU * bitU)
+val arith_op_bv_int : forall 'a 'b. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> 'a -> integer -> 'a
+let arith_op_bv_int op sign l r =
+ let r' = of_int (length l) r in
+ arith_op_bv op sign l r'
+
+val arith_op_int_bv : forall 'a 'b. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a
+let arith_op_int_bv op sign l r =
+ let l' = of_int (length r) l in
+ arith_op_bv op sign l' r
+
+let arith_op_bv_bool op sign l r = arith_op_bv_int op sign l (if r then 1 else 0)
+let arith_op_bv_bit op sign l r = Maybe.map (arith_op_bv_bool op sign l) (bool_of_bitU r)
+
+(* TODO (or just omit and define it per spec if needed)
+val arith_op_overflow_bv : forall 'a. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> (list bitU * bitU * bitU)
let arith_op_overflow_bv op sign size l r =
let len = length l in
let act_size = len * size in
- let (l_sign,r_sign) = (int_of_bv sign l,int_of_bv sign r) in
- let (l_unsign,r_unsign) = (int_of_bv false l,int_of_bv false r) in
- let n = op l_sign r_sign in
- let n_unsign = op l_unsign r_unsign in
- let correct_size = of_int act_size n in
- let one_more_size_u = bits_of_int (act_size + 1) n_unsign in
- let overflow =
- if n <= get_max_representable_in sign len &&
- n >= get_min_representable_in sign len
- then B0 else B1 in
- let c_out = most_significant one_more_size_u in
- (correct_size,overflow,c_out)
+ match (int_of_bv sign l, int_of_bv sign r, int_of_bv false l, int_of_bv false r) with
+ | (Just l_sign, Just r_sign, Just l_unsign, Just r_unsign) ->
+ let n = op l_sign r_sign in
+ let n_unsign = op l_unsign r_unsign in
+ let correct_size = of_int act_size n in
+ let one_more_size_u = bits_of_int (act_size + 1) n_unsign in
+ let overflow =
+ if n <= get_max_representable_in sign len &&
+ n >= get_min_representable_in sign len
+ then B0 else B1 in
+ let c_out = most_significant one_more_size_u in
+ (correct_size,overflow,c_out)
+ | (_, _, _, _) ->
+ (repeat [BU] act_size, BU, BU)
+ end
let add_overflow_bv = arith_op_overflow_bv integerAdd false 1
-let add_overflow_bv_signed = arith_op_overflow_bv integerAdd true 1
+let adds_overflow_bv = arith_op_overflow_bv integerAdd true 1
let sub_overflow_bv = arith_op_overflow_bv integerMinus false 1
-let sub_overflow_bv_signed = arith_op_overflow_bv integerMinus true 1
+let subs_overflow_bv = arith_op_overflow_bv integerMinus true 1
let mult_overflow_bv = arith_op_overflow_bv integerMult false 2
-let mult_overflow_bv_signed = arith_op_overflow_bv integerMult true 2
+let mults_overflow_bv = arith_op_overflow_bv integerMult true 2
-val arith_op_overflow_bv_bit : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> 'a -> bitU -> ('b * bitU * bitU)
+val arith_op_overflow_bv_bit : forall 'a. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> bitU -> (list bitU * bitU * bitU)
let arith_op_overflow_bv_bit op sign size l r_bit =
let act_size = length l * size in
- let l' = int_of_bv sign l in
- let l_u = int_of_bv false l in
- let (n,nu,changed) = match r_bit with
- | B1 -> (op l' 1, op l_u 1, true)
- | B0 -> (l',l_u,false)
- | BU -> failwith "arith_op_overflow_bv_bit applied to undefined bit"
- end in
- let correct_size = of_int act_size n in
- let one_larger = bits_of_int (act_size + 1) nu in
- let overflow =
- if changed
- then
- if n <= get_max_representable_in sign act_size && n >= get_min_representable_in sign act_size
- then B0 else B1
- else B0 in
- (correct_size,overflow,most_significant one_larger)
+ match (int_of_bv sign l, int_of_bv false l, r_bit = BU) with
+ | (Just l', Just l_u, false) ->
+ let (n, nu, changed) = match r_bit with
+ | B1 -> (op l' 1, op l_u 1, true)
+ | B0 -> (l', l_u, false)
+ | BU -> (* unreachable due to check above *)
+ failwith "arith_op_overflow_bv_bit applied to undefined bit"
+ end in
+ let correct_size = of_int act_size n in
+ let one_larger = bits_of_int (act_size + 1) nu in
+ let overflow =
+ if changed
+ then
+ if n <= get_max_representable_in sign act_size && n >= get_min_representable_in sign act_size
+ then B0 else B1
+ else B0 in
+ (correct_size, overflow, most_significant one_larger)
+ | (_, _, _) ->
+ (repeat [BU] act_size, BU, BU)
+ end
let add_overflow_bv_bit = arith_op_overflow_bv_bit integerAdd false 1
-let add_overflow_bv_bit_signed = arith_op_overflow_bv_bit integerAdd true 1
+let adds_overflow_bv_bit = arith_op_overflow_bv_bit integerAdd true 1
let sub_overflow_bv_bit = arith_op_overflow_bv_bit integerMinus false 1
-let sub_overflow_bv_bit_signed = arith_op_overflow_bv_bit integerMinus true 1
+let subs_overflow_bv_bit = arith_op_overflow_bv_bit integerMinus true 1*)
type shift = LL_shift | RR_shift | RR_shift_arith | LL_rot | RR_rot
-val shift_op_bv : forall 'a. Bitvector 'a => shift -> 'a -> integer -> 'a
+let invert_shift = function
+ | LL_shift -> RR_shift
+ | RR_shift -> LL_shift
+ | RR_shift_arith -> LL_shift
+ | LL_rot -> RR_rot
+ | RR_rot -> LL_rot
+end
+
+val shift_op_bv : forall 'a. Bitvector 'a => shift -> 'a -> integer -> list bitU
let shift_op_bv op v n =
+ let v = bits_of v in
+ if n = 0 then v else
+ let (op, n) = if n > 0 then (op, n) else (invert_shift op, ~n) in
match op with
| LL_shift ->
- of_bits (get_bits true v n (length v - 1) ++ repeat [B0] n)
+ subrange_list true v n (length v - 1) ++ repeat [B0] n
| RR_shift ->
- of_bits (repeat [B0] n ++ get_bits true v 0 (length v - n - 1))
+ repeat [B0] n ++ subrange_list true v 0 (length v - n - 1)
| RR_shift_arith ->
- of_bits (repeat [most_significant v] n ++ get_bits true v 0 (length v - n - 1))
+ repeat [most_significant v] n ++ subrange_list true v 0 (length v - n - 1)
| LL_rot ->
- of_bits (get_bits true v n (length v - 1) ++ get_bits true v 0 (n - 1))
+ subrange_list true v n (length v - 1) ++ subrange_list true v 0 (n - 1)
| RR_rot ->
- of_bits (get_bits false v 0 (n - 1) ++ get_bits false v n (length v - 1))
+ subrange_list false v 0 (n - 1) ++ subrange_list false v n (length v - 1)
end
let shiftl_bv = shift_op_bv LL_shift (*"<<"*)
@@ -173,10 +145,11 @@ let arith_shiftr_bv = shift_op_bv RR_shift_arith
let rotl_bv = shift_op_bv LL_rot (*"<<<"*)
let rotr_bv = shift_op_bv LL_rot (*">>>"*)
-let shiftl_mword w n = Machine_word.shiftLeft w (natFromInteger n)
-let shiftr_mword w n = Machine_word.shiftRight w (natFromInteger n)
-let rotl_mword w n = Machine_word.rotateLeft (natFromInteger n) w
-let rotr_mword w n = Machine_word.rotateRight (natFromInteger n) w
+let shiftl_mword w n = Machine_word.shiftLeft w (nat_of_int n)
+let shiftr_mword w n = Machine_word.shiftRight w (nat_of_int n)
+let arith_shiftr_mword w n = Machine_word.arithShiftRight w (nat_of_int n)
+let rotl_mword w n = Machine_word.rotateLeft (nat_of_int n) w
+let rotr_mword w n = Machine_word.rotateRight (nat_of_int n) w
let rec arith_op_no0 (op : integer -> integer -> integer) l r =
if r = 0
@@ -184,27 +157,19 @@ let rec arith_op_no0 (op : integer -> integer -> integer) l r =
else Just (op l r)
val arith_op_bv_no0 : forall 'a 'b. Bitvector 'a, Bitvector 'b =>
- (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> 'b
+ (integer -> integer -> integer) -> bool -> integer -> 'a -> 'a -> maybe 'b
let arith_op_bv_no0 op sign size l r =
- let act_size = length l * size in
- let (l',r') = (int_of_bv sign l,int_of_bv sign r) in
- let n = arith_op_no0 op l' r' in
- let (representable,n') =
- match n with
- | Just n' ->
- (n' <= get_max_representable_in sign act_size &&
- n' >= get_min_representable_in sign act_size, n')
- | _ -> (false,0)
- end in
- if representable then (of_int act_size n') else (of_bits (repeat [BU] act_size))
+ Maybe.bind (int_of_bv sign l) (fun l' ->
+ Maybe.bind (int_of_bv sign r) (fun r' ->
+ if r' = 0 then Nothing else Just (of_int (length l * size) (op l' r'))))
let mod_bv = arith_op_bv_no0 hardware_mod false 1
let quot_bv = arith_op_bv_no0 hardware_quot false 1
-let quot_bv_signed = arith_op_bv_no0 hardware_quot true 1
+let quots_bv = arith_op_bv_no0 hardware_quot true 1
let mod_mword = Machine_word.modulo
let quot_mword = Machine_word.unsignedDivide
-let quot_mword_signed = Machine_word.signedDivide
+let quots_mword = Machine_word.signedDivide
let arith_op_bv_int_no0 op sign size l r =
arith_op_bv_no0 op sign size l (of_int (length l) r)
@@ -212,26 +177,49 @@ let arith_op_bv_int_no0 op sign size l r =
let quot_bv_int = arith_op_bv_int_no0 hardware_quot false 1
let mod_bv_int = arith_op_bv_int_no0 hardware_mod false 1
-let replicate_bits_bv v count = of_bits (repeat (bits_of v) count)
+let mod_mword_int l r = Machine_word.modulo l (wordFromInteger r)
+let quot_mword_int l r = Machine_word.unsignedDivide l (wordFromInteger r)
+let quots_mword_int l r = Machine_word.signedDivide l (wordFromInteger r)
+
+let replicate_bits_bv v count = repeat (bits_of v) count
let duplicate_bit_bv bit len = replicate_bits_bv [bit] len
val eq_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
-let eq_bv l r = (unsigned l = unsigned r)
+let eq_bv l r = (bits_of l = bits_of r)
+
+let eq_mword l r = (l = r)
val neq_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
-let neq_bv l r = (unsigned l <> unsigned r)
-
-val ucmp_bv : forall 'a. Bitvector 'a => (integer -> integer -> bool) -> 'a -> 'a -> bool
-let ucmp_bv cmp l r = cmp (unsigned l) (unsigned r)
-
-val scmp_bv : forall 'a. Bitvector 'a => (integer -> integer -> bool) -> 'a -> 'a -> bool
-let scmp_bv cmp l r = cmp (signed l) (signed r)
-
-let ult_bv = ucmp_bv (<)
-let slt_bv = scmp_bv (<)
-let ugt_bv = ucmp_bv (>)
-let sgt_bv = scmp_bv (>)
-let ulteq_bv = ucmp_bv (<=)
-let slteq_bv = scmp_bv (<=)
-let ugteq_bv = ucmp_bv (>=)
-let sgteq_bv = scmp_bv (>=)
+let neq_bv l r = not (eq_bv l r)
+
+let neq_mword l r = (l <> r)
+
+val ult_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
+let ult_bv l r = lexicographicLess (List.reverse (bits_of l)) (List.reverse (bits_of r))
+let ulteq_bv l r = (eq_bv l r) || (ult_bv l r)
+let ugt_bv l r = not (ulteq_bv l r)
+let ugteq_bv l r = (eq_bv l r) || (ugt_bv l r)
+
+val slt_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
+let slt_bv l r =
+ match (most_significant l, most_significant r) with
+ | (B0, B0) -> ult_bv l r
+ | (B0, B1) -> false
+ | (B1, B0) -> true
+ | (B1, B1) ->
+ let l' = add_one_bit_ignore_overflow (bits_of l) in
+ let r' = add_one_bit_ignore_overflow (bits_of r) in
+ ugt_bv l' r'
+ | (BU, BU) -> ult_bv l r
+ | (BU, _) -> true
+ | (_, BU) -> false
+ end
+let slteq_bv l r = (eq_bv l r) || (slt_bv l r)
+let sgt_bv l r = not (slteq_bv l r)
+let sgteq_bv l r = (eq_bv l r) || (sgt_bv l r)
+
+val ucmp_mword : forall 'a. Size 'a => (integer -> integer -> bool) -> mword 'a -> mword 'a -> bool
+let ucmp_mword cmp l r = cmp (unsignedIntegerFromWord l) (unsignedIntegerFromWord r)
+
+val scmp_mword : forall 'a. Size 'a => (integer -> integer -> bool) -> mword 'a -> mword 'a -> bool
+let scmp_mword cmp l r = cmp (signedIntegerFromWord l) (signedIntegerFromWord r)
diff --git a/src/gen_lib/sail_operators_bitlists.lem b/src/gen_lib/sail_operators_bitlists.lem
index a627f560..9b81e233 100644
--- a/src/gen_lib/sail_operators_bitlists.lem
+++ b/src/gen_lib/sail_operators_bitlists.lem
@@ -2,9 +2,27 @@ open import Pervasives_extra
open import Machine_word
open import Sail_values
open import Sail_operators
+open import Prompt_monad
+open import Prompt
(* Specialisation of operators to bit lists *)
+val uint_maybe : list bitU -> maybe integer
+let uint_maybe v = unsigned v
+let uint_fail v = maybe_fail "uint" (unsigned v)
+let uint_oracle v =
+ bools_of_bits_oracle v >>= (fun bs ->
+ return (int_of_bools false bs))
+let uint v = maybe_failwith (uint_maybe v)
+
+val sint_maybe : list bitU -> maybe integer
+let sint_maybe v = signed v
+let sint_fail v = maybe_fail "sint" (signed v)
+let sint_oracle v =
+ bools_of_bits_oracle v >>= (fun bs ->
+ return (int_of_bools true bs))
+let sint v = maybe_failwith (sint_maybe v)
+
val access_vec_inc : list bitU -> integer -> bitU
let access_vec_inc = access_bv_inc
@@ -13,9 +31,15 @@ let access_vec_dec = access_bv_dec
val update_vec_inc : list bitU -> integer -> bitU -> list bitU
let update_vec_inc = update_bv_inc
+let update_vec_inc_maybe v i b = Just (update_vec_inc v i b)
+let update_vec_inc_fail v i b = return (update_vec_inc v i b)
+let update_vec_inc_oracle v i b = return (update_vec_inc v i b)
val update_vec_dec : list bitU -> integer -> bitU -> list bitU
let update_vec_dec = update_bv_dec
+let update_vec_dec_maybe v i b = Just (update_vec_dec v i b)
+let update_vec_dec_fail v i b = return (update_vec_dec v i b)
+let update_vec_dec_oracle v i b = return (update_vec_dec v i b)
val subrange_vec_inc : list bitU -> integer -> integer -> list bitU
let subrange_vec_inc = subrange_bv_inc
@@ -40,21 +64,30 @@ let concat_vec = concat_bv
val cons_vec : bitU -> list bitU -> list bitU
let cons_vec = cons_bv
+let cons_vec_maybe b v = Just (cons_vec b v)
+let cons_vec_fail b v = return (cons_vec b v)
+let cons_vec_oracle b v = return (cons_vec b v)
-val bool_of_vec : mword ty1 -> bitU
-let bool_of_vec = bool_of_bv
-
-val cast_unit_vec : bitU -> mword ty1
+val cast_unit_vec : bitU -> list bitU
let cast_unit_vec = cast_unit_bv
+let cast_unit_vec_maybe b = Just (cast_unit_vec b)
+let cast_unit_vec_fail b = return (cast_unit_vec b)
+let cast_unit_vec_oracle b = return (cast_unit_vec b)
val vec_of_bit : integer -> bitU -> list bitU
let vec_of_bit = bv_of_bit
+let vec_of_bit_maybe len b = Just (vec_of_bit len b)
+let vec_of_bit_fail len b = return (vec_of_bit len b)
+let vec_of_bit_oracle len b = return (vec_of_bit len b)
val msb : list bitU -> bitU
let msb = most_significant
-val int_of_vec : bool -> list bitU -> integer
-let int_of_vec = int_of_bv
+val int_of_vec_maybe : bool -> list bitU -> maybe integer
+let int_of_vec_maybe = int_of_bv
+let int_of_vec_fail sign v = maybe_fail "int_of_vec" (int_of_vec_maybe sign v)
+let int_of_vec_oracle sign v = bools_of_bits_oracle v >>= (fun v -> return (int_of_bools sign v))
+let int_of_vec sign v = maybe_failwith (int_of_vec_maybe sign v)
val string_of_vec : list bitU -> string
let string_of_vec = string_of_bv
@@ -63,52 +96,75 @@ val and_vec : list bitU -> list bitU -> list bitU
val or_vec : list bitU -> list bitU -> list bitU
val xor_vec : list bitU -> list bitU -> list bitU
val not_vec : list bitU -> list bitU
-let and_vec = and_bv
-let or_vec = or_bv
-let xor_vec = xor_bv
-let not_vec = not_bv
+let and_vec = binop_list and_bit
+let or_vec = binop_list or_bit
+let xor_vec = binop_list xor_bit
+let not_vec = List.map not_bit
+
+val arith_op_double_bl : forall 'a 'b. Bitvector 'a =>
+ (integer -> integer -> integer) -> bool -> 'a -> 'a -> list bitU
+let arith_op_double_bl op sign l r =
+ let len = 2 * length l in
+ let l' = if sign then exts_bv len l else extz_bv len l in
+ let r' = if sign then exts_bv len r else extz_bv len r in
+ arith_op_bv op sign l' r'
val add_vec : list bitU -> list bitU -> list bitU
-val sadd_vec : list bitU -> list bitU -> list bitU
+val adds_vec : list bitU -> list bitU -> list bitU
val sub_vec : list bitU -> list bitU -> list bitU
val mult_vec : list bitU -> list bitU -> list bitU
-val smult_vec : list bitU -> list bitU -> list bitU
-let add_vec = add_bv
-let sadd_vec = sadd_bv
-let sub_vec = sub_bv
-let mult_vec = mult_bv
-let smult_vec = smult_bv
-
-val add_vec_int : list bitU -> integer -> list bitU
-val sadd_vec_int : list bitU -> integer -> list bitU
-val sub_vec_int : list bitU -> integer -> list bitU
-val mult_vec_int : list bitU -> integer -> list bitU
-val smult_vec_int : list bitU -> integer -> list bitU
-let add_vec_int = add_bv_int
-let sadd_vec_int = sadd_bv_int
-let sub_vec_int = sub_bv_int
-let mult_vec_int = mult_bv_int
-let smult_vec_int = smult_bv_int
-
-val add_int_vec : integer -> list bitU -> list bitU
-val sadd_int_vec : integer -> list bitU -> list bitU
-val sub_int_vec : integer -> list bitU -> list bitU
-val mult_int_vec : integer -> list bitU -> list bitU
-val smult_int_vec : integer -> list bitU -> list bitU
-let add_int_vec = add_int_bv
-let sadd_int_vec = sadd_int_bv
-let sub_int_vec = sub_int_bv
-let mult_int_vec = mult_int_bv
-let smult_int_vec = smult_int_bv
-
-val add_vec_bit : list bitU -> bitU -> list bitU
-val sadd_vec_bit : list bitU -> bitU -> list bitU
-val sub_vec_bit : list bitU -> bitU -> list bitU
-let add_vec_bit = add_bv_bit
-let sadd_vec_bit = sadd_bv_bit
-let sub_vec_bit = sub_bv_bit
-
-val add_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
+val mults_vec : list bitU -> list bitU -> list bitU
+let add_vec = arith_op_bv integerAdd false
+let adds_vec = arith_op_bv integerAdd true
+let sub_vec = arith_op_bv integerMinus false
+let mult_vec = arith_op_double_bl integerMult false
+let mults_vec = arith_op_double_bl integerMult true
+
+val add_vec_int : list bitU -> integer -> list bitU
+val adds_vec_int : list bitU -> integer -> list bitU
+val sub_vec_int : list bitU -> integer -> list bitU
+val mult_vec_int : list bitU -> integer -> list bitU
+val mults_vec_int : list bitU -> integer -> list bitU
+let add_vec_int l r = arith_op_bv_int integerAdd false l r
+let adds_vec_int l r = arith_op_bv_int integerAdd true l r
+let sub_vec_int l r = arith_op_bv_int integerMinus false l r
+let mult_vec_int l r = arith_op_double_bl integerMult false l (of_int (length l) r)
+let mults_vec_int l r = arith_op_double_bl integerMult true l (of_int (length l) r)
+
+val add_int_vec : integer -> list bitU -> list bitU
+val adds_int_vec : integer -> list bitU -> list bitU
+val sub_int_vec : integer -> list bitU -> list bitU
+val mult_int_vec : integer -> list bitU -> list bitU
+val mults_int_vec : integer -> list bitU -> list bitU
+let add_int_vec l r = arith_op_int_bv integerAdd false l r
+let adds_int_vec l r = arith_op_int_bv integerAdd true l r
+let sub_int_vec l r = arith_op_int_bv integerMinus false l r
+let mult_int_vec l r = arith_op_double_bl integerMult false (of_int (length r) l) r
+let mults_int_vec l r = arith_op_double_bl integerMult true (of_int (length r) l) r
+
+val add_vec_bit : list bitU -> bitU -> list bitU
+val adds_vec_bit : list bitU -> bitU -> list bitU
+val sub_vec_bit : list bitU -> bitU -> list bitU
+
+let add_vec_bool l r = arith_op_bv_bool integerAdd false l r
+let add_vec_bit_maybe l r = arith_op_bv_bit integerAdd false l r
+let add_vec_bit_fail l r = maybe_fail "add_vec_bit" (add_vec_bit_maybe l r)
+let add_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (add_vec_bool l r))
+let add_vec_bit l r = fromMaybe (repeat [BU] (length l)) (add_vec_bit_maybe l r)
+
+let adds_vec_bool l r = arith_op_bv_bool integerAdd true l r
+let adds_vec_bit_maybe l r = arith_op_bv_bit integerAdd true l r
+let adds_vec_bit_fail l r = maybe_fail "adds_vec_bit" (adds_vec_bit_maybe l r)
+let adds_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (adds_vec_bool l r))
+let adds_vec_bit l r = fromMaybe (repeat [BU] (length l)) (adds_vec_bit_maybe l r)
+
+let sub_vec_bool l r = arith_op_bv_bool integerMinus false l r
+let sub_vec_bit_maybe l r = arith_op_bv_bit integerMinus false l r
+let sub_vec_bit_fail l r = maybe_fail "sub_vec_bit" (sub_vec_bit_maybe l r)
+let sub_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (sub_vec_bool l r))
+let sub_vec_bit l r = fromMaybe (repeat [BU] (length l)) (sub_vec_bit_maybe l r)
+
+(*val add_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
val add_overflow_vec_signed : list bitU -> list bitU -> (list bitU * bitU * bitU)
val sub_overflow_vec : list bitU -> list bitU -> (list bitU * bitU * bitU)
val sub_overflow_vec_signed : list bitU -> list bitU -> (list bitU * bitU * bitU)
@@ -128,7 +184,7 @@ val sub_overflow_vec_bit_signed : list bitU -> bitU -> (list bitU * bitU * bitU
let add_overflow_vec_bit = add_overflow_bv_bit
let add_overflow_vec_bit_signed = add_overflow_bv_bit_signed
let sub_overflow_vec_bit = sub_overflow_bv_bit
-let sub_overflow_vec_bit_signed = sub_overflow_bv_bit_signed
+let sub_overflow_vec_bit_signed = sub_overflow_bv_bit_signed*)
val shiftl : list bitU -> integer -> list bitU
val shiftr : list bitU -> integer -> list bitU
@@ -141,23 +197,28 @@ let arith_shiftr = arith_shiftr_bv
let rotl = rotl_bv
let rotr = rotr_bv
-val mod_vec : list bitU -> list bitU -> list bitU
-val quot_vec : list bitU -> list bitU -> list bitU
-val quot_vec_signed : list bitU -> list bitU -> list bitU
-let mod_vec = mod_bv
-let quot_vec = quot_bv
-let quot_vec_signed = quot_bv_signed
+val mod_vec : list bitU -> list bitU -> list bitU
+val quot_vec : list bitU -> list bitU -> list bitU
+val quots_vec : list bitU -> list bitU -> list bitU
+let mod_vec l r = fromMaybe (repeat [BU] (length l)) (mod_bv l r)
+let quot_vec l r = fromMaybe (repeat [BU] (length l)) (quot_bv l r)
+let quots_vec l r = fromMaybe (repeat [BU] (length l)) (quots_bv l r)
-val mod_vec_int : list bitU -> integer -> list bitU
-val quot_vec_int : list bitU -> integer -> list bitU
-let mod_vec_int = mod_bv_int
-let quot_vec_int = quot_bv_int
+val mod_vec_int : list bitU -> integer -> list bitU
+val quot_vec_int : list bitU -> integer -> list bitU
+let mod_vec_int l r = fromMaybe (repeat [BU] (length l)) (mod_bv_int l r)
+let quot_vec_int l r = fromMaybe (repeat [BU] (length l)) (quot_bv_int l r)
val replicate_bits : list bitU -> integer -> list bitU
let replicate_bits = replicate_bits_bv
val duplicate : bitU -> integer -> list bitU
let duplicate = duplicate_bit_bv
+let duplicate_maybe b n = Just (duplicate b n)
+let duplicate_fail b n = return (duplicate b n)
+let duplicate_oracle b n =
+ bool_of_bitU_oracle b >>= (fun b ->
+ return (duplicate (bitU_of_bool b) n))
val eq_vec : list bitU -> list bitU -> bool
val neq_vec : list bitU -> list bitU -> bool
diff --git a/src/gen_lib/sail_operators_mwords.lem b/src/gen_lib/sail_operators_mwords.lem
index 7411c0a9..ea7c11cf 100644
--- a/src/gen_lib/sail_operators_mwords.lem
+++ b/src/gen_lib/sail_operators_mwords.lem
@@ -2,59 +2,109 @@ open import Pervasives_extra
open import Machine_word
open import Sail_values
open import Sail_operators
+open import Prompt_monad
+open import Prompt
+
+val mword_zero : forall 'a. Size 'a => mword 'a
+let mword_zero = wordFromInteger 0
(* Specialisation of operators to machine words *)
+let uint v = unsignedIntegerFromWord v
+let uint_maybe v = Just (uint v)
+let uint_fail v = return (uint v)
+let uint_oracle v = return (uint v)
+
+let sint v = signedIntegerFromWord v
+let sint_maybe v = Just (sint v)
+let sint_fail v = return (sint v)
+let sint_oracle v = return (sint v)
+
+val vec_of_bits_failwith : forall 'a. Size 'a => integer -> list bitU -> mword 'a
+let vec_of_bits_failwith _ bits = of_bits_failwith bits
+
+val vec_of_bits_fail : forall 'rv 'a 'e. Size 'a => integer -> list bitU -> monad 'rv (mword 'a) 'e
+let vec_of_bits_fail _ bits = of_bits_fail bits
+
+val vec_of_bits_oracle : forall 'rv 'a 'e. Size 'a => integer -> list bitU -> monad 'rv (mword 'a) 'e
+let vec_of_bits_oracle _ bits = of_bits_oracle bits
+
val access_vec_inc : forall 'a. Size 'a => mword 'a -> integer -> bitU
let access_vec_inc = access_bv_inc
val access_vec_dec : forall 'a. Size 'a => mword 'a -> integer -> bitU
let access_vec_dec = access_bv_dec
-val update_vec_inc : forall 'a. Size 'a => mword 'a -> integer -> bitU -> mword 'a
-let update_vec_inc = update_bv_inc
+let update_vec_dec_maybe w i b = update_mword_dec w i b
+let update_vec_dec_fail w i b =
+ bool_of_bitU_fail b >>= (fun b ->
+ return (update_mword_bool_dec w i b))
+let update_vec_dec_oracle w i b =
+ bool_of_bitU_oracle b >>= (fun b ->
+ return (update_mword_bool_dec w i b))
+let update_vec_dec w i b = maybe_failwith (update_vec_dec_maybe w i b)
+
+let update_vec_inc_maybe w i b = update_mword_inc w i b
+let update_vec_inc_fail w i b =
+ bool_of_bitU_fail b >>= (fun b ->
+ return (update_mword_bool_inc w i b))
+let update_vec_inc_oracle w i b =
+ bool_of_bitU_oracle b >>= (fun b ->
+ return (update_mword_bool_inc w i b))
+let update_vec_inc w i b = maybe_failwith (update_vec_inc_maybe w i b)
-val update_vec_dec : forall 'a. Size 'a => mword 'a -> integer -> bitU -> mword 'a
-let update_vec_dec = update_bv_dec
+val subrange_vec_dec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b
+let subrange_vec_dec w i j = Machine_word.word_extract (nat_of_int i) (nat_of_int j) w
val subrange_vec_inc : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b
-let subrange_vec_inc = subrange_bv_inc
+let subrange_vec_inc w i j = subrange_vec_dec w (length w - 1 - i) (length w - 1 - j)
-val subrange_vec_dec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b
-let subrange_vec_dec = subrange_bv_dec
+val update_subrange_vec_dec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b -> mword 'a
+let update_subrange_vec_dec w i j w' = Machine_word.word_update w (nat_of_int i) (nat_of_int j) w'
val update_subrange_vec_inc : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b -> mword 'a
-let update_subrange_vec_inc = update_subrange_bv_inc
-
-val update_subrange_vec_dec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> integer -> mword 'b -> mword 'a
-let update_subrange_vec_dec = update_subrange_bv_dec
+let update_subrange_vec_inc w i j w' = update_subrange_vec_dec w (length w - 1 - i) (length w - 1 - j) w'
val extz_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
-let extz_vec = extz_bv
+let extz_vec _ w = Machine_word.zeroExtend w
val exts_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
-let exts_vec = exts_bv
+let exts_vec _ w = Machine_word.signExtend w
val concat_vec : forall 'a 'b 'c. Size 'a, Size 'b, Size 'c => mword 'a -> mword 'b -> mword 'c
-let concat_vec = concat_bv
-
-val cons_vec : forall 'a 'b 'c. Size 'a, Size 'b => bitU -> mword 'a -> mword 'b
-let cons_vec = cons_bv
-
-val bool_of_vec : mword ty1 -> bitU
-let bool_of_vec = bool_of_bv
-
-val cast_unit_vec : bitU -> mword ty1
-let cast_unit_vec = cast_unit_bv
-
-val vec_of_bit : forall 'a. Size 'a => integer -> bitU -> mword 'a
-let vec_of_bit = bv_of_bit
+let concat_vec = Machine_word.word_concat
+
+val cons_vec_bool : forall 'a 'b 'c. Size 'a, Size 'b => bool -> mword 'a -> mword 'b
+let cons_vec_bool b w = wordFromBitlist (b :: bitlistFromWord w)
+let cons_vec_maybe b w = Maybe.map (fun b -> cons_vec_bool b w) (bool_of_bitU b)
+let cons_vec_fail b w = bool_of_bitU_fail b >>= (fun b -> return (cons_vec_bool b w))
+let cons_vec_oracle b w = bool_of_bitU_oracle b >>= (fun b -> return (cons_vec_bool b w))
+let cons_vec b w = maybe_failwith (cons_vec_maybe b w)
+
+val vec_of_bool : forall 'a. Size 'a => integer -> bool -> mword 'a
+let vec_of_bool _ b = wordFromBitlist [b]
+let vec_of_bit_maybe len b = Maybe.map (vec_of_bool len) (bool_of_bitU b)
+let vec_of_bit_fail len b = bool_of_bitU_fail b >>= (fun b -> return (vec_of_bool len b))
+let vec_of_bit_oracle len b = bool_of_bitU_oracle b >>= (fun b -> return (vec_of_bool len b))
+let vec_of_bit len b = maybe_failwith (vec_of_bit_maybe len b)
+
+val cast_bool_vec : bool -> mword ty1
+let cast_bool_vec b = vec_of_bool 1 b
+let cast_unit_vec_maybe b = vec_of_bit_maybe 1 b
+let cast_unit_vec_fail b = bool_of_bitU_fail b >>= (fun b -> return (cast_bool_vec b))
+let cast_unit_vec_oracle b = bool_of_bitU_oracle b >>= (fun b -> return (cast_bool_vec b))
+let cast_unit_vec b = maybe_failwith (cast_unit_vec_maybe b)
val msb : forall 'a. Size 'a => mword 'a -> bitU
let msb = most_significant
val int_of_vec : forall 'a. Size 'a => bool -> mword 'a -> integer
-let int_of_vec = int_of_bv
+let int_of_vec sign w =
+ if sign
+ then signedIntegerFromWord w
+ else unsignedIntegerFromWord w
+let int_of_vec_maybe sign w = Just (int_of_vec sign w)
+let int_of_vec_fail sign w = return (int_of_vec sign w)
val string_of_vec : forall 'a. Size 'a => mword 'a -> string
let string_of_vec = string_of_bv
@@ -63,63 +113,83 @@ val and_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
val or_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
val xor_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
val not_vec : forall 'a. Size 'a => mword 'a -> mword 'a
-let and_vec = and_bv
-let or_vec = or_bv
-let xor_vec = xor_bv
-let not_vec = not_bv
+let and_vec = Machine_word.lAnd
+let or_vec = Machine_word.lOr
+let xor_vec = Machine_word.lXor
+let not_vec = Machine_word.lNot
val add_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
-val sadd_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val adds_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
val sub_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
val mult_vec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> mword 'a -> mword 'b
-val smult_vec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> mword 'a -> mword 'b
-let add_vec = add_bv
-let sadd_vec = sadd_bv
-let sub_vec = sub_bv
-let mult_vec = mult_bv
-let smult_vec = smult_bv
+val mults_vec : forall 'a 'b. Size 'a, Size 'b => mword 'a -> mword 'a -> mword 'b
+let add_vec l r = arith_op_bv integerAdd false l r
+let adds_vec l r = arith_op_bv integerAdd true l r
+let sub_vec l r = arith_op_bv integerMinus true l r
+let mult_vec l r = arith_op_bv integerMult false (zeroExtend l : mword 'b) (zeroExtend r : mword 'b)
+let mults_vec l r = arith_op_bv integerMult true (signExtend l : mword 'b) (signExtend r : mword 'b)
val add_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
-val sadd_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
+val adds_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val sub_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val mult_vec_int : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b
-val smult_vec_int : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b
-let add_vec_int = add_bv_int
-let sadd_vec_int = sadd_bv_int
-let sub_vec_int = sub_bv_int
-let mult_vec_int = mult_bv_int
-let smult_vec_int = smult_bv_int
+val mults_vec_int : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b
+let add_vec_int l r = arith_op_bv_int integerAdd false l r
+let adds_vec_int l r = arith_op_bv_int integerAdd true l r
+let sub_vec_int l r = arith_op_bv_int integerMinus true l r
+let mult_vec_int l r = arith_op_bv_int integerMult false (zeroExtend l : mword 'b) r
+let mults_vec_int l r = arith_op_bv_int integerMult true (signExtend l : mword 'b) r
val add_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
-val sadd_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
+val adds_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
val sub_int_vec : forall 'a. Size 'a => integer -> mword 'a -> mword 'a
val mult_int_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
-val smult_int_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
-let add_int_vec = add_int_bv
-let sadd_int_vec = sadd_int_bv
-let sub_int_vec = sub_int_bv
-let mult_int_vec = mult_int_bv
-let smult_int_vec = smult_int_bv
-
-val add_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
-val sadd_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
-val sub_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> mword 'a
-let add_vec_bit = add_bv_bit
-let sadd_vec_bit = sadd_bv_bit
-let sub_vec_bit = sub_bv_bit
-
-val add_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-val add_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-val sub_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-val sub_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-val mult_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-val mult_overflow_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> (mword 'a * bitU * bitU)
-let add_overflow_vec = add_overflow_bv
-let add_overflow_vec_signed = add_overflow_bv_signed
-let sub_overflow_vec = sub_overflow_bv
-let sub_overflow_vec_signed = sub_overflow_bv_signed
-let mult_overflow_vec = mult_overflow_bv
-let mult_overflow_vec_signed = mult_overflow_bv_signed
+val mults_int_vec : forall 'a 'b. Size 'a, Size 'b => integer -> mword 'a -> mword 'b
+let add_int_vec l r = arith_op_int_bv integerAdd false l r
+let adds_int_vec l r = arith_op_int_bv integerAdd true l r
+let sub_int_vec l r = arith_op_int_bv integerMinus true l r
+let mult_int_vec l r = arith_op_int_bv integerMult false l (zeroExtend r : mword 'b)
+let mults_int_vec l r = arith_op_int_bv integerMult true l (signExtend r : mword 'b)
+
+val add_vec_bool : forall 'a. Size 'a => mword 'a -> bool -> mword 'a
+val adds_vec_bool : forall 'a. Size 'a => mword 'a -> bool -> mword 'a
+val sub_vec_bool : forall 'a. Size 'a => mword 'a -> bool -> mword 'a
+
+let add_vec_bool l r = arith_op_bv_bool integerAdd false l r
+let add_vec_bit_maybe l r = Maybe.map (add_vec_bool l) (bool_of_bitU r)
+let add_vec_bit_fail l r = bool_of_bitU_fail r >>= (fun r -> return (add_vec_bool l r))
+let add_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (add_vec_bool l r))
+let add_vec_bit l r = maybe_failwith (add_vec_bit_maybe l r)
+
+let adds_vec_bool l r = arith_op_bv_bool integerAdd true l r
+let adds_vec_bit_maybe l r = Maybe.map (adds_vec_bool l) (bool_of_bitU r)
+let adds_vec_bit_fail l r = bool_of_bitU_fail r >>= (fun r -> return (adds_vec_bool l r))
+let adds_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (adds_vec_bool l r))
+let adds_vec_bit l r = maybe_failwith (adds_vec_bit_maybe l r)
+
+let sub_vec_bool l r = arith_op_bv_bool integerMinus true l r
+let sub_vec_bit_maybe l r = Maybe.map (sub_vec_bool l) (bool_of_bitU r)
+let sub_vec_bit_fail l r = bool_of_bitU_fail r >>= (fun r -> return (sub_vec_bool l r))
+let sub_vec_bit_oracle l r = bool_of_bitU_oracle r >>= (fun r -> return (sub_vec_bool l r))
+let sub_vec_bit l r = maybe_failwith (sub_vec_bit_maybe l r)
+
+(* TODO
+val maybe_mword_of_bits_overflow : forall 'a. Size 'a => (list bitU * bitU * bitU) -> maybe (mword 'a * bitU * bitU)
+let maybe_mword_of_bits_overflow (bits, overflow, carry) =
+ Maybe.map (fun w -> (w, overflow, carry)) (of_bits bits)
+
+val add_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+val adds_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+val sub_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+val subs_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+val mult_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+val mults_overflow_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> maybe (mword 'a * bitU * bitU)
+let add_overflow_vec l r = maybe_mword_of_bits_overflow (add_overflow_bv l r)
+let adds_overflow_vec l r = maybe_mword_of_bits_overflow (adds_overflow_bv l r)
+let sub_overflow_vec l r = maybe_mword_of_bits_overflow (sub_overflow_bv l r)
+let subs_overflow_vec l r = maybe_mword_of_bits_overflow (subs_overflow_bv l r)
+let mult_overflow_vec l r = maybe_mword_of_bits_overflow (mult_overflow_bv l r)
+let mults_overflow_vec l r = maybe_mword_of_bits_overflow (mults_overflow_bv l r)
val add_overflow_vec_bit : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
val add_overflow_vec_bit_signed : forall 'a. Size 'a => mword 'a -> bitU -> (mword 'a * bitU * bitU)
@@ -128,36 +198,40 @@ val sub_overflow_vec_bit_signed : forall 'a. Size 'a => mword 'a -> bitU -> (mw
let add_overflow_vec_bit = add_overflow_bv_bit
let add_overflow_vec_bit_signed = add_overflow_bv_bit_signed
let sub_overflow_vec_bit = sub_overflow_bv_bit
-let sub_overflow_vec_bit_signed = sub_overflow_bv_bit_signed
+let sub_overflow_vec_bit_signed = sub_overflow_bv_bit_signed*)
val shiftl : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val shiftr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val arith_shiftr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val rotl : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val rotr : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
-let shiftl = shiftl_bv
-let shiftr = shiftr_bv
-let arith_shiftr = arith_shiftr_bv
-let rotl = rotl_bv
-let rotr = rotr_bv
-
-val mod_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
-val quot_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
-val quot_vec_signed : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
-let mod_vec = mod_bv
-let quot_vec = quot_bv
-let quot_vec_signed = quot_bv_signed
+let shiftl = shiftl_mword
+let shiftr = shiftr_mword
+let arith_shiftr = arith_shiftr_mword
+let rotl = rotl_mword
+let rotr = rotr_mword
+
+val mod_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val quot_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+val quots_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> mword 'a
+let mod_vec = mod_mword
+let quot_vec = quot_mword
+let quots_vec = quots_mword
val mod_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
val quot_vec_int : forall 'a. Size 'a => mword 'a -> integer -> mword 'a
-let mod_vec_int = mod_bv_int
-let quot_vec_int = quot_bv_int
+let mod_vec_int = mod_mword_int
+let quot_vec_int = quot_mword_int
val replicate_bits : forall 'a 'b. Size 'a, Size 'b => mword 'a -> integer -> mword 'b
-let replicate_bits = replicate_bits_bv
+let replicate_bits v count = wordFromBitlist (repeat (bitlistFromWord v) count)
-val duplicate : forall 'a. Size 'a => bitU -> integer -> mword 'a
-let duplicate = duplicate_bit_bv
+val duplicate_bool : forall 'a. Size 'a => bool -> integer -> mword 'a
+let duplicate_bool b n = wordFromBitlist (repeat [b] n)
+let duplicate_maybe b n = Maybe.map (fun b -> duplicate_bool b n) (bool_of_bitU b)
+let duplicate_fail b n = bool_of_bitU_fail b >>= (fun b -> return (duplicate_bool b n))
+let duplicate_oracle b n = bool_of_bitU_oracle b >>= (fun b -> return (duplicate_bool b n))
+let duplicate b n = maybe_failwith (duplicate_maybe b n)
val eq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
val neq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
@@ -169,13 +243,13 @@ val ulteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
val slteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
val ugteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
val sgteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-let eq_vec = eq_bv
-let neq_vec = neq_bv
-let ult_vec = ult_bv
-let slt_vec = slt_bv
-let ugt_vec = ugt_bv
-let sgt_vec = sgt_bv
-let ulteq_vec = ulteq_bv
-let slteq_vec = slteq_bv
-let ugteq_vec = ugteq_bv
-let sgteq_vec = sgteq_bv
+let eq_vec = eq_mword
+let neq_vec = neq_mword
+let ult_vec = ucmp_mword (<)
+let slt_vec = scmp_mword (<)
+let ugt_vec = ucmp_mword (>)
+let sgt_vec = scmp_mword (>)
+let ulteq_vec = ucmp_mword (<=)
+let slteq_vec = scmp_mword (<=)
+let ugteq_vec = ucmp_mword (>=)
+let sgteq_vec = scmp_mword (>=)
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem
index edb8da88..238ebe58 100644
--- a/src/gen_lib/sail_values.lem
+++ b/src/gen_lib/sail_values.lem
@@ -1,5 +1,3 @@
-(* Version of sail_values.lem that uses Lem's machine words library *)
-
open import Pervasives_extra
open import Machine_word
(*open import Sail_impl_base*)
@@ -8,8 +6,11 @@ open import Machine_word
type ii = integer
type nn = natural
+val nat_of_int : integer -> nat
+let nat_of_int i = if i < 0 then 0 else natFromInteger i
+
val pow : integer -> integer -> integer
-let pow m n = m ** (natFromInteger n)
+let pow m n = m ** (nat_of_int n)
let pow2 n = pow 2 n
@@ -31,7 +32,7 @@ let mult_int l r = integerMult l r
let div_int l r = integerDiv l r
let div_nat l r = natDiv l r
let power_int_nat l r = integerPow l r
-let power_int_int l r = integerPow l (natFromInteger r)
+let power_int_int l r = integerPow l (nat_of_int r)
let negate_int i = integerNegate i
let min_int l r = integerMin l r
let max_int l r = integerMax l r
@@ -50,8 +51,8 @@ let xor_bool l r = xor l r
let append_list l r = l ++ r
let length_list xs = integerFromNat (List.length xs)
-let take_list n xs = List.take (natFromInteger n) xs
-let drop_list n xs = List.drop (natFromInteger n) xs
+let take_list n xs = List.take (nat_of_int n) xs
+let drop_list n xs = List.drop (nat_of_int n) xs
val repeat : forall 'a. list 'a -> integer -> list 'a
let rec repeat xs n =
@@ -99,6 +100,29 @@ let min_8 = (0 - 128 : integer)
let max_5 = (31 : integer)
let min_5 = (0 - 32 : integer)
+(* just_list takes a list of maybes and returns Just xs if all elements have
+ a value, and Nothing if one of the elements is Nothing. *)
+val just_list : forall 'a. list (maybe 'a) -> maybe (list 'a)
+let rec just_list l = match l with
+ | [] -> Just []
+ | (x :: xs) ->
+ match (x, just_list xs) with
+ | (Just x, Just xs) -> Just (x :: xs)
+ | (_, _) -> Nothing
+ end
+ end
+declare {isabelle} termination_argument just_list = automatic
+
+lemma just_list_spec:
+ ((forall xs. (just_list xs = Nothing) <-> List.elem Nothing xs) &&
+ (forall xs es. (just_list xs = Just es) <-> (xs = List.map Just es)))
+
+val maybe_failwith : forall 'a. maybe 'a -> 'a
+let maybe_failwith = function
+ | Just a -> a
+ | Nothing -> failwith "maybe_failwith"
+end
+
(*** Bits *)
type bitU = B0 | B1 | BU
@@ -118,6 +142,25 @@ instance (Show bitU)
let show = showBitU
end
+val compare_bitU : bitU -> bitU -> ordering
+let compare_bitU l r = match (l, r) with
+ | (BU, BU) -> EQ
+ | (B0, B0) -> EQ
+ | (B1, B1) -> EQ
+ | (BU, _) -> LT
+ | (_, BU) -> GT
+ | (B0, _) -> LT
+ | (_, _) -> GT
+end
+
+instance (Ord bitU)
+ let compare = compare_bitU
+ let (<) l r = (compare_bitU l r) = LT
+ let (<=) l r = (compare_bitU l r) <> GT
+ let (>) l r = (compare_bitU l r) = GT
+ let (>=) l r = (compare_bitU l r) <> LT
+end
+
class (BitU 'a)
val to_bitU : 'a -> bitU
val of_bitU : bitU -> 'a
@@ -129,44 +172,20 @@ instance (BitU bitU)
end
let bool_of_bitU = function
- | B0 -> false
- | B1 -> true
- | BU -> failwith "bool_of_bitU applied to BU"
+ | B0 -> Just false
+ | B1 -> Just true
+ | BU -> Nothing
end
let bitU_of_bool b = if b then B1 else B0
-instance (BitU bool)
+(*instance (BitU bool)
let to_bitU = bitU_of_bool
let of_bitU = bool_of_bitU
-end
+end*)
let cast_bit_bool = bool_of_bitU
-(*let bit_lifted_of_bitU = function
- | B0 -> Bitl_zero
- | B1 -> Bitl_one
- | BU -> Bitl_undef
- end
-
-let bitU_of_bit = function
- | Bitc_zero -> B0
- | Bitc_one -> B1
- end
-
-let bit_of_bitU = function
- | B0 -> Bitc_zero
- | B1 -> Bitc_one
- | BU -> failwith "bit_of_bitU: BU"
- end
-
-let bitU_of_bit_lifted = function
- | Bitl_zero -> B0
- | Bitl_one -> B1
- | Bitl_undef -> BU
- | Bitl_unknown -> failwith "bitU_of_bit_lifted Bitl_unknown"
- end*)
-
let not_bit = function
| B1 -> B0
| B0 -> B1
@@ -177,20 +196,33 @@ val is_one : integer -> bitU
let is_one i =
if i = 1 then B1 else B0
-let binop_bit op x y = match (x, y) with
- | (BU,_) -> BU (*Do we want to do this or to respect | of I and & of B0 rules?*)
- | (_,BU) -> BU (*Do we want to do this or to respect | of I and & of B0 rules?*)
- | (x,y) -> bitU_of_bool (op (bool_of_bitU x) (bool_of_bitU y))
- end
-
val and_bit : bitU -> bitU -> bitU
-let and_bit = binop_bit (&&)
+let and_bit x y =
+ match (x, y) with
+ | (B0, _) -> B0
+ | (_, B0) -> B0
+ | (B1, B1) -> B1
+ | (_, _) -> BU
+ end
val or_bit : bitU -> bitU -> bitU
-let or_bit = binop_bit (||)
+let or_bit x y =
+ match (x, y) with
+ | (B1, _) -> B1
+ | (_, B1) -> B1
+ | (B0, B0) -> B0
+ | (_, _) -> BU
+ end
val xor_bit : bitU -> bitU -> bitU
-let xor_bit = binop_bit xor
+let xor_bit x y=
+ match (x, y) with
+ | (B0, B0) -> B0
+ | (B0, B1) -> B1
+ | (B1, B0) -> B1
+ | (B1, B1) -> B0
+ | (_, _) -> BU
+ end
val (&.) : bitU -> bitU -> bitU
let inline (&.) x y = and_bit x y
@@ -202,81 +234,134 @@ val (+.) : bitU -> bitU -> bitU
let inline (+.) x y = xor_bit x y
-(*** Bit lists ***)
+(*** Bool lists ***)
-val bits_of_nat_aux : natural -> list bitU
-let rec bits_of_nat_aux x =
+val bools_of_nat_aux : natural -> list bool
+let rec bools_of_nat_aux x =
if x = 0 then []
- else (if x mod 2 = 1 then B1 else B0) :: bits_of_nat_aux (x / 2)
-declare {isabelle} termination_argument bits_of_nat_aux = automatic
-let bits_of_nat n = List.reverse (bits_of_nat_aux n)
+ else (if x mod 2 = 1 then true else false) :: bools_of_nat_aux (x / 2)
+declare {isabelle} termination_argument bools_of_nat_aux = automatic
+let bools_of_nat n = List.reverse (bools_of_nat_aux n)
-val nat_of_bits_aux : natural -> list bitU -> natural
-let rec nat_of_bits_aux acc bs = match bs with
+val nat_of_bools_aux : natural -> list bool -> natural
+let rec nat_of_bools_aux acc bs = match bs with
| [] -> acc
- | B1 :: bs -> nat_of_bits_aux ((2 * acc) + 1) bs
- | B0 :: bs -> nat_of_bits_aux (2 * acc) bs
- | BU :: _ -> failwith "nat_of_bits_aux: bit list has undefined bits"
+ | true :: bs -> nat_of_bools_aux ((2 * acc) + 1) bs
+ | false :: bs -> nat_of_bools_aux (2 * acc) bs
end
-declare {isabelle} termination_argument nat_of_bits_aux = automatic
-let nat_of_bits bits = nat_of_bits_aux 0 bits
+declare {isabelle} termination_argument nat_of_bools_aux = automatic
+let nat_of_bools bs = nat_of_bools_aux 0 bs
+
+val unsigned_of_bools : list bool -> integer
+let unsigned_of_bools bs = integerFromNatural (nat_of_bools bs)
+
+val signed_of_bools : list bool -> integer
+let signed_of_bools bs =
+ match bs with
+ | true :: _ -> 0 - (1 + (unsigned_of_bools (List.map not bs)))
+ | false :: _ -> unsigned_of_bools bs
+ | [] -> 0 (* Treat empty list as all zeros *)
+ end
-let not_bits = List.map not_bit
+val int_of_bools : bool -> list bool -> integer
+let int_of_bools sign bs = if sign then signed_of_bools bs else unsigned_of_bools bs
-let binop_bits op bsl bsr =
- foldr (fun (bl, br) acc -> binop_bit op bl br :: acc) [] (zip bsl bsr)
+val pad_list : forall 'a. 'a -> list 'a -> integer -> list 'a
+let rec pad_list x xs n =
+ if n <= 0 then xs else pad_list x (x :: xs) (n - 1)
+declare {isabelle} termination_argument pad_list = automatic
-let and_bits = binop_bits (&&)
-let or_bits = binop_bits (||)
-let xor_bits = binop_bits xor
+let ext_list pad len xs =
+ let longer = len - (integerFromNat (List.length xs)) in
+ if longer < 0 then drop (nat_of_int (abs (longer))) xs
+ else pad_list pad xs longer
-val unsigned_of_bits : list bitU -> integer
-let unsigned_of_bits bs = integerFromNatural (nat_of_bits bs)
+let extz_bools len bs = ext_list false len bs
+let exts_bools len bs =
+ match bs with
+ | true :: _ -> ext_list true len bs
+ | _ -> ext_list false len bs
+ end
-val signed_of_bits : list bitU -> integer
-let signed_of_bits bits =
- match bits with
- | B1 :: _ -> 0 - (1 + (unsigned_of_bits (not_bits bits)))
- | B0 :: _ -> unsigned_of_bits bits
- | BU :: _ -> failwith "signed_of_bits applied to list with undefined bits"
- | [] -> failwith "signed_of_bits applied to empty list"
+let rec add_one_bool_ignore_overflow_aux bits = match bits with
+ | [] -> []
+ | false :: bits -> true :: bits
+ | true :: bits -> false :: add_one_bool_ignore_overflow_aux bits
+end
+declare {isabelle} termination_argument add_one_bool_ignore_overflow_aux = automatic
+
+let add_one_bool_ignore_overflow bits =
+ List.reverse (add_one_bool_ignore_overflow_aux (List.reverse bits))
+
+let bool_list_of_int n =
+ let bs_abs = false :: bools_of_nat (naturalFromInteger (abs n)) in
+ if n >= (0 : integer) then bs_abs
+ else add_one_bool_ignore_overflow (List.map not bs_abs)
+let bools_of_int len n = exts_bools len (bool_list_of_int n)
+
+(*** Bit lists ***)
+
+val has_undefined_bits : list bitU -> bool
+let has_undefined_bits bs = List.any (function BU -> true | _ -> false end) bs
+
+let bits_of_nat n = List.map bitU_of_bool (bools_of_nat n)
+
+let nat_of_bits bits =
+ match (just_list (List.map bool_of_bitU bits)) with
+ | Just bs -> Just (nat_of_bools bs)
+ | Nothing -> Nothing
+ end
+
+let not_bits = List.map not_bit
+
+val binop_list : forall 'a. ('a -> 'a -> 'a) -> list 'a -> list 'a -> list 'a
+let binop_list op xs ys =
+ foldr (fun (x, y) acc -> op x y :: acc) [] (zip xs ys)
+
+let unsigned_of_bits bits =
+ match (just_list (List.map bool_of_bitU bits)) with
+ | Just bs -> Just (unsigned_of_bools bs)
+ | Nothing -> Nothing
end
-val pad_bitlist : bitU -> list bitU -> integer -> list bitU
-let rec pad_bitlist b bits n =
- if n <= 0 then bits else pad_bitlist b (b :: bits) (n - 1)
-declare {isabelle} termination_argument pad_bitlist = automatic
+let signed_of_bits bits =
+ match (just_list (List.map bool_of_bitU bits)) with
+ | Just bs -> Just (signed_of_bools bs)
+ | Nothing -> Nothing
+ end
-let ext_bits pad len bits =
- let longer = len - (integerFromNat (List.length bits)) in
- if longer < 0 then drop (natFromInteger (abs (longer))) bits
- else pad_bitlist pad bits longer
+val int_of_bits : bool -> list bitU -> maybe integer
+let int_of_bits sign bs = if sign then signed_of_bits bs else unsigned_of_bits bs
-let extz_bits len bits = ext_bits B0 len bits
+let extz_bits len bits = ext_list B0 len bits
let exts_bits len bits =
match bits with
- | BU :: _ -> failwith "exts_bits: undefined bit"
- | B1 :: _ -> ext_bits B1 len bits
- | _ -> ext_bits B0 len bits
+ | BU :: _ -> ext_list BU len bits
+ | B1 :: _ -> ext_list B1 len bits
+ | _ -> ext_list B0 len bits
end
let rec add_one_bit_ignore_overflow_aux bits = match bits with
| [] -> []
| B0 :: bits -> B1 :: bits
| B1 :: bits -> B0 :: add_one_bit_ignore_overflow_aux bits
- | BU :: _ -> failwith "add_one_bit_ignore_overflow: undefined bit"
+ | BU :: bits -> BU :: List.map (fun _ -> BU) bits
end
declare {isabelle} termination_argument add_one_bit_ignore_overflow_aux = automatic
let add_one_bit_ignore_overflow bits =
List.reverse (add_one_bit_ignore_overflow_aux (List.reverse bits))
-let bitlist_of_int n =
- let bits_abs = B0 :: bits_of_nat (naturalFromInteger (abs n)) in
- if n >= (0 : integer) then bits_abs
- else add_one_bit_ignore_overflow (not_bits bits_abs)
+let bit_list_of_int n = List.map bitU_of_bool (bool_list_of_int n)
+let bits_of_int len n = exts_bits len (bit_list_of_int n)
-let bits_of_int len n = exts_bits len (bitlist_of_int n)
+val arith_op_bits :
+ (integer -> integer -> integer) -> bool -> list bitU -> list bitU -> list bitU
+let arith_op_bits op sign l r =
+ match (int_of_bits sign l, int_of_bits sign r) with
+ | (Just li, Just ri) -> bits_of_int (length_list l) (op li ri)
+ | (_, _) -> repeat [BU] (length_list l)
+ end
let char_of_nibble = function
| (B0, B0, B0, B0) -> Just #'0'
@@ -322,8 +407,8 @@ let inline (^^) = append_list
val subrange_list_inc : forall 'a. list 'a -> integer -> integer -> list 'a
let subrange_list_inc xs i j =
- let (toJ,_suffix) = List.splitAt (natFromInteger j + 1) xs in
- let (_prefix,fromItoJ) = List.splitAt (natFromInteger i) toJ in
+ let (toJ,_suffix) = List.splitAt (nat_of_int (j + 1)) xs in
+ let (_prefix,fromItoJ) = List.splitAt (nat_of_int i) toJ in
fromItoJ
val subrange_list_dec : forall 'a. list 'a -> integer -> integer -> list 'a
@@ -336,8 +421,8 @@ let subrange_list is_inc xs i j = if is_inc then subrange_list_inc xs i j else s
val update_subrange_list_inc : forall 'a. list 'a -> integer -> integer -> list 'a -> list 'a
let update_subrange_list_inc xs i j xs' =
- let (toJ,suffix) = List.splitAt (natFromInteger j + 1) xs in
- let (prefix,_fromItoJ) = List.splitAt (natFromInteger i) toJ in
+ let (toJ,suffix) = List.splitAt (nat_of_int (j + 1)) xs in
+ let (prefix,_fromItoJ) = List.splitAt (nat_of_int i) toJ in
prefix ++ xs' ++ suffix
val update_subrange_list_dec : forall 'a. list 'a -> integer -> integer -> list 'a -> list 'a
@@ -350,7 +435,7 @@ let update_subrange_list is_inc xs i j xs' =
if is_inc then update_subrange_list_inc xs i j xs' else update_subrange_list_dec xs i j xs'
val access_list_inc : forall 'a. list 'a -> integer -> 'a
-let access_list_inc xs n = List_extra.nth xs (natFromInteger n)
+let access_list_inc xs n = List_extra.nth xs (nat_of_int n)
val access_list_dec : forall 'a. list 'a -> integer -> 'a
let access_list_dec xs n =
@@ -362,7 +447,7 @@ let access_list is_inc xs n =
if is_inc then access_list_inc xs n else access_list_dec xs n
val update_list_inc : forall 'a. list 'a -> integer -> 'a -> list 'a
-let update_list_inc xs n x = List.update xs (natFromInteger n) x
+let update_list_inc xs n x = List.update xs (nat_of_int n) x
val update_list_dec : forall 'a. list 'a -> integer -> 'a -> list 'a
let update_list_dec xs n x =
@@ -373,36 +458,19 @@ val update_list : forall 'a. bool -> list 'a -> integer -> 'a -> list 'a
let update_list is_inc xs n x =
if is_inc then update_list_inc xs n x else update_list_dec xs n x
-let extract_only_element = function
- | [] -> failwith "extract_only_element called for empty list"
+let extract_only_bit = function
+ | [] -> BU
| [e] -> e
- | _ -> failwith "extract_only_element called for list with more elements"
+ | _ -> BU
end
-(* just_list takes a list of maybes and returns Just xs if all elements have
- a value, and Nothing if one of the elements is Nothing. *)
-val just_list : forall 'a. list (maybe 'a) -> maybe (list 'a)
-let rec just_list l = match l with
- | [] -> Just []
- | (x :: xs) ->
- match (x, just_list xs) with
- | (Just x, Just xs) -> Just (x :: xs)
- | (_, _) -> Nothing
- end
- end
-declare {isabelle} termination_argument just_list = automatic
-
-lemma just_list_spec:
- ((forall xs. (just_list xs = Nothing) <-> List.elem Nothing xs) &&
- (forall xs es. (just_list xs = Just es) <-> (xs = List.map Just es)))
-
(*** Machine words *)
val length_mword : forall 'a. mword 'a -> integer
let length_mword w = integerFromNat (word_length w)
val slice_mword_dec : forall 'a 'b. mword 'a -> integer -> integer -> mword 'b
-let slice_mword_dec w i j = word_extract (natFromInteger i) (natFromInteger j) w
+let slice_mword_dec w i j = word_extract (nat_of_int i) (nat_of_int j) w
val slice_mword_inc : forall 'a 'b. mword 'a -> integer -> integer -> mword 'b
let slice_mword_inc w i j =
@@ -413,7 +481,7 @@ val slice_mword : forall 'a 'b. bool -> mword 'a -> integer -> integer -> mword
let slice_mword is_inc w i j = if is_inc then slice_mword_inc w i j else slice_mword_dec w i j
val update_slice_mword_dec : forall 'a 'b. mword 'a -> integer -> integer -> mword 'b -> mword 'a
-let update_slice_mword_dec w i j w' = word_update w (natFromInteger i) (natFromInteger j) w'
+let update_slice_mword_dec w i j w' = word_update w (nat_of_int i) (nat_of_int j) w'
val update_slice_mword_inc : forall 'a 'b. mword 'a -> integer -> integer -> mword 'b -> mword 'a
let update_slice_mword_inc w i j w' =
@@ -425,7 +493,7 @@ let update_slice_mword is_inc w i j w' =
if is_inc then update_slice_mword_inc w i j w' else update_slice_mword_dec w i j w'
val access_mword_dec : forall 'a. mword 'a -> integer -> bitU
-let access_mword_dec w n = bitU_of_bool (getBit w (natFromInteger n))
+let access_mword_dec w n = bitU_of_bool (getBit w (nat_of_int n))
val access_mword_inc : forall 'a. mword 'a -> integer -> bitU
let access_mword_inc w n =
@@ -436,22 +504,19 @@ val access_mword : forall 'a. bool -> mword 'a -> integer -> bitU
let access_mword is_inc w n =
if is_inc then access_mword_inc w n else access_mword_dec w n
-val update_mword_dec : forall 'a. mword 'a -> integer -> bitU -> mword 'a
-let update_mword_dec w n b = setBit w (natFromInteger n) (bool_of_bitU b)
+val update_mword_bool_dec : forall 'a. mword 'a -> integer -> bool -> mword 'a
+let update_mword_bool_dec w n b = setBit w (nat_of_int n) b
+let update_mword_dec w n b = Maybe.map (update_mword_bool_dec w n) (bool_of_bitU b)
-val update_mword_inc : forall 'a. mword 'a -> integer -> bitU -> mword 'a
-let update_mword_inc w n b =
+val update_mword_bool_inc : forall 'a. mword 'a -> integer -> bool -> mword 'a
+let update_mword_bool_inc w n b =
let top = (length_mword w) - 1 in
- update_mword_dec w (top - n) b
-
-val update_mword : forall 'a. bool -> mword 'a -> integer -> bitU -> mword 'a
-let update_mword is_inc w n b =
- if is_inc then update_mword_inc w n b else update_mword_dec w n b
+ update_mword_bool_dec w (top - n) b
+let update_mword_inc w n b = Maybe.map (update_mword_bool_inc w n) (bool_of_bitU b)
-val mword_of_int : forall 'a. Size 'a => integer -> integer -> mword 'a
-let mword_of_int len n =
- let w = wordFromInteger n in
- if (length_mword w = len) then w else failwith "unexpected word length"
+val int_of_mword : forall 'a. bool -> mword 'a -> integer
+let int_of_mword sign w =
+ if sign then signedIntegerFromWord w else unsignedIntegerFromWord w
(* Translating between a type level number (itself 'n) and an integer *)
@@ -461,68 +526,71 @@ let size_itself_int x = integerFromNat (size_itself x)
the actual integer is ignored. *)
val make_the_value : forall 'n. integer -> itself 'n
-let inline make_the_value x = the_value
+let inline make_the_value = (fun _ -> the_value)
(*** Bitvectors *)
class (Bitvector 'a)
val bits_of : 'a -> list bitU
- val of_bits : list bitU -> 'a
- (* The first parameter specifies the desired length of the bitvector *)
- val of_int : integer -> integer -> 'a
+ (* We allow of_bits to be partial, as not all bitvector representations
+ support undefined bits *)
+ val of_bits : list bitU -> maybe 'a
+ val of_bools : list bool -> 'a
val length : 'a -> integer
- val unsigned : 'a -> integer
- val signed : 'a -> integer
- (* The first parameter specifies the indexing order (true is increasing) *)
- val get_bit : bool -> 'a -> integer -> bitU
- val set_bit : bool -> 'a -> integer -> bitU -> 'a
- val get_bits : bool -> 'a -> integer -> integer -> list bitU
- val set_bits : bool -> 'a -> integer -> integer -> list bitU -> 'a
+ (* of_int: the first parameter specifies the desired length of the bitvector *)
+ val of_int : integer -> integer -> 'a
+ (* Conversion to integers is undefined if any bit is undefined *)
+ val unsigned : 'a -> maybe integer
+ val signed : 'a -> maybe integer
+ (* Lifting of integer operations to bitvectors: The boolean flag indicates
+ whether to treat the bitvectors as signed (true) or not (false). *)
+ val arith_op_bv : (integer -> integer -> integer) -> bool -> 'a -> 'a -> 'a
end
+val of_bits_failwith : forall 'a. Bitvector 'a => list bitU -> 'a
+let of_bits_failwith bits = maybe_failwith (of_bits bits)
+
+let int_of_bv sign = if sign then signed else unsigned
+
instance forall 'a. BitU 'a => (Bitvector (list 'a))
let bits_of v = List.map to_bitU v
- let of_bits v = List.map of_bitU v
+ let of_bits v = Just (List.map of_bitU v)
+ let of_bools v = List.map of_bitU (List.map bitU_of_bool v)
let of_int len n = List.map of_bitU (bits_of_int len n)
let length = length_list
let unsigned v = unsigned_of_bits (List.map to_bitU v)
let signed v = signed_of_bits (List.map to_bitU v)
- let get_bit is_inc v n = to_bitU (access_list is_inc v n)
- let set_bit is_inc v n b = update_list is_inc v n (of_bitU b)
- let get_bits is_inc v i j = List.map to_bitU (subrange_list is_inc v i j)
- let set_bits is_inc v i j v' = update_subrange_list is_inc v i j (List.map of_bitU v')
+ let arith_op_bv op sign l r = List.map of_bitU (arith_op_bits op sign (List.map to_bitU l) (List.map to_bitU r))
end
instance forall 'a. Size 'a => (Bitvector (mword 'a))
- let bits_of v = List.map to_bitU (bitlistFromWord v)
- let of_bits v = wordFromBitlist (List.map of_bitU v)
- let of_int = mword_of_int
+ let bits_of v = List.map bitU_of_bool (bitlistFromWord v)
+ let of_bits v = Maybe.map wordFromBitlist (just_list (List.map bool_of_bitU v))
+ let of_bools v = wordFromBitlist v
+ let of_int = (fun _ n -> wordFromInteger n)
let length v = integerFromNat (word_length v)
- let unsigned = unsignedIntegerFromWord
- let signed = signedIntegerFromWord
- let get_bit = access_mword
- let set_bit = update_mword
- let get_bits is_inc v i j = get_bits is_inc (bitlistFromWord v) i j
- let set_bits is_inc v i j v' = wordFromBitlist (set_bits is_inc (bitlistFromWord v) i j v')
+ let unsigned v = Just (unsignedIntegerFromWord v)
+ let signed v = Just (signedIntegerFromWord v)
+ let arith_op_bv op sign l r = wordFromInteger (op (int_of_mword sign l) (int_of_mword sign r))
end
-let access_bv_inc v n = get_bit true v n
-let access_bv_dec v n = get_bit false v n
+let access_bv_inc v n = access_list true (bits_of v) n
+let access_bv_dec v n = access_list false (bits_of v) n
-let update_bv_inc v n b = set_bit true v n b
-let update_bv_dec v n b = set_bit false v n b
+let update_bv_inc v n b = update_list true (bits_of v) n b
+let update_bv_dec v n b = update_list false (bits_of v) n b
-let subrange_bv_inc v i j = of_bits (get_bits true v i j)
-let subrange_bv_dec v i j = of_bits (get_bits false v i j)
+let subrange_bv_inc v i j = subrange_list true (bits_of v) i j
+let subrange_bv_dec v i j = subrange_list false (bits_of v) i j
-let update_subrange_bv_inc v i j v' = set_bits true v i j (bits_of v')
-let update_subrange_bv_dec v i j v' = set_bits false v i j (bits_of v')
+let update_subrange_bv_inc v i j v' = update_subrange_list true (bits_of v) i j (bits_of v')
+let update_subrange_bv_dec v i j v' = update_subrange_list false (bits_of v) i j (bits_of v')
-val extz_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b => integer -> 'a -> 'b
-let extz_bv n v = of_bits (extz_bits n (bits_of v))
+val extz_bv : forall 'a. Bitvector 'a => integer -> 'a -> list bitU
+let extz_bv n v = extz_bits n (bits_of v)
-val exts_bv : forall 'a 'b. Bitvector 'a, Bitvector 'b => integer -> 'a -> 'b
-let exts_bv n v = of_bits (exts_bits n (bits_of v))
+val exts_bv : forall 'a. Bitvector 'a => integer -> 'a -> list bitU
+let exts_bv n v = exts_bits n (bits_of v)
val string_of_bv : forall 'a. Bitvector 'a => 'a -> string
let string_of_bv v = show_bitlist (bits_of v)
@@ -543,8 +611,8 @@ declare {isabelle} termination_argument byte_chunks = automatic
val bytes_of_bits : forall 'a. Bitvector 'a => 'a -> maybe (list memory_byte)
let bytes_of_bits bs = byte_chunks (bits_of bs)
-val bits_of_bytes : forall 'a. Bitvector 'a => list memory_byte -> 'a
-let bits_of_bytes bs = of_bits (List.concat (List.map bits_of bs))
+val bits_of_bytes : forall 'a. Bitvector 'a => list memory_byte -> list bitU
+let bits_of_bytes bs = List.concat (List.map bits_of bs)
let mem_bytes_of_bits bs = Maybe.map List.reverse (bytes_of_bits bs)
let bits_of_mem_bytes bs = bits_of_bytes (List.reverse bs)
@@ -596,9 +664,6 @@ let rec reverse_endianness_list bits =
if List.length bits <= 8 then bits else
reverse_endianness_list (drop_list 8 bits) ++ take_list 8 bits
-val reverse_endianness : forall 'a. Bitvector 'a => 'a -> 'a
-let reverse_endianness v = of_bits (reverse_endianness_list (bits_of v))
-
(*** Registers *)
@@ -760,10 +825,10 @@ let internal_mem_value bytes =
val foreach : forall 'a 'vars.
(list 'a) -> 'vars -> ('a -> 'vars -> 'vars) -> 'vars
let rec foreach l vars body =
-match l with
-| [] -> vars
-| (x :: xs) -> foreach xs (body x vars) body
-end
+ match l with
+ | [] -> vars
+ | (x :: xs) -> foreach xs (body x vars) body
+ end
declare {isabelle} termination_argument foreach = automatic
@@ -783,13 +848,6 @@ let rec until vars cond body =
if cond vars then vars else until (body vars) cond body
-let assert' b msg_opt =
- let msg = match msg_opt with
- | Just msg -> msg
- | Nothing -> "unspecified error"
- end in
- if b then () else failwith msg
-
(* convert numbers unsafely to naturals *)
class (ToNatural 'a) val toNatural : 'a -> natural end
diff --git a/src/gen_lib/state_monad.lem b/src/gen_lib/state_monad.lem
index 9fcbd5ce..8253b800 100644
--- a/src/gen_lib/state_monad.lem
+++ b/src/gen_lib/state_monad.lem
@@ -120,14 +120,21 @@ let try_catchSR m h =
| Right e -> h e
end)
+val maybe_failS : forall 'regs 'a 'e. string -> maybe 'a -> monadS 'regs 'a 'e
+let maybe_failS msg = function
+ | Just a -> returnS a
+ | Nothing -> failS msg
+end
+
val read_tagS : forall 'regs 'a 'e. Bitvector 'a => 'a -> monadS 'regs bitU 'e
let read_tagS addr =
- readS (fun s -> fromMaybe B0 (Map.lookup (unsigned addr) s.tagstate))
+ maybe_failS "unsigned" (unsigned addr) >>$= (fun addr ->
+ readS (fun s -> fromMaybe B0 (Map.lookup addr s.tagstate)))
(* Read bytes from memory and return in little endian order *)
val read_mem_bytesS : forall 'regs 'e 'a. Bitvector 'a => read_kind -> 'a -> nat -> monadS 'regs (list memory_byte) 'e
let read_mem_bytesS read_kind addr sz =
- let addr = unsigned addr in
+ maybe_failS "unsigned" (unsigned addr) >>$= (fun addr ->
let sz = integerFromNat sz in
let addrs = index_list addr (addr+sz-1) 1 in
let read_byte s addr = Map.lookup addr s.memstate in
@@ -139,12 +146,12 @@ let read_mem_bytesS read_kind addr sz =
else s) >>$
returnS mem_val
| Nothing -> failS "read_memS"
- end)
+ end))
val read_memS : forall 'regs 'e 'a 'b. Bitvector 'a, Bitvector 'b => read_kind -> 'a -> integer -> monadS 'regs 'b 'e
let read_memS rk a sz =
- read_mem_bytesS rk a (natFromInteger sz) >>$= (fun bytes ->
- returnS (bits_of_mem_bytes bytes))
+ read_mem_bytesS rk a (nat_of_int sz) >>$= (fun bytes ->
+ maybe_failS "bits_of_mem_bytes" (of_bits (bits_of_mem_bytes bytes)))
val excl_resultS : forall 'regs 'e. unit -> monadS 'regs bool 'e
let excl_resultS () =
@@ -154,9 +161,9 @@ let excl_resultS () =
val write_mem_eaS : forall 'regs 'e 'a. Bitvector 'a => write_kind -> 'a -> nat -> monadS 'regs unit 'e
let write_mem_eaS write_kind addr sz =
- let addr = unsigned addr in
+ maybe_failS "unsigned" (unsigned addr) >>$= (fun addr ->
let sz = integerFromNat sz in
- updateS (fun s -> <| s with write_ea = Just (write_kind, addr, sz) |>)
+ updateS (fun s -> <| s with write_ea = Just (write_kind, addr, sz) |>))
(* Write little-endian list of bytes to previously announced address *)
val write_mem_bytesS : forall 'regs 'e. list memory_byte -> monadS 'regs bool 'e
@@ -181,9 +188,9 @@ end
val write_tagS : forall 'regs 'a 'e. Bitvector 'a => 'a -> bitU -> monadS 'regs bool 'e
let write_tagS addr t =
- (*let taddr = addr / cap_alignment in*)
- updateS (fun s -> <| s with tagstate = Map.insert (unsigned addr) t s.tagstate |>) >>$
- returnS true
+ maybe_failS "unsigned" (unsigned addr) >>$= (fun addr ->
+ updateS (fun s -> <| s with tagstate = Map.insert addr t s.tagstate |>) >>$
+ returnS true)
val read_regS : forall 'regs 'rv 'a 'e. register_ref 'regs 'rv 'a -> monadS 'regs 'a 'e
let read_regS reg = readS (fun s -> reg.read_from s.regstate)