(** The following lemmas show the correctness of the register reloading code generated by [reload_callee_save]: after this code has executed, all callee-save registers contain the same values they had at function entry. *)
Section RESTORE_CALLEE_SAVE.
Variable j: meminj.
Variable cs: list stackframe.
Variable fb: block.
Variable sp: block.
Variable ls0: locset.
Variable m: mem.
Definition agree_unused (ls0: locset) (rs: regset) : Prop :=
forall r, ~(mreg_within_bounds b r) -> Val.inject j (ls0 (R r)) (rs r).

(* Specifications: *)
Lemma restore_callee_save_rec_correct:
forall l ofs rs k,
m |= contains_callee_saves j sp ofs l ls0 ->
agree_unused ls0 rs ->
(forall r, In r l -> mreg_within_bounds b r) ->
exists rs',
star step tge
(State cs fb (Vptr sp Ptrofs.zero) (restore_callee_save_rec l ofs k) rs m)
E0 (State cs fb (Vptr sp Ptrofs.zero) k rs' m)
/\ (forall r, In r l -> Val.inject j (ls0 (R r)) (rs' r))
/\ (forall r, ~(In r l) -> rs' r = rs r)
/\ agree_unused ls0 rs'.