(** A register is an adequate target for holding the value of an expression if - either the register is associated with a Cminor let-bound variable or a Cminor local variable; - or the register is not associated with any Cminor variable and does not belong to the preserved set [pr]. *)
Inductive target_reg_ok (map: mapping) (pr: list reg): expr -> reg -> Prop :=
| target_reg_var:
forall id r,
map.(map_vars)!id = Some r ->
target_reg_ok map pr (Evar id) r
| target_reg_letvar:
forall idx r,
nth_error map.(map_letvars) idx = Some r ->
target_reg_ok map pr (Eletvar idx) r
| target_reg_other:
forall a r,
~(reg_in_map map r) -> ~In r pr ->
target_reg_ok map pr a r.
Inductive target_regs_ok (map: mapping) (pr: list reg): exprlist -> list reg -> Prop :=
| target_regs_nil:
target_regs_ok map pr Enil nil
| target_regs_cons: forall a1 al r1 rl,
target_reg_ok map pr a1 r1 ->
target_regs_ok map (r1 :: pr) al rl ->
target_regs_ok map pr (Econs a1 al) (r1 :: rl).

(* Specifications: *)
Lemma target_reg_ok_append:
forall map pr a r,
target_reg_ok map pr a r ->
forall pr',
(forall r', In r' pr' -> reg_in_map map r' \/ r' <> r) ->
target_reg_ok map (pr' ++ pr) a r.
Lemma target_reg_ok_cons:
forall map pr a r,
target_reg_ok map pr a r ->
forall r',
reg_in_map map r' \/ r' <> r ->
target_reg_ok map (r' :: pr) a r.
Lemma new_reg_target_ok:
forall map pr s1 a r s2 i,
map_valid map s1 ->
regs_valid pr s1 ->
new_reg s1 = OK r s2 i ->
target_reg_ok map pr a r.
Lemma alloc_reg_target_ok:
forall map pr s1 a r s2 i,
map_valid map s1 ->
regs_valid pr s1 ->
alloc_reg map a s1 = OK r s2 i ->
target_reg_ok map pr a r.
Lemma alloc_regs_target_ok:
forall map al pr s1 rl s2 i,
map_valid map s1 ->
regs_valid pr s1 ->
alloc_regs map al s1 = OK rl s2 i ->
target_regs_ok map pr al rl.