(** Preservation of register agreement under various assignments. *)

(* Specifications: *)
Lemma agree_set_mreg:
forall ms sp rs r v rs',
agree ms sp rs ->
Val.lessdef v (rs'#(preg_of r)) ->
(forall r', data_preg r' = true -> r' <> preg_of r -> rs'#r' = rs#r') ->
agree (Regmap.set r v ms) sp rs'.
Corollary agree_set_mreg_parallel:
forall ms sp rs r v v',
agree ms sp rs ->
Val.lessdef v v' ->
agree (Regmap.set r v ms) sp (Pregmap.set (preg_of r) v' rs).
Lemma agree_set_other:
forall ms sp rs r v,
agree ms sp rs ->
data_preg r = false ->
agree ms sp (rs#r <- v).
Lemma agree_nextinstr:
forall ms sp rs,
agree ms sp rs -> agree ms sp (nextinstr rs).
Lemma agree_set_pair:
forall sp p v v' ms rs,
agree ms sp rs ->
Val.lessdef v v' ->
agree (Mach.set_pair p v ms) sp (set_pair (map_rpair preg_of p) v' rs).
Lemma agree_undef_nondata_regs:
forall ms sp rl rs,
agree ms sp rs ->
(forall r, In r rl -> data_preg r = false) ->
agree ms sp (undef_regs rl rs).
Lemma agree_undef_regs:
forall ms sp rl rs rs',
agree ms sp rs ->
(forall r', data_preg r' = true -> preg_notin r' rl -> rs'#r' = rs#r') ->
agree (Mach.undef_regs rl ms) sp rs'.
Lemma agree_undef_regs2:
forall ms sp rl rs rs',
agree (Mach.undef_regs rl ms) sp rs ->
(forall r', data_preg r' = true -> preg_notin r' rl -> rs'#r' = rs#r') ->
agree (Mach.undef_regs rl ms) sp rs'.
Lemma agree_set_undef_mreg:
forall ms sp rs r v rl rs',
agree ms sp rs ->
Val.lessdef v (rs'#(preg_of r)) ->
(forall r', data_preg r' = true -> r' <> preg_of r -> preg_notin r' rl -> rs'#r' = rs#r') ->
agree (Regmap.set r v (Mach.undef_regs rl ms)) sp rs'.
Lemma agree_undef_caller_save_regs:
forall ms sp rs,
agree ms sp rs ->
agree (Mach.undef_caller_save_regs ms) sp (Asm.undef_caller_save_regs rs).
Lemma agree_change_sp:
forall ms sp rs sp',
agree ms sp rs -> sp' <> Vundef ->
agree ms sp' (rs#SP <- sp').