Remark branch_on_X31:
forall normal lbl (rs: regset) m b,
rs#X31 = Val.of_bool (eqb normal b) ->
exec_instr ge fn (if normal then Pbnew X31 X0 lbl else Pbeqw X31 X0 lbl) rs m =
eval_branch fn lbl rs m (Some b).
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).
Inductive exec_straight_opt: code -> regset -> mem -> code -> regset -> mem -> Prop :=
| exec_straight_opt_refl: forall c rs m,
exec_straight_opt c rs m c rs m
| exec_straight_opt_intro: forall c1 rs1 m1 c2 rs2 m2,
exec_straight ge fn c1 rs1 m1 c2 rs2 m2 ->
exec_straight_opt c1 rs1 m1 c2 rs2 m2.
Remark exec_straight_opt_right:
forall c3 rs3 m3 c1 rs1 m1 c2 rs2 m2,
exec_straight_opt c1 rs1 m1 c2 rs2 m2 ->
exec_straight ge fn c2 rs2 m2 c3 rs3 m3 ->
exec_straight ge fn c1 rs1 m1 c3 rs3 m3.

Lemma transl_cbranch_correct_1:
forall cond args lbl k c m ms b sp rs m',
transl_cbranch cond args lbl k = OK c ->
eval_condition cond (List.map ms args) m = Some b ->
agree ms sp rs ->
Mem.extends m m' ->
exists rs', exists insn,
exec_straight_opt c rs m' (insn :: k) rs' m'
/\ exec_instr ge fn insn rs' m' = eval_branch fn lbl rs' m' (Some b)
/\ forall r, r <> PC -> r <> X31 -> rs'#r = rs#r.