Proof with (try exact I; try reflexivity; auto using Val.Vptr_has_type).
intros.
destruct op; simpl; simpl in H0; FuncInv; subst; simpl.
(* move *)
- congruence.
(* intconst, longconst, floatconst, singleconst *)
- exact I.
- exact I.
- exact I.
- exact I.
(* addrsymbol *)
- unfold Genv.symbol_address. destruct (Genv.find_symbol genv id)...
(* addrstack *)
- destruct sp... apply Val.Vptr_has_type.
(* castsigned *)
- destruct v0...
- destruct v0...
(* add, addimm *)
- apply type_add.
- apply type_add.
(* neg, sub *)
- destruct v0...
- unfold Val.sub. destruct v0; destruct v1...
unfold Val.has_type; destruct Archi.ptr64...
destruct Archi.ptr64... destruct (eq_block b b0)...
(* mul, mulhs, mulhu *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* div, divu *)
- 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...
(* mod, modu *)
- 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...
(* and, andimm *)
- destruct v0; destruct v1...
- destruct v0...
(* or, orimm *)
- destruct v0; destruct v1...
- destruct v0...
(* xor, xorimm *)
- destruct v0; destruct v1...
- destruct v0...
(* shl, shlimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
- destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
(* shr, shrimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
- destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
(* shru, shruimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int.iwordsize)...
- destruct v0; simpl... destruct (Int.ltu n Int.iwordsize)...
(* shrx *)
- destruct v0; simpl in H0; try discriminate. destruct (Int.ltu n (Int.repr 31)); inv H0...
(* makelong, lowlong, highlong *)
- destruct v0; destruct v1...
- destruct v0...
- destruct v0...
(* cast32 *)
- destruct v0...
- destruct v0...
(* addl, addlimm *)
- apply type_addl.
- apply type_addl.
(* negl, subl *)
- destruct v0...
- unfold Val.subl. destruct v0; destruct v1...
unfold Val.has_type; destruct Archi.ptr64...
destruct Archi.ptr64... destruct (eq_block b b0)...
(* mull, mullhs, mullhu *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* divl, divlu *)
- 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...
(* modl, modlu *)
- 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...
(* andl, andlimm *)
- destruct v0; destruct v1...
- destruct v0...
(* orl, orlimm *)
- destruct v0; destruct v1...
- destruct v0...
(* xorl, xorlimm *)
- destruct v0; destruct v1...
- destruct v0...
(* shll, shllimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
- destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
(* shr, shrimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
- destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
(* shru, shruimm *)
- destruct v0; destruct v1; simpl... destruct (Int.ltu i0 Int64.iwordsize')...
- destruct v0; simpl... destruct (Int.ltu n Int64.iwordsize')...
(* shrxl *)
- destruct v0; simpl in H0; try discriminate. destruct (Int.ltu n (Int.repr 63)); inv H0...
(* negf, absf *)
- destruct v0...
- destruct v0...
(* addf, subf *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* mulf, divf *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* negfs, absfs *)
- destruct v0...
- destruct v0...
(* addfs, subfs *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* mulfs, divfs *)
- destruct v0; destruct v1...
- destruct v0; destruct v1...
(* singleoffloat, floatofsingle *)
- destruct v0...
- destruct v0...
(* intoffloat, intuoffloat *)
- 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...
(* floatofint, floatofintu *)
- destruct v0; simpl in H0; inv H0...
- destruct v0; simpl in H0; inv H0...
(* intofsingle, intuofsingle *)
- destruct v0; simpl in H0; inv H0. destruct (Float32.to_int f); inv H2...
- destruct v0; simpl in H0; inv H0. destruct (Float32.to_intu f); inv H2...
(* singleofint, singleofintu *)
- destruct v0; simpl in H0; inv H0...
- destruct v0; simpl in H0; inv H0...
(* longoffloat, longuoffloat *)
- destruct v0; simpl in H0; inv H0. destruct (Float.to_long f); inv H2...
- destruct v0; simpl in H0; inv H0. destruct (Float.to_longu f); inv H2...
(* floatoflong, floatoflongu *)
- destruct v0; simpl in H0; inv H0...
- destruct v0; simpl in H0; inv H0...
(* longofsingle, longuofsingle *)
- destruct v0; simpl in H0; inv H0. destruct (Float32.to_long f); inv H2...
- destruct v0; simpl in H0; inv H0. destruct (Float32.to_longu f); inv H2...
(* singleoflong, singleoflongu *)
- destruct v0; simpl in H0; inv H0...
- destruct v0; simpl in H0; inv H0...
(* cmp *)
- destruct (eval_condition cond vl m)... destruct b...
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.

Lemma is_move_operation_correct:
forall (A: Type) (op: operation) (args: list A) (a: A),
is_move_operation op args = Some a ->
op = Omove /\ args = a :: nil.