Section CMCONSTR.
Variable sp: val.
Variable e: env.
Variable m: mem.
(*(Sstore chunk addr al b) effsstep tge (State f (store chunk a1 a2) k sp e m) E0 (State f Sskip k sp e m').*)
(** Correctness of instruction selection for operators *)
End CMCONSTR.
(** Recognition of calls to built-in functions *)
(** Compatibility of evaluation functions with the "less defined than" relation. *)
Ltac TrivialExists :=
match goal with
| [ |- exists v, Some ?x = Some v /\ _ ] => exists x; split; auto
| _ => idtac
end.
(*Lemma eval_unop_lessdef: forall op v1 v1' v, eval_unop op v1 = Some v -> Val.lessdef v1 v1' -> exists v', eval_unop op v1' = Some v' /\ Val.lessdef v v'.  (** Lenb: replace eval_unop_lessdef with eval_unop from Cminorgenproof; this requires the additio of Require Import Float above Compatibility of [eval_unop] with respect to [val_inject]. *)
(*Lemma eval_binop_lessdef: forall op v1 v1' v2 v2' v m m', eval_binop op v1 v2 m = Some v -> Val.lessdef v1 v1' -> Val.lessdef v2 v2' -> Mem.extends m m' -> exists v', eval_binop op v1' v2' m' = Some v' /\ Val.lessdef v v'. *)
(** Lenb: same for binops Compatibility of [eval_binop] with respect to [val_inject]. *)
(*Lenb: fom Cminorgenproof: *)
Remark val_inject_val_of_bool:
forall f b, val_inject f (Val.of_bool b) (Val.of_bool b).
(*Lenb: fom Cminorgenproof: *)
Remark val_inject_val_of_optbool:
forall f ob, val_inject f (Val.of_optbool ob) (Val.of_optbool ob).
(*Lenb: fom Cminorgenproof: *)
Ltac TrivialExistsCMINORGEN :=
match goal with
| [ |- exists y, Some ?x = Some y /\ val_inject _ _ _ ] =>
exists x; split; [auto | try(econstructor; eauto)]
| [ |- exists y, _ /\ val_inject _ (Vint ?x) _ ] =>
exists (Vint x); split; [eauto with evalexpr | constructor]
| [ |- exists y, _ /\ val_inject _ (Vfloat ?x) _ ] =>
exists (Vfloat x); split; [eauto with evalexpr | constructor]
| [ |- exists y, _ /\ val_inject _ (Vlong ?x) _ ] =>
exists (Vlong x); split; [eauto with evalexpr | constructor]
| _ => idtac
end.
(** * Semantic preservation for instruction selection. *)
(** Relationship between the local environments. *)
(* Definition env_lessdef (e1 e2: env) : Prop := forall id v1, e1!id = Some v1 -> exists v2, e2!id = Some v2 /\ Val.lessdef v1 v2. *)
Definition env_inject j (e1 e2: env) : Prop :=
forall id v1, e1!id = Some v1 -> exists v2, e2!id = Some v2 /\ val_inject j v1 v2.

(* Lemma set_var_lessdef: forall e1 e2 id v1 v2, env_lessdef e1 e2 -> Val.lessdef v1 v2 -> env_lessdef (PTree.set id v1 e1) (PTree.set id v2 e2). *)
Lemma set_var_inject:
forall j e1 e2 id v1 v2,
env_inject j e1 e2 -> val_inject j v1 v2 ->
env_inject j (PTree.set id v1 e1) (PTree.set id v2 e2).