Section PARMOV.
(** * Registers, moves, and their semantics *)
(** The development is parameterized by the type of registers, equipped with a decidable equality. *)
Variable reg: Type.
Variable reg_eq : forall (r1 r2: reg), {r1=r2} + {r1<>r2}.
(** The [temp] function maps every register [r] to the register that should be used to save the value of [r] temporarily while performing a cyclic assignment involving [r].  In the simplest case, there is only one such temporary register [rtemp] and [temp] is the constant function [fun r => rtemp].  In more realistic cases, different temporary registers can be used to hold different values.  In the case of Compcert, we have two temporary registers, one for integer values and the other for floating-point values, and [temp] returns the appropriate temporary depending on the type of its argument. *)
Variable temp: reg -> reg.
Definition is_temp (r: reg): Prop := exists s, r = temp s.
(** A set of moves is a list of pairs of registers, of the form (source, destination). *)
Definition moves := (list (reg * reg))%type.  (* src -> dst *)
Definition srcs (m: moves) := List.map (@fst reg reg) m.
Definition dests (m: moves) := List.map (@snd reg reg) m.
(** ** Semantics of moves *)
(** The dynamic  semantics of moves is given in terms of environments. An environment is a mapping of registers to their current values. *)
Variable val: Type.
Definition env := reg -> val.
Proof (@extensionality reg val).
(** The main operation over environments is update: it assigns a value [v] to a register [r] and preserves the values of other registers. *)
Definition update (r: reg) (v: val) (e: env) : env :=
fun r' => if reg_eq r' r then v else e r'.

Lemma update_commut:
forall r1 v1 r2 v2 e,
r1 <> r2 ->
update r1 v1 (update r2 v2 e) = update r2 v2 (update r1 v1 e).