Section BUILTIN_ARGUMENTS.
Variable f: Linear.function.
Let b := function_bounds f.
Let fe := make_env b.
Variable tf: Mach.function.
Hypothesis TRANSF_F: transf_function f = OK tf.
Variable j: meminj.
Variables m m': mem.
Variables ls ls0: locset.
Variable rs: regset.
Variables sp sp': block.
Variables parent retaddr: val.
Hypothesis INJ: j sp = Some(sp', fe.(fe_stack_data)).
Hypothesis AGR: agree_regs j ls rs.
Hypothesis SEP: m' |= frame_contents f j sp' ls ls0 parent retaddr ** minjection j m ** globalenv_inject ge j.
End BUILTIN_ARGUMENTS.
(** The proof of semantic preservation relies on simulation diagrams of the following form: << st1 --------------- st2 |                   | t|                  +|t |                   | v                   v st1'--------------- st2' >> Matching between source and target states is defined by [match_states] below.  It implies: - Satisfaction of the separation logic assertions that describe the contents of memory.  This is a separating conjunction of facts about: -- the current stack frame -- the frames in the call stack -- the injection from the Linear memory state into the Mach memory state -- the preservation of the global environment. - Agreement between, on the Linear side, the location sets [ls] and [parent_locset s] of the current function and its caller, and on the Mach side the register set [rs]. - The Linear code [c] is a suffix of the code of the function [f] being executed. - Well-typedness of [f]. *)
Inductive match_states: Linear.state -> Mach.state -> Prop :=
| match_states_intro:
forall cs f sp c ls m cs' fb sp' rs m' j tf
(STACKS: match_stacks j cs cs' f.(Linear.fn_sig))
(TRANSL: transf_function f = OK tf)
(FIND: Genv.find_funct_ptr tge fb = Some (Internal tf))
(AGREGS: agree_regs j ls rs)
(AGLOCS: agree_locs f ls (parent_locset cs))
(INJSP: j sp = Some(sp', fe_stack_data (make_env (function_bounds f))))
(TAIL: is_tail c (Linear.fn_code f))
(SEP: m' |= frame_contents f j sp' ls (parent_locset cs) (parent_sp cs') (parent_ra cs')
** stack_contents j cs cs'
** minjection j m
** globalenv_inject ge j),
match_states (Linear.State cs f (Vptr sp Ptrofs.zero) c ls m)
(Mach.State cs' fb (Vptr sp' Ptrofs.zero) (transl_code (make_env (function_bounds f)) c) rs m')
| match_states_call:
forall cs f ls m cs' fb rs m' j tf
(STACKS: match_stacks j cs cs' (Linear.funsig f))
(TRANSL: transf_fundef f = OK tf)
(FIND: Genv.find_funct_ptr tge fb = Some tf)
(AGREGS: agree_regs j ls rs)
(SEP: m' |= stack_contents j cs cs'
** minjection j m
** globalenv_inject ge j),
match_states (Linear.Callstate cs f ls m)
(Mach.Callstate cs' fb rs m')
| match_states_return:
forall cs ls m cs' rs m' j sg
(STACKS: match_stacks j cs cs' sg)
(AGREGS: agree_regs j ls rs)
(SEP: m' |= stack_contents j cs cs'
** minjection j m
** globalenv_inject ge j),
match_states (Linear.Returnstate cs ls m)
(Mach.Returnstate cs' rs m').

Lemma transf_initial_states:
forall st1, Linear.initial_state prog st1 ->
exists st2, Mach.initial_state tprog st2 /\ match_states st1 st2.