Section SOUNDNESS.
Variable A V: Type.
Variable genv: Genv.t A V.
Proof with (try exact I; try reflexivity).
intros.
destruct op; simpl in H0; FuncInv; subst; simpl.
congruence.
exact I.
auto.
auto.
unfold Genv.symbol_address. destruct (Genv.find_symbol genv i)...
destruct sp...
destruct v0...
destruct v0...
destruct v0; destruct v1...
destruct v0...
unfold Genv.symbol_address. destruct (Genv.find_symbol genv i)... destruct v0...
destruct v0; destruct v1... simpl. destruct (eq_block b b0)...
destruct v0...
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...
destruct v0...
destruct v0; destruct v1...
destruct v0...
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 v1...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0; simpl... destruct (Int.ltu i Int.iwordsize)...
destruct v0; simpl in *; inv H0. destruct (Int.ltu i (Int.repr 31)); inv H2...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
destruct v0...
destruct v0; destruct v1...
exact I.
destruct v0...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
destruct v0...
destruct v0; destruct v1...
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...
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; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
destruct v0; simpl... destruct (Int.ltu i Int64.iwordsize')...
destruct v0; simpl in *; inv H0. destruct (Int.ltu i (Int.repr 63)); inv H2...
destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
destruct v0...
destruct v0; simpl in H0; inv H0. destruct (Float.to_long f); inv H2...
destruct v0; simpl in H0; inv H0...
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 (Float.to_intu f); inv H2...
destruct v0; simpl in H0; inv H0...
destruct v0; simpl in H0; inv H0...
destruct v0; destruct v1...
destruct v0; destruct v1...
destruct v0...
destruct v0...
destruct (eval_condition c 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
| Ccompf c => Cnotcompf c
| Cnotcompf c => Ccompf c
| Cmaskzero n => Cmasknotzero n
| Cmasknotzero n => Cmaskzero 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
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.
(** Offset an addressing mode [addr] by a quantity [delta], so that it designates the pointer [delta] bytes past the pointer designated by [addr].  May be undefined, in which case [None] is returned. *)
Definition offset_addressing (addr: addressing) (delta: Z) : option addressing :=
match addr with
| Aindexed n => Some(Aindexed (Int.add n (Int.repr delta)))
| Aindexed2 => None
| Aglobal s n => Some(Aglobal s (Ptrofs.add n (Ptrofs.repr delta)))
| Abased s n => Some(Abased s (Ptrofs.add n (Ptrofs.repr delta)))
| Ainstack n => Some(Ainstack (Ptrofs.add n (Ptrofs.repr delta)))
end.
(** Operations that are so cheap to recompute that CSE should not factor them out. *)
Definition is_trivial_op (op: operation) : bool :=
match op with
| Omove => true
| Ointconst _ => true
| Oaddrsymbol _ _ => true
| Oaddrstack _ => true
| _ => false
end.
(** Operations that depend on the memory state. *)
Definition condition_depends_on_memory (c: condition) : bool :=
match c with
| Ccompu _ => true
| Ccompuimm _ _ => true
| Ccomplu _ => Archi.ppc64
| Ccompluimm _ _ => Archi.ppc64
| _ => false
end.
Definition op_depends_on_memory (op: operation) : bool :=
match op with
| Ocmp c => condition_depends_on_memory c
| Osel c ty => condition_depends_on_memory c
| _ => false
end.

Lemma op_depends_on_memory_correct:
forall (F V: Type) (ge: Genv.t F V) sp op args m1 m2,
op_depends_on_memory op = false ->
eval_operation ge sp op args m1 = eval_operation ge sp op args m2.