Require Export Coq.Lists.List.
Require Export Coq.ZArith.ZArith.
Require Export compcert.lib.Coqlib.
Require Export compcert.lib.Integers.
Require Export compcert.lib.Floats.
Require Export compcert.common.Values.
Require Export VST.msl.eq_dec.
Require Export VST.msl.Coqlib2.
Require Export VST.floyd.coqlib3.
Require Export VST.floyd.sublist.
Hint Rewrite <- offset_val_force_ptr : norm.
Hint Rewrite offset_offset_val: norm.
Hint Rewrite add_repr add64_repr ptrofs_add_repr : norm.
Hint Rewrite mul_repr mul64_repr ptrofs_mul_repr : norm.
Hint Rewrite sub_repr sub64_repr ptrofs_sub_repr : norm.
Hint Rewrite and_repr and64_repr : norm.
Hint Rewrite or_repr or64_repr : norm.
Hint Rewrite neg_repr neg64_repr : norm.
Hint Rewrite int_add_assoc1 : norm.
Hint Rewrite ptrofs_add_assoc1 : norm.
(* Hint Rewrite ptr_eq_True' using solve[auto] : norm. *)
Hint Rewrite ptr_eq_True using solve[auto] : norm.
Hint Rewrite isptr_offset_val_zero using solve [auto] : norm.
Hint Rewrite isptr_offset_val : norm.
Hint Rewrite isptr_force_ptr' : norm.
Ltac no_evars P := (has_evar P; fail 1) || idtac.
Ltac putable x :=
match x with
| O => idtac
| S ?x => putable x
| Z.lt ?x ?y => putable x; putable y
| Z.le ?x ?y => putable x; putable y
| Z.gt ?x ?y => putable x; putable y
| Z.ge ?x ?y => putable x; putable y
| eq?x ?y => putable x; putable y
| ?x <> ?y => putable x; putable y
| Zpos ?x => putable x
| Zneg ?x => putable x
| Z0 => idtac
| xH => idtac
| xI ?x => putable x
| xO ?x => putable x
| Z.add ?x ?y => putable x; putable y
| Z.sub ?x ?y => putable x; putable y
| Z.mul ?x ?y => putable x; putable y
| Z.div ?x ?y => putable x; putable y
| Zmod ?x ?y => putable x; putable y
| Z.max ?x ?y => putable x; putable y
| Z.opp ?x => putable x
| Ceq => idtac
| Cne => idtac
| Clt => idtac
| Cle => idtac
| Cgt => idtac
| Cge => idtac
| ?x /\ ?y => putable x; putable y
| two_power_nat ?x => putable x
| Int.eq ?x ?y => putable x; putable y
| Int64.eq ?x ?y => putable x; putable y
| Ptrofs.eq ?x ?y => putable x; putable y
| Int.lt ?x ?y => putable x; putable y
| Int64.lt ?x ?y => putable x; putable y
| Ptrofs.lt ?x ?y => putable x; putable y
| Int.ltu ?x ?y => putable x; putable y
| Int64.ltu ?x ?y => putable x; putable y
| Ptrofs.ltu ?x ?y => putable x; putable y
| Int.add ?x ?y => putable x; putable y
| Int64.add ?x ?y => putable x; putable y
| Ptrofs.add ?x ?y => putable x; putable y
| Int.sub ?x ?y => putable x; putable y
| Int64.sub ?x ?y => putable x; putable y
| Ptrofs.sub ?x ?y => putable x; putable y
| Int.mul ?x ?y => putable x; putable y
| Int64.mul ?x ?y => putable x; putable y
| Ptrofs.mul ?x ?y => putable x; putable y
| Int.neg ?x => putable x
| Int64.neg ?x => putable x
| Ptrofs.neg ?x => putable x
| Ceq => idtac
| Cne => idtac
| Clt => idtac
| Cle => idtac
| Cgt => idtac
| Cge => idtac
| Int.cmp ?op ?x ?y => putable op; putable x; putable y
| Int64.cmp ?op ?x ?y => putable op; putable x; putable y
| Ptrofs.cmp ?op ?x ?y => putable op; putable x; putable y
| Int.cmpu ?op ?x ?y => putable op; putable x; putable y
| Int64.cmpu ?op ?x ?y => putable op; putable x; putable y
| Ptrofs.cmpu ?op ?x ?y => putable op; putable x; putable y
| Int.repr ?x => putable x
| Int64.repr ?x => putable x
| Ptrofs.repr ?x => putable x
| Int.signed ?x => putable x
| Int64.signed ?x => putable x
| Ptrofs.signed ?x => putable x
| Int.unsigned ?x => putable x
| Int64.unsigned ?x => putable x
| Ptrofs.unsigned ?x => putable x
| two_power_nat ?x => putable x
| Int.max_unsigned => idtac
| Int64.max_unsigned => idtac
| Ptrofs.max_unsigned => idtac
| Int.min_signed => idtac
| Int64.min_signed => idtac
| Ptrofs.min_signed => idtac
| Int.max_signed => idtac
| Int64.max_signed => idtac
| Ptrofs.max_signed => idtac
| Int.modulus => idtac
| Int64.modulus => idtac
| Ptrofs.modulus => idtac
| Int.zwordsize => idtac
| Int64.zwordsize => idtac
| Ptrofs.zwordsize => idtac
end.
Ltac computable := match goal with |- ?x =>
no_evars x;
putable x;
compute; clear; repeat split; auto; congruence;
(match goal with |- context [Archi.ptr64] => idtac end;
first [change Archi.ptr64 with false | change Archi.ptr64 with true];
compute; repeat split; auto; congruence)
end.
Hint Extern 3 (_ <= Int.signed (Int.sign_ext _ _) <= _) =>
(apply sign_ext_range2; [computable | reflexivity | reflexivity]) : core.
Hint Extern 3 (_ <= Int.unsigned (Int.zero_ext _ _) <= _) =>
(apply zero_ext_range2; [computable | reflexivity | reflexivity]) : core.
Hint Rewrite sign_ext_inrange using assumption : norm.
Hint Rewrite zero_ext_inrange using assumption : norm.
Definition repable_signed (z: Z) :=
Int.min_signed <= z <= Int.max_signed.
Definition repable_signed_dec (z: Z) : {repable_signed z}+{~repable_signed z}.

Lemma repable_signed_mult1:
forall i j, j<>0 ->  (i <= Int.max_signed \/ j <> -1) ->
repable_signed (i*j) -> repable_signed i.