Require Import Coqlib.
Require Import Axioms.
Require Import Integers.
Require Import Floats.
Require Import Psatz.
Lemma nat_ge_le:
forall n m,
(
m >=
n)%
nat ->
(
n <=
m)%
nat.
Proof.
intros; lia.
Qed.
Ltac assert_val val :=
match goal with
|-
context [
if ?
a then _ else _] =>
let x:=
fresh in assert (
x:
a=
val);[|
rewrite x in *;
clear x]
end.
Ltac destr_no_dep :=
destr;
repeat match goal with
H:
_ =
left _ |-
_ =>
clear H
|
H:
_ =
right _ |-
_ =>
clear H
end.
Lemma shl_zero_l:
forall i,
Int.shl Int.zero i =
Int.zero.
Proof.
Ltac solve_int :=
repeat
match goal with
| |-
context [
Int.shl _ (
Int.repr 0)] =>
rewrite Int.shl_zero
| |-
context [
Int.shl Int.zero _] =>
rewrite shl_zero_l
| |-
context [
Int.add Int.zero _] =>
rewrite Int.add_zero_l
| |-
context [
Int.shru (
Int.shl ?
i (
Int.repr ?
n)) (
Int.repr ?
n)] =>
change n with (
Int.zwordsize - (
Int.zwordsize -
n));
rewrite <-
Int.zero_ext_shru_shl by (
unfold Int.zwordsize;
simpl;
lia)
| |-
context [
Int.shru (
Int.shl ?
i (
Int.repr ?
n)) (
Int.repr ?
m)] =>
change (
Int.shru (
Int.shl i (
Int.repr n)) (
Int.repr m))
with
(
Int.shru (
Int.shl i (
Int.repr (
Int.zwordsize - (
Int.zwordsize -
n)))) (
Int.add (
Int.repr n) (
Int.sub (
Int.repr m) (
Int.repr n))));
rewrite <-
Int.shru_shru by (
vm_compute;
auto);
rewrite <-
Int.zero_ext_shru_shl by (
unfold Int.zwordsize;
simpl;
lia)
| |-
context [
Int.sub (
Int.repr ?
i) (
Int.repr ?
j)] =>
change (
Int.sub (
Int.repr i) (
Int.repr j))
with (
Int.repr (
i -
j));
simpl
| |-
context [
Int.add (
Int.repr ?
i) (
Int.repr ?
j)] =>
change (
Int.add (
Int.repr i) (
Int.repr j))
with (
Int.repr (
i +
j));
simpl
| |-
context [
Int.testbit (
Int.add _ _)
_] =>
rewrite Int.add_is_or;
simpl;
auto;
try lia
| |-
context [
Int.testbit (
Int.and _ _)
_] =>
rewrite Int.bits_and;
simpl;
auto
| |-
context [
Int.testbit (
Int.or _ _)
_] =>
rewrite Int.bits_or;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int.testbit (
Int.shl _ _)
_] =>
rewrite Int.bits_shl;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int.testbit (
Int.shru _ _)
_] =>
rewrite Int.bits_shru;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int.testbit (
Int.zero_ext _ _)
_] =>
rewrite Int.bits_zero_ext;
simpl
| |-
context [
Int.testbit (
Int.sign_ext _ _)
_] =>
f_equal;
apply Int.sign_ext_equal_if_zero_equal;
try lia
|
H:
context[
Int.unsigned (
Int.repr _)]|-
_ =>
rewrite Int.unsigned_repr in H by (
unfold Int.max_unsigned;
simpl;
lia)
| |-
context[
Int.unsigned (
Int.repr _)] =>
rewrite Int.unsigned_repr by (
unfold Int.max_unsigned;
simpl;
lia)
| |-
context [
_ ||
false] =>
rewrite orb_false_r
| |-
context [
_ &&
false] =>
rewrite andb_false_r
| |-
context [
Int.testbit Int.zero ?
i] =>
rewrite Int.bits_zero
| |-
context [?
n - ?
i + ?
i] =>
replace (
n -
i +
i)
with n by (
rewrite Z.sub_simpl_r;
auto)
| |-
Int.testbit ?
e ?
i =
Int.testbit ?
e ?
j =>
f_equal;
lia
| |- @
eq int _ _ =>
apply Int.same_bits_eq;
simpl;
intros
| |-
_ =>
destr;
repeat match goal with
|
H:
_ =
left _ |-
_ =>
clear H
|
H:
_ =
right _ |-
_ =>
clear H
end;
try lia
| |-
_ =>
progress simpl
end.
Lemma shl_zero_r_64:
forall i,
Int64.shl'
i (
Int.repr 0) =
i.
Proof.
Lemma shl_zero_l_64:
forall i,
Int64.shl'
Int64.zero i =
Int64.zero.
Proof.
Lemma shru'
_shru:
forall l i,
0 <=
Int.unsigned i <= 64 ->
Int64.shru'
l i =
Int64.shru l (
Int64.repr (
Int.unsigned i)).
Proof.
Lemma shl'
_shl:
forall l i,
0 <=
Int.unsigned i <= 64 ->
Int64.shl'
l i =
Int64.shl l (
Int64.repr (
Int.unsigned i)).
Proof.
Ltac solve_long :=
repeat
match goal with
| |-
context [
Int64.shl'
_ (
Int.repr 0)] =>
rewrite shl_zero_r_64
| |-
context [
Int64.shl'
Int64.zero _] =>
rewrite shl_zero_l_64
| |-
context [
Int64.add Int64.zero _] =>
rewrite Int64.add_zero_l
| |-
context [
Int64.mul Int64.zero _] =>
rewrite Int64.mul_commut;
rewrite Int64.mul_zero
| |-
context [
Int64.shru (
Int64.shl ?
i (
Int64.repr ?
n)) (
Int64.repr ?
n)] =>
change n with (
Int64.zwordsize - (
Int64.zwordsize -
n));
rewrite <-
Int64.zero_ext_shru_shl by (
unfold Int64.zwordsize;
simpl;
lia)
| |-
context [
Int64.shru (
Int64.shl ?
i (
Int64.repr ?
n)) (
Int64.repr ?
m)] =>
change (
Int64.shru (
Int64.shl i (
Int64.repr n)) (
Int64.repr m))
with
(
Int64.shru (
Int64.shl i (
Int64.repr (
Int64.zwordsize - (
Int64.zwordsize -
n)))) (
Int64.add (
Int64.repr n) (
Int64.sub (
Int64.repr m) (
Int64.repr n))));
rewrite <-
Int64.shru_shru by (
vm_compute;
auto);
rewrite <-
Int64.zero_ext_shru_shl by (
unfold Int64.zwordsize;
simpl;
lia)
| |-
context [
Int64.sub (
Int64.repr ?
i) (
Int64.repr ?
j)] =>
change (
Int64.sub (
Int64.repr i) (
Int64.repr j))
with (
Int64.repr (
i -
j));
simpl
| |-
context [
Int64.add (
Int64.repr ?
i) (
Int64.repr ?
j)] =>
change (
Int64.add (
Int64.repr i) (
Int64.repr j))
with (
Int64.repr (
i +
j));
simpl
| |-
context [
Int64.testbit (
Int64.and _ _)
_] =>
rewrite Int64.bits_and;
simpl;
auto
| |-
context [
Int64.testbit (
Int64.or _ _)
_] =>
rewrite Int64.bits_or;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int64.testbit (
Int64.shl _ _)
_] =>
rewrite Int64.bits_shl;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int64.testbit (
Int64.shru _ _)
_] =>
rewrite Int64.bits_shru;
simpl;
auto;
try lia; [
idtac]
| |-
context [
Int64.testbit (
Int64.zero_ext _ _)
_] =>
rewrite Int64.bits_zero_ext;
simpl
| |-
context [
Int64.testbit (
Int64.sign_ext _ _)
_] =>
f_equal;
apply Int64.sign_ext_equal_if_zero_equal;
try lia; [
idtac]
|
H:
context[
Int64.unsigned (
Int64.repr _)]|-
_ =>
rewrite Int64.unsigned_repr in H by (
unfold Int64.max_unsigned;
simpl;
lia)
| |-
context[
Int64.unsigned (
Int64.repr _)] =>
rewrite Int64.unsigned_repr by (
unfold Int64.max_unsigned;
simpl;
lia)
|
H:
context[
Int.unsigned (
Int.repr _)]|-
_ =>
rewrite Int.unsigned_repr in H by (
unfold Int.max_unsigned;
simpl;
lia)
| |-
context[
Int.unsigned (
Int.repr _)] =>
rewrite Int.unsigned_repr by (
unfold Int.max_unsigned;
simpl;
lia)
| |-
context [
_ ||
false] =>
rewrite orb_false_r
| |-
context [
_ &&
false] =>
rewrite andb_false_r
| |-
context [
Int64.testbit Int64.zero ?
i] =>
rewrite Int64.bits_zero
| |-
context [?
n - ?
i + ?
i] =>
replace (
n -
i +
i)
with n by (
rewrite Z.sub_simpl_r;
auto)
| |-
Int64.testbit ?
e ?
i =
Int64.testbit ?
e ?
j =>
f_equal;
lia
| |- @
eq int64 _ _ =>
apply Int64.same_bits_eq;
simpl;
intros
| |-
_ =>
destr;
repeat match goal with
|
H:
_ =
left _ |-
_ =>
clear H
|
H:
_ =
right _ |-
_ =>
clear H
end;
try lia
| |-
_ =>
progress simpl
end.
Lemma Forall_rev:
forall A P (
l:
list A),
Forall P (
rev l) ->
Forall P l.
Proof.
Lemma int_zwordsize:
Int.zwordsize = 32.
Proof.
reflexivity.
Qed.
Lemma int64_zwordsize:
Int64.zwordsize = 64.
Proof.
reflexivity.
Qed.
Lemma list_forall2_sym:
forall {
A} (
P:
A ->
A ->
Prop)
(
Psym:
forall a b,
P a b ->
P b a)
la lb,
list_forall2 P la lb ->
list_forall2 P lb la.
Proof.
intros.
induction H.
constructor.
constructor; auto.
Qed.
Lemma list_forall2_rev:
forall {
A} (
P:
A ->
A ->
Prop) (
l l':
list A),
list_forall2 P l l' ->
list_forall2 P (
rev l) (
rev l').
Proof.
induction l;
intros.
-
inv H.
simpl;
constructor.
-
simpl.
inv H.
apply IHl in H4.
simpl.
apply list_forall2_app;
auto.
constructor;
auto.
constructor.
Qed.
Lemma bits_255_below:
forall i0, 0 <=
i0 < 8 ->
Int.testbit (
Int.repr 255)
i0 =
true.
Proof.
Lemma bits_255_above:
forall i0, 8 <=
i0 <
Int.zwordsize ->
Int.testbit (
Int.repr 255)
i0 =
false.
Proof.
Lemma bits64_255_below:
forall i0, 0 <=
i0 < 8 ->
Int64.testbit (
Int64.repr 255)
i0 =
true.
Proof.
Lemma bits64_255_above:
forall i0, 8 <=
i0 <
Int64.zwordsize ->
Int64.testbit (
Int64.repr 255)
i0 =
false.
Proof.
Lemma sign_ext_8_id:
forall i0,
(
Int.sign_ext 8
(
Int.add (
Int.and i0 (
Int.repr 255)) (
Int.shl Int.zero (
Int.repr 8)))) =
(
Int.sign_ext 8
i0).
Proof.
Lemma zero_ext_8_id:
forall i0,
(
Int.zero_ext 8
(
Int.add (
Int.and i0 (
Int.repr 255)) (
Int.shl Int.zero (
Int.repr 8)))) =
(
Int.zero_ext 8
i0).
Proof.
Lemma sign_ext_16_id:
forall i0,
(
Int.sign_ext 16
(
Int.add (
Int.and i0 (
Int.repr 255))
(
Int.shl
(
Int.add (
Int.and (
Int.shru i0 (
Int.repr 8)) (
Int.repr 255))
(
Int.shl Int.zero (
Int.repr 8))) (
Int.repr 8)))) =
(
Int.sign_ext 16
i0).
Proof.
Ltac unfsize :=
change Int.zwordsize with 32
in *;
change Int64.zwordsize with 64
in *;
change Int.max_unsigned with 4294967295
in *;
change Int64.max_unsigned with 18446744073709551615
in *;
change Int.modulus with 4294967296
in *;
change Int64.max_unsigned with 18446744073709551616
in *.
Lemma sign_ext_16_id_long:
forall i,
Int.sign_ext 16
(
Int64.loword
(
Int64.add (
Int64.and (
Int64.repr (
Int.unsigned i)) (
Int64.repr 255))
(
Int64.shl'
(
Int64.add
(
Int64.and
(
Int64.shru' (
Int64.repr (
Int.unsigned i)) (
Int.repr 8))
(
Int64.repr 255)) (
Int64.shl'
Int64.zero (
Int.repr 8)))
(
Int.repr 8)))) =
Int.sign_ext 16
i.
Proof.
Lemma zero_ext_16_id_long:
forall i,
Int.zero_ext 16
(
Int64.loword
(
Int64.add
(
Int64.and (
Int64.repr (
Int.unsigned i)) (
Int64.repr 255))
(
Int64.shl'
(
Int64.add
(
Int64.and
(
Int64.shru' (
Int64.repr (
Int.unsigned i)) (
Int.repr 8))
(
Int64.repr 255)) (
Int64.shl'
Int64.zero (
Int.repr 8)))
(
Int.repr 8)))) =
Int.zero_ext 16
i.
Proof.
Lemma zero_ext_16_id:
forall i0,
(
Int.zero_ext 16
(
Int.add (
Int.and i0 (
Int.repr 255))
(
Int.shl
(
Int.add (
Int.and (
Int.shru i0 (
Int.repr 8)) (
Int.repr 255))
(
Int.shl Int.zero (
Int.repr 8))) (
Int.repr 8)))) =
(
Int.zero_ext 16
i0).
Proof.
Ltac sl :=
solve_long;
unfsize;
try lia.
Lemma int32_decomp:
forall i,
Int64.loword
(
Int64.add (
Int64.and (
Int64.repr (
Int.unsigned i)) (
Int64.repr 255))
(
Int64.shl'
(
Int64.add
(
Int64.and
(
Int64.shru' (
Int64.repr (
Int.unsigned i)) (
Int.repr 8))
(
Int64.repr 255))
(
Int64.shl'
(
Int64.add
(
Int64.and
(
Int64.shru'
(
Int64.shru' (
Int64.repr (
Int.unsigned i))
(
Int.repr 8)) (
Int.repr 8))
(
Int64.repr 255))
(
Int64.shl'
(
Int64.add
(
Int64.and
(
Int64.shru'
(
Int64.shru'
(
Int64.shru'
(
Int64.repr (
Int.unsigned i))
(
Int.repr 8))
(
Int.repr 8))
(
Int.repr 8)) (
Int64.repr 255))
(
Int64.shl'
Int64.zero (
Int.repr 8)))
(
Int.repr 8))) (
Int.repr 8)))
(
Int.repr 8))) =
Int.sign_ext 32
i.
Proof.
Lemma add_and_shl_rew:
forall i i'
j,
0 <=
j <
Int64.zwordsize ->
Int64.testbit
(
Int64.add (
Int64.and i (
Int64.repr 255)) (
Int64.shl i' (
Int64.repr 8)))
j =
if zlt j 8
then Int64.testbit i j
else Int64.testbit i' (
j - 8 ).
Proof.
Lemma int64_decomp:
forall i0,
Int64.add (
Int64.and i0 (
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and (
Int64.shru i0 (
Int64.repr 8)) (
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and (
Int64.shru i0 (
Int64.repr 16)) (
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and (
Int64.shru i0 (
Int64.repr 24))
(
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and (
Int64.shru i0 (
Int64.repr 32))
(
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and (
Int64.shru i0 (
Int64.repr 40))
(
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and
(
Int64.shru i0 (
Int64.repr 48))
(
Int64.repr 255))
(
Int64.shl
(
Int64.add
(
Int64.and
(
Int64.shru i0
(
Int64.repr 56))
(
Int64.repr 255))
(
Int64.shl Int64.zero
(
Int64.repr 8)))
(
Int64.repr 8)))
(
Int64.repr 8)))
(
Int64.repr 8))) (
Int64.repr 8)))
(
Int64.repr 8))) (
Int64.repr 8)))
(
Int64.repr 8)) =
i0.
Proof.
Lemma alignment_inj:
forall i i0 i1 i2
(
A :
Int.and i (
Int.not (
Int.repr (
two_power_nat i0 - 1))) =
i)
(
B :
Int.and (
Int.not (
Int.repr (
two_power_nat i0 - 1)))
(
Int.not (
Int.repr (
two_power_nat i1 - 1))) =
Int.not (
Int.repr (
two_power_nat i0 - 1)))
(
C :
Int.and i2 (
Int.not (
Int.repr (
two_power_nat i1 - 1))) =
i2),
Int.and (
Int.add i i2) (
Int.not (
Int.repr (
two_power_nat i1 - 1))) =
Int.add i i2.
Proof.
Ltac elim_div :=
unfold Zdiv,
Zmod in *;
repeat
match goal with
|
H :
context[
Zdiv_eucl ?
X ?
Y ] |-
_ =>
generalize (
Z_div_mod_full X Y) ;
destruct (
Zdiv_eucl X Y)
| |-
context[
Zdiv_eucl ?
X ?
Y ] =>
generalize (
Z_div_mod_full X Y) ;
destruct (
Zdiv_eucl X Y)
end;
unfold Remainder.
Ltac unf_modulus :=
change (
Int.modulus)
with 4294967296
in *.
Lemma int_add_diff_range_plus:
forall o z o'
z0 i,
o +
z <>
o' +
z0 ->
z0 >= 0 ->
z >= 0 ->
0 <=
o' +
z0 <=
Int.modulus - 1 ->
0 <=
o +
z <=
Int.modulus - 1 ->
((
i +
z)
mod Int.modulus +
o)
mod Int.modulus <>
((
i +
z0)
mod Int.modulus +
o')
mod Int.modulus.
Proof.
intros.
rewrite !
Zplus_mod_idemp_l.
revert H.
revert H2 H3.
replace (
i+
z+
o)
with (
i + (
o +
z))
by lia.
replace (
i+
z0+
o')
with (
i + (
o' +
z0))
by lia.
generalize (
o +
z) (
o' +
z0).
clear.
intros.
intro.
unf_modulus.
elim_div.
lia.
Qed.
Lemma int_add_rew:
forall a b,
Int.repr (
Int.unsigned a +
Int.unsigned b) =
Int.add a b.
Proof.
Lemma two_p_abs:
forall n n0,
(
n >=
n0)%
nat ->
Int.and (
Int.not (
Int.repr (
two_power_nat n - 1)))
(
Int.not (
Int.repr (
two_power_nat n0 - 1))) =
Int.not (
Int.repr (
two_power_nat n - 1)).
Proof.
Lemma ge_trans:
(
forall (
a b c:
nat),
a >=
b ->
b >=
c ->
a >=
c)%
nat.
Proof.
intros. lia.
Qed.
Lemma odd_not_2_divides:
forall z,
Z.odd z =
true ->
~ (2 |
z).
Proof.
intros.
destruct 1.
subst.
unfold Z.odd in H.
destruct x;
simpl in *;
try congruence;
destruct p;
simpl in *;
try congruence.
Qed.
Lemma pos2nat_not_zero:
forall b,
Pos.to_nat b <>
O.
Proof.
clear.
intros. lia.
Qed.
Remark decompose_cmpl_eq_zero:
forall h l,
Int64.eq (
Int64.ofwords h l)
Int64.zero =
Int.eq (
Int.or h l)
Int.zero.
Proof.
Remark int64_eq_xor:
forall p q,
Int64.eq p q =
Int64.eq (
Int64.xor p q)
Int64.zero.
Proof.
Lemma int64_ltu_rew:
forall a b,
Int64.ltu a b =
Int64.ltu
(
Int64.ofwords (
Int64.hiword a) (
Int64.loword a))
(
Int64.ofwords (
Int64.hiword b) (
Int64.loword b)).
Proof.
Lemma int64_lt_rew:
forall a b,
Int64.lt a b =
Int64.lt
(
Int64.ofwords (
Int64.hiword a) (
Int64.loword a))
(
Int64.ofwords (
Int64.hiword b) (
Int64.loword b)).
Proof.
Remark decompose_cmpl_lt_zero:
forall h l,
Int64.lt (
Int64.ofwords h l)
Int64.zero =
Int.lt h Int.zero.
Proof.
Lemma two_p_inj_div:
forall n m,
0 <=
n <=
m ->
Z.divide (
two_p n) (
two_p m).
Proof.