Section INLINING.
Variable prog: program.
Variable tprog: program.
Hypothesis TRANSF: match_prog prog tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
Proof (Genv.find_symbol_match TRANSF).
Proof (Genv.senv_match TRANSF).
Proof (Genv.find_funct_match TRANSF).
Proof (Genv.find_funct_ptr_match TRANSF).
(** ** Properties of contexts and relocations *)
Remark sreg_below_diff:
forall ctx r r', Plt r' ctx.(dreg) -> sreg ctx r <> r'.
Remark context_below_diff:
forall ctx1 ctx2 r1 r2,
context_below ctx1 ctx2 -> Ple r1 ctx1.(mreg) -> sreg ctx1 r1 <> sreg ctx2 r2.
Remark context_below_lt:
forall ctx1 ctx2 r, context_below ctx1 ctx2 -> Ple r ctx1.(mreg) -> Plt (sreg ctx1 r) ctx2.(dreg).
(* Remark context_below_le: forall ctx1 ctx2 r, context_below ctx1 ctx2 -> Ple r ctx1.(mreg) -> Ple (sreg ctx1 r) ctx2.(dreg). *)
(** ** Agreement between register sets before and after inlining. *)
Definition agree_regs (F: meminj) (ctx: context) (rs rs': regset) :=
(forall r, Ple r ctx.(mreg) -> Val.inject F rs#r rs'#(sreg ctx r))
/\(forall r, Plt ctx.(mreg) r -> rs#r = Vundef).
Definition val_reg_charact (F: meminj) (ctx: context) (rs': regset) (v: val) (r: reg) :=
(Plt ctx.(mreg) r /\ v = Vundef) \/ (Ple r ctx.(mreg) /\ Val.inject F v rs'#(sreg ctx r)).
Remark Plt_Ple_dec:
forall p q, {Plt p q} + {Ple q p}.
Remark agree_regs_init:
forall F ctx rs, agree_regs F ctx (Regmap.init Vundef) rs.
(** ** Executing sequences of moves *)

Lemma tr_moves_init_regs:
forall F stk f sp m ctx1 ctx2, context_below ctx1 ctx2 ->
forall rdsts rsrcs vl pc1 pc2 rs1,
tr_moves f.(fn_code) pc1 (sregs ctx1 rsrcs) (sregs ctx2 rdsts) pc2 ->
(forall r, In r rdsts -> Ple r ctx2.(mreg)) ->
list_forall2 (val_reg_charact F ctx1 rs1) vl rsrcs ->
exists rs2,
star step tge (State stk f sp pc1 rs1 m)
E0 (State stk f sp pc2 rs2 m)
/\ agree_regs F ctx2 (init_regs vl rdsts) rs2
/\ forall r, Plt r ctx2.(dreg) -> rs2#r = rs1#r.