Definition match_prog (p: CminorSel.program) (tp: RTL.program) :=
  match_program (fun cu f tf => transl_fundef f = Errors.OK tf) eq p tp.

(* Specifications: *)
Lemma transf_program_match: forall p tp, transl_program p = OK tp -> match_prog p tp.
Lemma symbols_preserved: forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
Lemma function_ptr_translated: forall (b: block) (f: CminorSel.fundef), Genv.find_funct_ptr ge b = Some f -> exists tf, Genv.find_funct_ptr tge b = Some tf /\ transl_fundef f = OK tf.
Lemma functions_translated: forall (v: val) (f: CminorSel.fundef), Genv.find_funct ge v = Some f -> exists tf, Genv.find_funct tge v = Some tf /\ transl_fundef f = OK tf.
Lemma sig_transl_function: forall (f: CminorSel.fundef) (tf: RTL.fundef), transl_fundef f = OK tf -> RTL.funsig tf = CminorSel.funsig f.
Lemma senv_preserved: Senv.equiv (Genv.to_senv ge) (Genv.to_senv tge).
Lemma transl_expr_Eop_correct: forall (le : letenv) (op : operation) (args : exprlist) (vargs : list val) (v : val), eval_exprlist ge sp e m le args vargs -> transl_exprlist_prop le args vargs -> eval_operation ge sp op vargs m = Some v -> transl_expr_prop le (Eop op args) v.
Lemma transl_expr_Eload_correct: forall (le : letenv) (chunk : memory_chunk) (addr : Op.addressing) (args : exprlist) (vargs : list val) (vaddr v : val), eval_exprlist ge sp e m le args vargs -> transl_exprlist_prop le args vargs -> Op.eval_addressing ge sp addr vargs = Some vaddr -> Mem.loadv chunk m vaddr = Some v -> transl_expr_prop le (Eload chunk addr args) v.
Lemma transl_expr_Econdition_correct: forall (le : letenv) (a: condexpr) (ifso ifnot : expr) (va : bool) (v : val), eval_condexpr ge sp e m le a va -> transl_condexpr_prop le a va -> eval_expr ge sp e m le (if va then ifso else ifnot) v -> transl_expr_prop le (if va then ifso else ifnot) v -> transl_expr_prop le (Econdition a ifso ifnot) v.
Lemma transl_expr_Elet_correct: forall (le : letenv) (a1 a2 : expr) (v1 v2 : val), eval_expr ge sp e m le a1 v1 -> transl_expr_prop le a1 v1 -> eval_expr ge sp e m (v1 :: le) a2 v2 -> transl_expr_prop (v1 :: le) a2 v2 -> transl_expr_prop le (Elet a1 a2) v2.
Lemma transl_expr_Eletvar_correct: forall (le : list val) (n : nat) (v : val), nth_error le n = Some v -> transl_expr_prop le (Eletvar n) v.
Lemma transl_expr_Ebuiltin_correct: forall le ef al vl v, eval_exprlist ge sp e m le al vl -> transl_exprlist_prop le al vl -> external_call ef ge vl m E0 v m -> transl_expr_prop le (Ebuiltin ef al) v.
Lemma transl_expr_Eexternal_correct: forall le id sg al b ef vl v, Genv.find_symbol ge id = Some b -> Genv.find_funct_ptr ge b = Some (External ef) -> ef_sig ef = sg -> eval_exprlist ge sp e m le al vl -> transl_exprlist_prop le al vl -> external_call ef ge vl m E0 v m -> transl_expr_prop le (Eexternal id sg al) v.
Lemma transl_exprlist_Enil_correct: forall (le : letenv), transl_exprlist_prop le Enil nil.
Lemma transl_exprlist_Econs_correct: forall (le : letenv) (a1 : expr) (al : exprlist) (v1 : val) (vl : list val), eval_expr ge sp e m le a1 v1 -> transl_expr_prop le a1 v1 -> eval_exprlist ge sp e m le al vl -> transl_exprlist_prop le al vl -> transl_exprlist_prop le (Econs a1 al) (v1 :: vl).
Lemma transl_condexpr_CEcond_correct: forall le cond al vl vb, eval_exprlist ge sp e m le al vl -> transl_exprlist_prop le al vl -> eval_condition cond vl m = Some vb -> transl_condexpr_prop le (CEcond cond al) vb.
Lemma transl_condexpr_CEcondition_correct: forall le a b c va v, eval_condexpr ge sp e m le a va -> transl_condexpr_prop le a va -> eval_condexpr ge sp e m le (if va then b else c) v -> transl_condexpr_prop le (if va then b else c) v -> transl_condexpr_prop le (CEcondition a b c) v.
Lemma transl_condexpr_CElet_correct: forall le a b v1 v2, eval_expr ge sp e m le a v1 -> transl_expr_prop le a v1 -> eval_condexpr ge sp e m (v1 :: le) b v2 -> transl_condexpr_prop (v1 :: le) b v2 -> transl_condexpr_prop le (CElet a b) v2.
Theorem transl_expr_correct: forall le a v, eval_expr ge sp e m le a v -> transl_expr_prop le a v.
Theorem transl_exprlist_correct: forall le a v, eval_exprlist ge sp e m le a v -> transl_exprlist_prop le a v.
Theorem transl_condexpr_correct: forall le a v, eval_condexpr ge sp e m le a v -> transl_condexpr_prop le a v.