open import Pervasives_extra open import Machine_word 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 cons_bv : forall 'a 'b 'c. Bitvector 'a, Bitvector 'b => bitU -> 'a -> 'b let cons_bv b v = of_bits (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 let most_significant v = match bits_of v with | b :: _ -> b | _ -> failwith "most_significant applied to empty vector" end let get_max_representable_in sign (n : integer) : integer = if (n = 64) then match sign with | true -> max_64 | false -> max_64u end else if (n=32) then match sign with | true -> max_32 | false -> max_32u end else if (n=8) then max_8 else if (n=5) then max_5 else match sign with | true -> integerPow 2 ((natFromInteger n) -1) | false -> integerPow 2 (natFromInteger n) end let get_min_representable_in _ (n : integer) : integer = if n = 64 then min_64 else if n = 32 then min_32 else if n = 8 then min_8 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 addS_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 multS_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 addS_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 multS_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 addS_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 multS_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 addS_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) 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) let add_overflow_bv = arith_op_overflow_bv integerAdd false 1 let add_overflow_bv_signed = 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 mult_overflow_bv = arith_op_overflow_bv integerMult false 2 let mult_overflow_bv_signed = 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) 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) 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 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 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 shift_op_bv op v n = match op with | LL_shift -> of_bits (get_bits 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)) | RR_shift_arith -> of_bits (repeat [most_significant v] n ++ get_bits 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)) | RR_rot -> of_bits (get_bits false v 0 (n - 1) ++ get_bits false v n (length v - 1)) end let shiftl_bv = shift_op_bv LL_shift (*"<<"*) let shiftr_bv = shift_op_bv RR_shift (*">>"*) 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 rec arith_op_no0 (op : integer -> integer -> integer) l r = if r = 0 then Nothing 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 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)) 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 mod_mword = Machine_word.modulo let quot_mword = Machine_word.unsignedDivide let quot_mword_signed = 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) 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 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) 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 (>=)