Module Regmap := PMap.
Set Implicit Arguments.
Definition regmap_optget
(A: Type) (or: option reg) (dfl: A) (rs: Regmap.t A) : A :=
match or with
| None => dfl
| Some r => Regmap.get r rs
end.
Definition regmap_optset
(A: Type) (or: option reg) (v: A) (rs: Regmap.t A) : Regmap.t A :=
match or with
| None => rs
| Some r => Regmap.set r v rs
end.
Definition regmap_setres
(A: Type) (res: builtin_res reg) (v: A) (rs: Regmap.t A) : Regmap.t A :=
match res with
| BR r => Regmap.set r v rs
| _ => rs
end.
Notation "a # b" := (Regmap.get b a) (at level 1) : rtl.
Notation "a ## b" := (List.map (fun r => Regmap.get r a) b) (at level 1) : rtl.
Notation "a # b <- c" := (Regmap.set b c a) (at level 1, b at next level) : rtl.
Open Scope rtl.
(** Pointwise "less defined than" relation between register maps. *)
Definition regs_lessdef (rs1 rs2: Regmap.t val) : Prop :=
forall r, Val.lessdef (rs1#r) (rs2#r).

Lemma set_res_lessdef:
forall res v1 v2 rs1 rs2,
Val.lessdef v1 v2 -> regs_lessdef rs1 rs2 ->
regs_lessdef (regmap_setres res v1 rs1) (regmap_setres res v2 rs2).