(** 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).

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.