(** Theorems on arithmetic operations. *)

(* Specifications: *)
Theorem cast8unsigned_and:
forall x, zero_ext 8 x = and x (Vint(Int.repr 255)).
Theorem cast16unsigned_and:
forall x, zero_ext 16 x = and x (Vint(Int.repr 65535)).
Theorem bool_of_val_of_bool:
forall b1 b2, bool_of_val (of_bool b1) b2 -> b1 = b2.
Theorem bool_of_val_of_optbool:
forall ob b, bool_of_val (of_optbool ob) b -> ob = Some b.
Theorem notbool_negb_1:
forall b, of_bool (negb b) = notbool (of_bool b).
Theorem notbool_negb_2:
forall b, of_bool b = notbool (of_bool (negb b)).
Theorem notbool_negb_3:
forall ob, of_optbool (option_map negb ob) = notbool (of_optbool ob).
Theorem notbool_idem2:
forall b, notbool(notbool(of_bool b)) = of_bool b.
Theorem notbool_idem3:
forall x, notbool(notbool(notbool x)) = notbool x.
Theorem notbool_idem4:
forall ob, notbool (notbool (of_optbool ob)) = of_optbool ob.
Theorem add_commut: forall x y, add x y = add y x.
Theorem add_assoc: forall x y z, add (add x y) z = add x (add y z).
Theorem add_permut: forall x y z, add x (add y z) = add y (add x z).
Theorem add_permut_4:
forall x y z t, add (add x y) (add z t) = add (add x z) (add y t).
Theorem neg_zero: neg Vzero = Vzero.
Theorem neg_add_distr: forall x y, neg(add x y) = add (neg x) (neg y).
Theorem sub_zero_r: forall x, sub Vzero x = neg x.
Theorem sub_add_opp: forall x y, sub x (Vint y) = add x (Vint (Int.neg y)).
Theorem sub_opp_add: forall x y, sub x (Vint (Int.neg y)) = add x (Vint y).
Theorem sub_add_l:
forall v1 v2 i, sub (add v1 (Vint i)) v2 = add (sub v1 v2) (Vint i).
Theorem sub_add_r:
forall v1 v2 i, sub v1 (add v2 (Vint i)) = add (sub v1 v2) (Vint (Int.neg i)).
Theorem mul_commut: forall x y, mul x y = mul y x.
Theorem mul_assoc: forall x y z, mul (mul x y) z = mul x (mul y z).
Theorem mul_add_distr_l:
forall x y z, mul (add x y) z = add (mul x z) (mul y z).
Theorem mul_add_distr_r:
forall x y z, mul x (add y z) = add (mul x y) (mul x z).
Theorem mul_pow2:
forall x n logn,
Int.is_power2 n = Some logn ->
mul x (Vint n) = shl x (Vint logn).
Theorem mods_divs:
forall x y z,
mods x y = Some z -> exists v, divs x y = Some v /\ z = sub x (mul v y).
Theorem modu_divu:
forall x y z,
modu x y = Some z -> exists v, divu x y = Some v /\ z = sub x (mul v y).
Theorem modls_divls:
forall x y z,
modls x y = Some z -> exists v, divls x y = Some v /\ z = subl x (mull v y).
Theorem modlu_divlu:
forall x y z,
modlu x y = Some z -> exists v, divlu x y = Some v /\ z = subl x (mull v y).
Theorem divs_pow2:
forall x n logn y,
Int.is_power2 n = Some logn -> Int.ltu logn (Int.repr 31) = true ->
divs x (Vint n) = Some y ->
shrx x (Vint logn) = Some y.
Theorem divs_one:
forall s , divs (Vint s) (Vint Int.one) = Some (Vint s).
Theorem divu_pow2:
forall x n logn y,
Int.is_power2 n = Some logn ->
divu x (Vint n) = Some y ->
shru x (Vint logn) = y.
Theorem divu_one:
forall s, divu (Vint s) (Vint Int.one) = Some (Vint s).
Theorem modu_pow2:
forall x n logn y,
Int.is_power2 n = Some logn ->
modu x (Vint n) = Some y ->
and x (Vint (Int.sub n Int.one)) = y.
Theorem and_commut: forall x y, and x y = and y x.
Theorem and_assoc: forall x y z, and (and x y) z = and x (and y z).
Theorem or_commut: forall x y, or x y = or y x.
Theorem or_assoc: forall x y z, or (or x y) z = or x (or y z).
Theorem xor_commut: forall x y, xor x y = xor y x.
Theorem xor_assoc: forall x y z, xor (xor x y) z = xor x (xor y z).
Theorem not_xor: forall x, notint x = xor x (Vint Int.mone).
Theorem shl_mul: forall x y, mul x (shl Vone y) = shl x y.
Theorem shl_rolm:
forall x n,
Int.ltu n Int.iwordsize = true ->
shl x (Vint n) = rolm x n (Int.shl Int.mone n).
Theorem shll_rolml:
forall x n,
Int.ltu n Int64.iwordsize' = true ->
shll x (Vint n) = rolml x n (Int64.shl Int64.mone (Int64.repr (Int.unsigned n))).
Theorem shru_rolm:
forall x n,
Int.ltu n Int.iwordsize = true ->
shru x (Vint n) = rolm x (Int.sub Int.iwordsize n) (Int.shru Int.mone n).
Theorem shrlu_rolml:
forall x n,
Int.ltu n Int64.iwordsize' = true ->
shrlu x (Vint n) = rolml x (Int.sub Int64.iwordsize' n) (Int64.shru Int64.mone (Int64.repr (Int.unsigned n))).
Theorem shrx_carry:
forall x y z,
shrx x y = Some z ->
add (shr x y) (shr_carry x y) = z.
Theorem shrx_shr:
forall x y z,
shrx x y = Some z ->
exists p, exists q,
x = Vint p /\ y = Vint q /\
z = shr (if Int.lt p Int.zero then add x (Vint (Int.sub (Int.shl Int.one q) Int.one)) else x) (Vint q).
Theorem shrx_shr_2:
forall n x z,
shrx x (Vint n) = Some z ->
z = (if Int.eq n Int.zero then x else
shr (add x (shru (shr x (Vint (Int.repr 31)))
(Vint (Int.sub (Int.repr 32) n))))
(Vint n)).
Theorem or_rolm:
forall x n m1 m2,
or (rolm x n m1) (rolm x n m2) = rolm x n (Int.or m1 m2).
Theorem rolm_rolm:
forall x n1 m1 n2 m2,
rolm (rolm x n1 m1) n2 m2 =
rolm x (Int.modu (Int.add n1 n2) Int.iwordsize)
(Int.and (Int.rol m1 n2) m2).
Theorem rolm_zero:
forall x m,
rolm x Int.zero m = and x (Vint m).
Theorem addl_commut: forall x y, addl x y = addl y x.
Theorem addl_assoc: forall x y z, addl (addl x y) z = addl x (addl y z).
Theorem addl_permut: forall x y z, addl x (addl y z) = addl y (addl x z).
Theorem addl_permut_4:
forall x y z t, addl (addl x y) (addl z t) = addl (addl x z) (addl y t).
Theorem negl_addl_distr: forall x y, negl(addl x y) = addl (negl x) (negl y).
Theorem subl_addl_opp: forall x y, subl x (Vlong y) = addl x (Vlong (Int64.neg y)).
Theorem subl_opp_addl: forall x y, subl x (Vlong (Int64.neg y)) = addl x (Vlong y).
Theorem subl_addl_l:
forall v1 v2 i, subl (addl v1 (Vlong i)) v2 = addl (subl v1 v2) (Vlong i).
Theorem subl_addl_r:
forall v1 v2 i, subl v1 (addl v2 (Vlong i)) = addl (subl v1 v2) (Vlong (Int64.neg i)).
Theorem mull_commut: forall x y, mull x y = mull y x.
Theorem mull_assoc: forall x y z, mull (mull x y) z = mull x (mull y z).
Theorem mull_addl_distr_l:
forall x y z, mull (addl x y) z = addl (mull x z) (mull y z).
Theorem mull_addl_distr_r:
forall x y z, mull x (addl y z) = addl (mull x y) (mull x z).
Theorem andl_commut: forall x y, andl x y = andl y x.
Theorem andl_assoc: forall x y z, andl (andl x y) z = andl x (andl y z).
Theorem orl_commut: forall x y, orl x y = orl y x.
Theorem orl_assoc: forall x y z, orl (orl x y) z = orl x (orl y z).
Theorem xorl_commut: forall x y, xorl x y = xorl y x.
Theorem xorl_assoc: forall x y z, xorl (xorl x y) z = xorl x (xorl y z).
Theorem notl_xorl: forall x, notl x = xorl x (Vlong Int64.mone).
Theorem divls_pow2:
forall x n logn y,
Int64.is_power2' n = Some logn -> Int.ltu logn (Int.repr 63) = true ->
divls x (Vlong n) = Some y ->
shrxl x (Vint logn) = Some y.
Theorem divls_one:
forall n, divls (Vlong n) (Vlong Int64.one) = Some (Vlong n).
Theorem divlu_pow2:
forall x n logn y,
Int64.is_power2' n = Some logn ->
divlu x (Vlong n) = Some y ->
shrlu x (Vint logn) = y.
Theorem divlu_one:
forall n, divlu (Vlong n) (Vlong Int64.one) = Some (Vlong n).
Theorem modlu_pow2:
forall x n logn y,
Int64.is_power2 n = Some logn ->
modlu x (Vlong n) = Some y ->
andl x (Vlong (Int64.sub n Int64.one)) = y.
Theorem shrxl_carry:
forall x y z,
shrxl x y = Some z ->
addl (shrl x y) (shrl_carry x y) = z.
Theorem shrxl_shrl_2:
forall n x z,
shrxl x (Vint n) = Some z ->
z = (if Int.eq n Int.zero then x else
shrl (addl x (shrlu (shrl x (Vint (Int.repr 63)))
(Vint (Int.sub (Int.repr 64) n))))
(Vint n)).
Theorem negate_cmp_bool:
forall c x y, cmp_bool (negate_comparison c) x y = option_map negb (cmp_bool c x y).
Theorem negate_cmpu_bool:
forall valid_ptr c x y,
cmpu_bool valid_ptr (negate_comparison c) x y = option_map negb (cmpu_bool valid_ptr c x y).
Theorem negate_cmpl_bool:
forall c x y, cmpl_bool (negate_comparison c) x y = option_map negb (cmpl_bool c x y).
Theorem negate_cmplu_bool:
forall valid_ptr c x y,
cmplu_bool valid_ptr (negate_comparison c) x y = option_map negb (cmplu_bool valid_ptr c x y).
Lemma not_of_optbool:
forall ob, of_optbool (option_map negb ob) = notbool (of_optbool ob).
Theorem negate_cmp:
forall c x y,
cmp (negate_comparison c) x y = notbool (cmp c x y).
Theorem negate_cmpu:
forall valid_ptr c x y,
cmpu valid_ptr (negate_comparison c) x y =
notbool (cmpu valid_ptr c x y).
Theorem swap_cmp_bool:
forall c x y,
cmp_bool (swap_comparison c) x y = cmp_bool c y x.
Theorem swap_cmpu_bool:
forall valid_ptr c x y,
cmpu_bool valid_ptr (swap_comparison c) x y =
cmpu_bool valid_ptr c y x.
Theorem swap_cmpl_bool:
forall c x y,
cmpl_bool (swap_comparison c) x y = cmpl_bool c y x.
Theorem swap_cmplu_bool:
forall valid_ptr c x y,
cmplu_bool valid_ptr (swap_comparison c) x y = cmplu_bool valid_ptr c y x.
Theorem negate_cmpf_eq:
forall v1 v2, notbool (cmpf Cne v1 v2) = cmpf Ceq v1 v2.
Theorem negate_cmpf_ne:
forall v1 v2, notbool (cmpf Ceq v1 v2) = cmpf Cne v1 v2.
Theorem cmpf_le:
forall v1 v2, cmpf Cle v1 v2 = or (cmpf Clt v1 v2) (cmpf Ceq v1 v2).
Theorem cmpf_ge:
forall v1 v2, cmpf Cge v1 v2 = or (cmpf Cgt v1 v2) (cmpf Ceq v1 v2).
Theorem cmp_ne_0_optbool:
forall ob, cmp Cne (of_optbool ob) (Vint Int.zero) = of_optbool ob.
Theorem cmp_eq_1_optbool:
forall ob, cmp Ceq (of_optbool ob) (Vint Int.one) = of_optbool ob.
Theorem cmp_eq_0_optbool:
forall ob, cmp Ceq (of_optbool ob) (Vint Int.zero) = of_optbool (option_map negb ob).
Theorem cmp_ne_1_optbool:
forall ob, cmp Cne (of_optbool ob) (Vint Int.one) = of_optbool (option_map negb ob).
Theorem cmpu_ne_0_optbool:
forall valid_ptr ob,
cmpu valid_ptr Cne (of_optbool ob) (Vint Int.zero) = of_optbool ob.
Theorem cmpu_eq_1_optbool:
forall valid_ptr ob,
cmpu valid_ptr Ceq (of_optbool ob) (Vint Int.one) = of_optbool ob.
Theorem cmpu_eq_0_optbool:
forall valid_ptr ob,
cmpu valid_ptr Ceq (of_optbool ob) (Vint Int.zero) = of_optbool (option_map negb ob).
Theorem cmpu_ne_1_optbool:
forall valid_ptr ob,
cmpu valid_ptr Cne (of_optbool ob) (Vint Int.one) = of_optbool (option_map negb ob).
Lemma zero_ext_and:
forall n v,
0 < n < Int.zwordsize ->
Val.zero_ext n v = Val.and v (Vint (Int.repr (two_p n - 1))).
Lemma rolm_lt_zero:
forall v, rolm v Int.one Int.one = cmp Clt v (Vint Int.zero).
Lemma rolm_ge_zero:
forall v,
xor (rolm v Int.one Int.one) (Vint Int.one) = cmp Cge v (Vint Int.zero).