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.

Lemma zero_ext_range2:
forall n i lo hi,
0 <= n < Int.zwordsize ->
lo = 0 ->
hi = two_p n - 1 ->
lo <= Int.unsigned (Int.zero_ext n i) <= hi.