Section CONSTRUCTORS.
Variable ge: genv.
Variable fn: function.
(** Properties of comparisons. *)
(** Loading a constant. *)
(** Add integer immediate. *)
(** And integer immediate. *)
(** Or integer immediate. *)
(** Xor integer immediate. *)
(** Rotate and mask. *)
(** Load int64 constant. *)
(** Alternate load int64 immediate *)
(** Add int64 immediate. *)
(** Or int64 immediate. *)
(** Xor int64 immediate. *)
(** And int64 immediate. *)
(** Rotate-and-mask for int64 *)
(** Indexed memory loads. *)
(** Indexed memory stores. *)
(** Float comparisons. *)
(** Translation of conditions. *)
Ltac ArgsInv :=
repeat (match goal with
| [ H: Error _ = OK _ |- _ ] => discriminate
| [ H: match ?args with nil => _ | _ :: _ => _ end = OK _ |- _ ] => destruct args
| [ H: bind _ _ = OK _ |- _ ] => monadInv H
| [ H: match _ with left _ => _ | right _ => assertion_failed end = OK _ |- _ ] => monadInv H; ArgsInv
| [ H: match _ with true => _ | false => assertion_failed end = OK _ |- _ ] => monadInv H; ArgsInv
end);
subst;
repeat (match goal with
| [ H: ireg_of _ = OK _ |- _ ] => simpl in *; rewrite (ireg_of_eq _ _ H) in *
| [ H: freg_of _ = OK _ |- _ ] => simpl in *; rewrite (freg_of_eq _ _ H) in *
end).
(** Translation of condition operators *)
Remark add_carry_eq0:
forall i,
Vint (Int.add (Int.add (Int.sub Int.zero i) i)
(Int.add_carry Int.zero (Int.xor i Int.mone) Int.one)) =
Val.of_bool (Int.eq i Int.zero).
Remark add_carry_ne0:
forall i,
Vint (Int.add (Int.add i (Int.xor (Int.add i Int.mone) Int.mone))
(Int.add_carry i Int.mone Int.zero)) =
Val.of_bool (negb (Int.eq i Int.zero)).
(** Translation of arithmetic operations. *)
Ltac TranslOpSimpl :=
econstructor; split;
[ apply exec_straight_one; [simpl; eauto | reflexivity]
| split; [ apply Val.lessdef_same; Simpl; fail | intros; Simpl; fail ] ].
(** Translation of memory accesses *)

Lemma transl_memory_access_correct:
forall (P: regset -> Prop) mk1 mk2 addr args temp k c (rs: regset) a m m',
transl_memory_access mk1 mk2 addr args temp k = OK c ->
eval_addressing ge (rs#GPR1) addr (map rs (map preg_of args)) = Some a ->
temp <> GPR0 ->
(forall cst (r1: ireg) (rs1: regset) k,
Val.lessdef a (Val.add (gpr_or_zero rs1 r1) (const_low ge cst)) ->
(forall r, r <> PC -> r <> temp -> r <> GPR0 -> rs1 r = rs r) ->
exists rs',
exec_straight ge fn (mk1 cst r1 :: k) rs1 m k rs' m' /\ P rs') ->
(forall (r1 r2: ireg) (rs1: regset) k,
Val.lessdef a (Val.add (gpr_or_zero rs1 r1) rs1#r2) ->
(forall r, r <> PC -> r <> temp -> r <> GPR0 -> rs1 r = rs r) ->
exists rs',
exec_straight ge fn (mk2 r1 r2 :: k) rs1 m k rs' m' /\ P rs') ->
exists rs',
exec_straight ge fn c rs m k rs' m' /\ P rs'.