Section SOUNDNESS.
Variable A V: Type.
Variable genv: Genv.t A V.
Proof with (try exact I; try reflexivity).
assert (S: forall s v, Val.has_type (eval_shift s v) Tint).
intros. unfold eval_shift. destruct s; destruct v; simpl; auto; rewrite s_range; exact I.
intros.
destruct op; simpl; simpl in H0; FuncInv; try subst v...
congruence.
unfold Genv.symbol_address. destruct (Genv.find_symbol genv i)...
destruct sp...
destruct v0...
destruct v0...
destruct v0; destruct v1...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; tauto.
destruct v0...
destruct v0; destruct v1... simpl. destruct (eq_block b b0)...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; intuition. destruct (eq_block b b0)...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; intuition. destruct (eq_block b0 b)...
destruct v0...
destruct v0; destruct v1...
destruct v0... destruct v1... destruct v2...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1; simpl in H0; inv H0.
destruct (Int.eq i0 Int.zero || Int.eq i (Int.repr Int.min_signed) && Int.eq i0 Int.mone); inv H2...
destruct v0; destruct v1; simpl in H0; inv H0. destruct (Int.eq i0 Int.zero); inv H2...
destruct v0; destruct v1...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; tauto.
destruct v0...
destruct v0; destruct v1...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; tauto.
destruct v0...
destruct v0; destruct v1...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; tauto.
destruct v0...
destruct v0; destruct v1...
generalize (S s v1). destruct v0; destruct (eval_shift s v1); simpl; tauto.
destruct v0...
generalize (S s v0). destruct (eval_shift s v0); simpl; tauto.
destruct v0; destruct v1... simpl. destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; destruct v1... simpl. destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; destruct v1... simpl. destruct (Int.ltu i0 Int.iwordsize)...
apply S.
destruct v0; simpl in H0; inv H0. destruct (Int.ltu i (Int.repr 31)); inv H2...
destruct v0...
destruct v0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct v0; simpl in H0; inv H0. destruct (Float.to_int f); simpl in H2; inv H2...
destruct v0; simpl in H0; inv H0. destruct (Float.to_intu f); simpl in H2; inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0. destruct (Float32.to_int f); simpl in H2; inv H2...
destruct v0; simpl in H0; inv H0. destruct (Float32.to_intu f); simpl in H2; inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct (eval_condition c vl m)... destruct b...
unfold Val.select. destruct (eval_condition c vl m). apply Val.normalize_type. exact I.
Qed.
End SOUNDNESS.
(** * Manipulating and transforming operations *)
(** Constructing shift amounts. *)
Program Definition mk_shift_amount (n: int) : shift_amount :=
{| s_amount := Int.modu n Int.iwordsize; s_range := _ |}.
Next Obligation.
assert (0 <= Z.modulo (Int.unsigned n) 32 < 32). apply Z_mod_lt. omega.
unfold Int.ltu, Int.modu. change (Int.unsigned Int.iwordsize) with 32.
rewrite Int.unsigned_repr. apply zlt_true. omega.
assert (32 < Int.max_unsigned). compute; auto. omega.
Qed.
(** Recognition of move operations. *)
Definition is_move_operation
(A: Type) (op: operation) (args: list A) : option A :=
match op, args with
| Omove, arg :: nil => Some arg
| _, _ => None
end.
(** [negate_condition cond] returns a condition that is logically equivalent to the negation of [cond]. *)
Definition negate_condition (cond: condition): condition :=
match cond with
| Ccomp c => Ccomp(negate_comparison c)
| Ccompu c => Ccompu(negate_comparison c)
| Ccompshift c s => Ccompshift (negate_comparison c) s
| Ccompushift c s => Ccompushift (negate_comparison c) s
| Ccompimm c n => Ccompimm (negate_comparison c) n
| Ccompuimm c n => Ccompuimm (negate_comparison c) n
| Ccompf c => Cnotcompf c
| Cnotcompf c => Ccompf c
| Ccompfzero c => Cnotcompfzero c
| Cnotcompfzero c => Ccompfzero c
| Ccompfs c => Cnotcompfs c
| Cnotcompfs c => Ccompfs c
| Ccompfszero c => Cnotcompfszero c
| Cnotcompfszero c => Ccompfszero c
end.
(** Shifting stack-relative references.  This is used in [Stacking]. *)
Definition shift_stack_addressing (delta: Z) (addr: addressing) :=
match addr with
| Ainstack ofs => Ainstack (Ptrofs.add (Ptrofs.repr delta) ofs)
| _ => addr
end.
Definition shift_stack_operation (delta: Z) (op: operation) :=
match op with
| Oaddrstack ofs => Oaddrstack (Ptrofs.add (Ptrofs.repr delta) ofs)
| _ => op
end.

Lemma type_shift_stack_operation:
forall delta op, type_of_operation (shift_stack_operation delta op) = type_of_operation op.