(** Translation of conditions. *)
Ltac ArgsInv :=
repeat (match goal with
| [ H: Error _ = OK _ |- _ ] => discriminate
| [ H: match ?args with nil => _ | _ :: _ => _ end = OK _ |- _ ] => destruct args
| [ H: bind _ _ = OK _ |- _ ] => monadInv H
| [ H: match _ with left _ => _ | right _ => assertion_failed end = OK _ |- _ ] => monadInv H; ArgsInv
| [ H: match _ with true => _ | false => assertion_failed end = OK _ |- _ ] => monadInv H; ArgsInv
end);
subst;
repeat (match goal with
| [ H: ireg_of _ = OK _ |- _ ] => simpl in *; rewrite (ireg_of_eq _ _ H) in *
| [ H: freg_of _ = OK _ |- _ ] => simpl in *; rewrite (freg_of_eq _ _ H) in *
end).

(* Specifications: *)
Lemma transl_cond_correct_1:
forall cond args k rs m c,
transl_cond cond args k = OK c ->
exists rs',
exec_straight ge fn c rs m k rs' m
/\ rs'#(reg_of_crbit (fst (crbit_for_cond cond))) =
(if snd (crbit_for_cond cond)
then Val.of_optbool (eval_condition cond (map rs (map preg_of args)) m)
else Val.notbool (Val.of_optbool (eval_condition cond (map rs (map preg_of args)) m)))
/\ forall r, important_preg r = true  -> preg_notin r (destroyed_by_cond cond) ->  rs'#r = rs#r.
Lemma transl_cond_correct_2:
forall cond args k rs m b c,
transl_cond cond args k = OK c ->
eval_condition cond (map rs (map preg_of args)) m = Some b ->
exists rs',
exec_straight ge fn c rs m k rs' m
/\ rs'#(reg_of_crbit (fst (crbit_for_cond cond))) =
(if snd (crbit_for_cond cond)
then Val.of_bool b
else Val.notbool (Val.of_bool b))
/\ forall r, important_preg r = true -> preg_notin r (destroyed_by_cond cond)  -> rs'#r = rs#r.
Lemma transl_cond_correct_3:
forall cond args k ms sp rs m b m' c,
transl_cond cond args k = OK c ->
agree ms sp rs ->
eval_condition cond (map ms args) m = Some b ->
Mem.extends m m' ->
exists rs',
exec_straight ge fn c rs m' k rs' m'
/\ rs'#(reg_of_crbit (fst (crbit_for_cond cond))) =
(if snd (crbit_for_cond cond)
then Val.of_bool b
else Val.notbool (Val.of_bool b))
/\ agree (Mach.undef_regs (destroyed_by_cond cond) ms) sp rs'.