2016-04-17 16:50:42 +00:00
|
|
|
(*
|
2020-03-09 06:18:30 +00:00
|
|
|
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
2016-04-17 16:50:42 +00:00
|
|
|
*
|
2020-03-09 06:18:30 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2016-04-17 16:50:42 +00:00
|
|
|
*)
|
|
|
|
|
2021-01-15 07:10:07 +00:00
|
|
|
section "Words of Length 32"
|
|
|
|
|
|
|
|
theory Word_32
|
|
|
|
imports
|
2021-01-21 21:49:03 +00:00
|
|
|
Word_Lemmas
|
2021-01-15 07:10:07 +00:00
|
|
|
Word_Syntax
|
2021-01-21 21:49:03 +00:00
|
|
|
Word_Names
|
2021-01-15 07:10:07 +00:00
|
|
|
Rsplit
|
|
|
|
More_Word_Operations
|
|
|
|
Bitwise
|
2016-04-17 16:50:42 +00:00
|
|
|
begin
|
|
|
|
|
2021-11-14 10:05:54 +00:00
|
|
|
context
|
|
|
|
includes bit_operations_syntax
|
|
|
|
begin
|
|
|
|
|
2021-01-15 07:10:07 +00:00
|
|
|
type_synonym word32 = "32 word"
|
|
|
|
lemma len32: "len_of (x :: 32 itself) = 32" by simp
|
|
|
|
|
|
|
|
type_synonym sword32 = "32 sword"
|
|
|
|
|
2016-04-17 16:50:42 +00:00
|
|
|
lemma ucast_8_32_inj:
|
|
|
|
"inj (ucast :: 8 word \<Rightarrow> 32 word)"
|
2016-04-18 20:25:44 +00:00
|
|
|
by (rule down_ucast_inj) (clarsimp simp: is_down_def target_size source_size)
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemmas unat_power_lower32' = unat_power_lower[where 'a=32]
|
|
|
|
|
|
|
|
lemmas word32_less_sub_le' = word_less_sub_le[where 'a = 32]
|
|
|
|
|
|
|
|
lemmas word32_power_less_1' = word_power_less_1[where 'a = 32]
|
|
|
|
|
|
|
|
lemmas unat_of_nat32' = unat_of_nat_eq[where 'a=32]
|
|
|
|
|
|
|
|
lemmas unat_mask_word32' = unat_mask[where 'a=32]
|
|
|
|
|
|
|
|
lemmas word32_minus_one_le' = word_minus_one_le[where 'a=32]
|
|
|
|
lemmas word32_minus_one_le = word32_minus_one_le'[simplified]
|
|
|
|
|
|
|
|
lemma unat_ucast_8_32:
|
2021-01-21 21:49:03 +00:00
|
|
|
fixes x :: "8 word"
|
2016-04-17 16:50:42 +00:00
|
|
|
shows "unat (ucast x :: word32) = unat x"
|
2021-01-15 07:10:07 +00:00
|
|
|
by transfer simp
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemma ucast_le_ucast_8_32:
|
2021-01-21 21:49:03 +00:00
|
|
|
"(ucast x \<le> (ucast y :: word32)) = (x \<le> (y :: 8 word))"
|
2016-10-04 00:53:24 +00:00
|
|
|
by (simp add: ucast_le_ucast)
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemma eq_2_32_0:
|
|
|
|
"(2 ^ 32 :: word32) = 0"
|
|
|
|
by simp
|
|
|
|
|
2016-04-18 20:25:44 +00:00
|
|
|
lemmas mask_32_max_word = max_word_mask [symmetric, where 'a=32, simplified]
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemma of_nat32_n_less_equal_power_2:
|
|
|
|
"n < 32 \<Longrightarrow> ((of_nat n)::32 word) < 2 ^ n"
|
|
|
|
by (rule of_nat_n_less_equal_power_2, clarsimp simp: word_size)
|
|
|
|
|
|
|
|
lemma unat_ucast_10_32 :
|
|
|
|
fixes x :: "10 word"
|
|
|
|
shows "unat (ucast x :: word32) = unat x"
|
2021-01-15 07:10:07 +00:00
|
|
|
by transfer simp
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemma word32_bounds:
|
|
|
|
"- (2 ^ (size (x :: word32) - 1)) = (-2147483648 :: int)"
|
|
|
|
"((2 ^ (size (x :: word32) - 1)) - 1) = (2147483647 :: int)"
|
|
|
|
"- (2 ^ (size (y :: 32 signed word) - 1)) = (-2147483648 :: int)"
|
|
|
|
"((2 ^ (size (y :: 32 signed word) - 1)) - 1) = (2147483647 :: int)"
|
|
|
|
by (simp_all add: word_size)
|
|
|
|
|
|
|
|
lemmas signed_arith_ineq_checks_to_eq_word32'
|
|
|
|
= signed_arith_ineq_checks_to_eq[where 'a=32]
|
|
|
|
signed_arith_ineq_checks_to_eq[where 'a="32 signed"]
|
|
|
|
|
|
|
|
lemmas signed_arith_ineq_checks_to_eq_word32
|
|
|
|
= signed_arith_ineq_checks_to_eq_word32' [unfolded word32_bounds]
|
|
|
|
|
|
|
|
lemmas signed_mult_eq_checks32_to_64'
|
|
|
|
= signed_mult_eq_checks_double_size[where 'a=32 and 'b=64]
|
|
|
|
signed_mult_eq_checks_double_size[where 'a="32 signed" and 'b=64]
|
|
|
|
|
|
|
|
lemmas signed_mult_eq_checks32_to_64 = signed_mult_eq_checks32_to_64'[simplified]
|
|
|
|
|
|
|
|
lemmas sdiv_word32_max' = sdiv_word_max [where 'a=32] sdiv_word_max [where 'a="32 signed"]
|
|
|
|
lemmas sdiv_word32_max = sdiv_word32_max'[simplified word_size, simplified]
|
|
|
|
|
|
|
|
lemmas sdiv_word32_min' = sdiv_word_min [where 'a=32] sdiv_word_min [where 'a="32 signed"]
|
|
|
|
lemmas sdiv_word32_min = sdiv_word32_min' [simplified word_size, simplified]
|
|
|
|
|
|
|
|
lemmas sint32_of_int_eq' = sint_of_int_eq [where 'a=32]
|
|
|
|
lemmas sint32_of_int_eq = sint32_of_int_eq' [simplified]
|
|
|
|
|
|
|
|
lemma ucast_of_nats [simp]:
|
|
|
|
"(ucast (of_nat x :: word32) :: sword32) = (of_nat x)"
|
2021-01-21 21:49:03 +00:00
|
|
|
"(ucast (of_nat x :: word32) :: 16 sword) = (of_nat x)"
|
|
|
|
"(ucast (of_nat x :: word32) :: 8 sword) = (of_nat x)"
|
|
|
|
"(ucast (of_nat x :: 16 word) :: 16 sword) = (of_nat x)"
|
|
|
|
"(ucast (of_nat x :: 16 word) :: 8 sword) = (of_nat x)"
|
|
|
|
"(ucast (of_nat x :: 8 word) :: 8 sword) = (of_nat x)"
|
2021-11-14 10:05:54 +00:00
|
|
|
by (simp_all add: of_nat_take_bit take_bit_word_eq_self unsigned_of_nat)
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemmas signed_shift_guard_simpler_32'
|
|
|
|
= power_strict_increasing_iff[where b="2 :: nat" and y=31]
|
|
|
|
lemmas signed_shift_guard_simpler_32 = signed_shift_guard_simpler_32'[simplified]
|
|
|
|
|
|
|
|
lemma word32_31_less:
|
|
|
|
"31 < len_of TYPE (32 signed)" "31 > (0 :: nat)"
|
|
|
|
"31 < len_of TYPE (32)" "31 > (0 :: nat)"
|
|
|
|
by auto
|
|
|
|
|
|
|
|
lemmas signed_shift_guard_to_word_32
|
|
|
|
= signed_shift_guard_to_word[OF word32_31_less(1-2)]
|
|
|
|
signed_shift_guard_to_word[OF word32_31_less(3-4)]
|
|
|
|
|
|
|
|
lemma has_zero_byte:
|
|
|
|
"~~ (((((v::word32) && 0x7f7f7f7f) + 0x7f7f7f7f) || v) || 0x7f7f7f7f) \<noteq> 0
|
|
|
|
\<Longrightarrow> v && 0xff000000 = 0 \<or> v && 0xff0000 = 0 \<or> v && 0xff00 = 0 \<or> v && 0xff = 0"
|
2021-01-15 07:10:07 +00:00
|
|
|
by word_bitwise auto
|
2016-04-17 16:50:42 +00:00
|
|
|
|
2016-04-18 20:25:44 +00:00
|
|
|
lemma mask_step_down_32:
|
2021-01-15 07:10:07 +00:00
|
|
|
\<open>\<exists>x. mask x = b\<close> if \<open>b && 1 = 1\<close>
|
|
|
|
and \<open>\<exists>x. x < 32 \<and> mask x = b >> 1\<close> for b :: \<open>32word\<close>
|
|
|
|
proof -
|
|
|
|
from \<open>b && 1 = 1\<close> have \<open>odd b\<close>
|
|
|
|
by (auto simp add: mod_2_eq_odd and_one_eq)
|
|
|
|
then have \<open>b mod 2 = 1\<close>
|
|
|
|
using odd_iff_mod_2_eq_one by blast
|
|
|
|
from \<open>\<exists>x. x < 32 \<and> mask x = b >> 1\<close> obtain x where \<open>x < 32\<close> \<open>mask x = b >> 1\<close> by blast
|
|
|
|
then have \<open>mask x = b div 2\<close>
|
|
|
|
using shiftr1_is_div_2 [of b] by simp
|
|
|
|
with \<open>b mod 2 = 1\<close> have \<open>2 * mask x + 1 = 2 * (b div 2) + b mod 2\<close>
|
|
|
|
by (simp only:)
|
|
|
|
also have \<open>\<dots> = b\<close>
|
|
|
|
by (simp add: mult_div_mod_eq)
|
|
|
|
finally have \<open>2 * mask x + 1 = b\<close> .
|
|
|
|
moreover have \<open>mask (Suc x) = 2 * mask x + (1 :: 'a::len word)\<close>
|
|
|
|
by (simp add: mask_Suc_rec)
|
|
|
|
ultimately show ?thesis
|
|
|
|
by auto
|
|
|
|
qed
|
2016-04-17 16:50:42 +00:00
|
|
|
|
2016-04-18 20:25:44 +00:00
|
|
|
lemma unat_of_int_32:
|
2016-04-17 16:50:42 +00:00
|
|
|
"\<lbrakk>i \<ge> 0; i \<le>2 ^ 31\<rbrakk> \<Longrightarrow> (unat ((of_int i)::sword32)) = nat i"
|
2021-11-14 10:05:54 +00:00
|
|
|
by (simp add: unsigned_of_int nat_take_bit_eq take_bit_nat_eq_self)
|
2016-04-17 16:50:42 +00:00
|
|
|
|
2019-10-21 23:50:09 +00:00
|
|
|
lemmas word_ctz_not_minus_1_32 = word_ctz_not_minus_1[where 'a=32, simplified]
|
|
|
|
|
2016-04-17 16:50:42 +00:00
|
|
|
(* Helper for packing then unpacking a 64-bit variable. *)
|
|
|
|
lemma cast_chunk_assemble_id_64[simp]:
|
|
|
|
"(((ucast ((ucast (x::64 word))::32 word))::64 word) || (((ucast ((ucast (x >> 32))::32 word))::64 word) << 32)) = x"
|
|
|
|
by (simp add:cast_chunk_assemble_id)
|
|
|
|
|
|
|
|
(* Another variant of packing and unpacking a 64-bit variable. *)
|
|
|
|
lemma cast_chunk_assemble_id_64'[simp]:
|
|
|
|
"(((ucast ((scast (x::64 word))::32 word))::64 word) || (((ucast ((scast (x >> 32))::32 word))::64 word) << 32)) = x"
|
|
|
|
by (simp add:cast_chunk_scast_assemble_id)
|
|
|
|
|
2018-06-09 09:41:48 +00:00
|
|
|
(* Specialisations of down_cast_same for adding to local simpsets. *)
|
2016-04-17 16:50:42 +00:00
|
|
|
lemma cast_down_u64: "(scast::64 word \<Rightarrow> 32 word) = (ucast::64 word \<Rightarrow> 32 word)"
|
2021-01-21 21:49:03 +00:00
|
|
|
by (subst down_cast_same[symmetric]; simp add:is_down)+
|
2016-04-17 16:50:42 +00:00
|
|
|
|
|
|
|
lemma cast_down_s64: "(scast::64 sword \<Rightarrow> 32 word) = (ucast::64 sword \<Rightarrow> 32 word)"
|
2021-01-21 21:49:03 +00:00
|
|
|
by (subst down_cast_same[symmetric]; simp add:is_down)
|
2016-04-17 16:50:42 +00:00
|
|
|
|
2021-01-15 07:10:07 +00:00
|
|
|
lemma word32_and_max_simp:
|
|
|
|
\<open>x AND 0xFFFFFFFF = x\<close> for x :: \<open>32 word\<close>
|
|
|
|
using word_and_full_mask_simp [of x]
|
|
|
|
by (simp add: numeral_eq_Suc mask_Suc_exp)
|
|
|
|
|
2016-04-17 16:50:42 +00:00
|
|
|
end
|
2021-11-14 10:05:54 +00:00
|
|
|
|
|
|
|
end
|