Section CONSTRUCTORS.
Variable ge: genv.
Variable fn: function.
(** 32-bit integer constants and arithmetic *)
(** 64-bit integer constants and arithmetic *)
(** Add offset to pointer *)
(** Translation of conditional branches *)
Remark branch_on_X31:
forall normal lbl (rs: regset) m b,
rs#X31 = Val.of_bool (eqb normal b) ->
exec_instr ge fn (if normal then Pbnew X31 X0 lbl else Pbeqw X31 X0 lbl) rs m =
eval_branch fn lbl rs m (Some b).
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 *)
(** Some arithmetic properties. *)
Remark cast32unsigned_from_cast32signed:
forall i, Int64.repr (Int.unsigned i) = Int64.zero_ext 32 (Int64.repr (Int.signed i)).
(* Translation of arithmetic operations *)
Ltac SimplEval H :=
match type of H with
| Some _ = None _ => discriminate
| Some _ = Some _ => inv H
| ?a = Some ?b => let A := fresh in assert (A: Val.maketotal a = b) by (rewrite H; reflexivity)
end.
Ltac TranslOpSimpl :=
econstructor; split;
[ apply exec_straight_one; [simpl; eauto | reflexivity]
| split; [ apply Val.lessdef_same; Simpl; fail | intros; Simpl; fail ] ].
(** Memory accesses *)
(** Function epilogues *)

Lemma make_epilogue_correct:
forall ge0 f m stk soff cs m' ms rs k tm,
load_stack m (Vptr stk soff) Tptr f.(fn_link_ofs) = Some (parent_sp cs) ->
load_stack m (Vptr stk soff) Tptr f.(fn_retaddr_ofs) = Some (parent_ra cs) ->
Mem.free m stk 0 f.(fn_stacksize) = Some m' ->
agree ms (Vptr stk soff) rs ->
Mem.extends m tm ->
match_stack ge0 cs ->
exists rs', exists tm',
exec_straight ge fn (make_epilogue f k) rs tm k rs' tm'
/\ agree ms (parent_sp cs) rs'
/\ Mem.extends m' tm'
/\ rs'#RA = parent_ra cs
/\ rs'#SP = parent_sp cs
/\ (forall r, r <> PC -> r <> RA -> r <> SP -> r <> X31 -> rs'#r = rs#r).