Section SOUNDNESS.
Variable A V: Type.
Variable genv: Genv.t A V.
Remark type_add:
forall v1 v2, Val.has_type (Val.add v1 v2) Tint.
Remark type_addl:
forall v1 v2, Val.has_type (Val.addl v1 v2) Tlong.
Proof with (try exact I; try reflexivity).
intros.
destruct op; simpl in H0; FuncInv; subst; simpl.
congruence.
exact I.
exact I.
exact I.
exact I.
unfold Genv.symbol_address; destruct (Genv.find_symbol genv id)...
destruct v0...
destruct v0...
destruct v0...
destruct v0...
destruct v0...
unfold Val.sub, Val.has_type; destruct Archi.ptr64, v0, v1... destruct (eq_block b b0)...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1; simpl in *; 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 *; inv H0. destruct (Int.eq i0 Int.zero); inv H2...
destruct v0; destruct v1; simpl in *; 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 *; inv H0. destruct (Int.eq i0 Int.zero); inv H2...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
destruct v0; simpl in H0; try discriminate. destruct (Int.ltu n (Int.repr 31)); inv H0...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
destruct v0...
destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
destruct v1; simpl... destruct (Int.ltu (Int.sub Int.iwordsize n) Int.iwordsize)...
eapply type_of_addressing32_sound; eauto.
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct v0...
destruct v0...
destruct v0...
unfold Val.addl, Val.has_type; destruct Archi.ptr64, v0...
unfold Val.subl, Val.has_type; destruct Archi.ptr64, v0, v1... destruct (eq_block b b0)...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0; destruct v1; simpl in *; inv H0.
destruct (Int64.eq i0 Int64.zero || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2...
destruct v0; destruct v1; simpl in *; inv H0. destruct (Int64.eq i0 Int64.zero); inv H2...
destruct v0; destruct v1; simpl in *; inv H0.
destruct (Int64.eq i0 Int64.zero || Int64.eq i (Int64.repr Int64.min_signed) && Int64.eq i0 Int64.mone); inv H2...
destruct v0; destruct v1; simpl in *; inv H0. destruct (Int64.eq i0 Int64.zero); inv H2...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
destruct v0; inv H0. destruct (Int.ltu n (Int.repr 63)); inv H2...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
destruct v0...
eapply type_of_addressing64_sound; eauto.
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); inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0. destruct (Float32.to_int f); inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0. destruct (Float.to_long f); inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0. destruct (Float32.to_long f); inv H2...
destruct v0; simpl in H0; inv H0...
destruct (eval_condition cond vl m); simpl... destruct b...
unfold Val.select. destruct (eval_condition c vl m). apply Val.normalize_type. exact I.
Qed.
End SOUNDNESS.
(** * Manipulating and transforming operations *)
(** 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)
| Ccompimm c n => Ccompimm (negate_comparison c) n
| Ccompuimm c n => Ccompuimm (negate_comparison c) n
| Ccompl c => Ccompl(negate_comparison c)
| Ccomplu c => Ccomplu(negate_comparison c)
| Ccomplimm c n => Ccomplimm (negate_comparison c) n
| Ccompluimm c n => Ccompluimm (negate_comparison c) n
| Ccompf c => Cnotcompf c
| Cnotcompf c => Ccompf c
| Ccompfs c => Cnotcompfs c
| Cnotcompfs c => Ccompfs c
| Cmaskzero n => Cmasknotzero n
| Cmasknotzero n => Cmaskzero n
end.

Lemma eval_negate_condition:
forall cond vl m,
eval_condition (negate_condition cond) vl m = option_map negb (eval_condition cond vl m).