(*From Cminorgenproof*)
Remark val_inject_function_pointer:
  forall v fd j tv,
  Genv.find_funct ge v = Some fd ->
  globalfunction_ptr_inject j ->
  val_inject j v tv ->
  tv = v.

(* Specifications: *)
Lemma match_env_inject_incr: forall j e te (MENV : match_env j e te) j' (INC: inject_incr j j'), match_env j' e te.
Lemma match_env_restrictD: forall j X e te (MENV : match_env (restrict j X) e te), match_env j e te.
Lemma match_env_same_blocks: forall j e te (ENV: match_env j e te), list_forall2 (fun (i_x : positive * (block * type)) (i_y : positive * (block * Z)) => fst i_x = fst i_y /\ j (fst (snd i_x)) = Some (fst (snd i_y), 0) /\ snd (snd i_y) = sizeof (snd (snd i_x))) (PTree.elements e) (PTree.elements te).
Lemma match_env_free_blocks_parallel_inject: forall e te m m' j tm (ENV: match_env j e te) (INJ: Mem.inject j m tm) (FL: Mem.free_list m (Clight.blocks_of_env e) = Some m'), exists tm', Mem.free_list tm (blocks_of_env te) = Some tm' /\ Mem.inject j m' tm'.
Lemma freelist_freelist_inject: forall m1 m1' j m2 e (FL1: Mem.free_list m1 (Clight.blocks_of_env e) = Some m1') (INJ : Mem.inject j m1 m2) te (MENV : match_env j e te) m2' (FL2 : Mem.free_list m2 (blocks_of_env te) = Some m2'), Mem.inject j m1' m2'.
Lemma FreelistEffect_PropagateLeft: forall m e m' (FL : Mem.free_list m (Clight.blocks_of_env e) = Some m') mu m2 (SMV : sm_valid mu m m2) (WD: SM_wd mu) te (MENV: match_env (restrict (as_inj mu) (vis mu)) e te) b2 ofs (EFF : FreelistEffect m2 (blocks_of_env te) b2 ofs = true) (LB: locBlocksTgt mu b2 = false), exists b1 delta, foreign_of mu b1 = Some (b2, delta) /\ FreelistEffect m (Clight.blocks_of_env e) b1 (ofs - delta) = true /\ Mem.perm m b1 (ofs - delta) Max Nonempty.
Lemma match_env_empty: forall j, match_env j Clight.empty_env Csharpminor.empty_env.
Lemma match_env_alloc_variables: forall vars e1 m1 e2 m2, Clight.alloc_variables e1 m1 vars e2 m2 -> forall mu te1 tm1, match_env (restrict (as_inj mu) (vis mu)) e1 te1 -> Mem.inject (as_inj mu) m1 tm1 -> SM_wd mu -> sm_valid mu m1 tm1 -> exists te2 tm2 mu', Csharpminor.alloc_variables te1 tm1 (map transl_var vars) te2 tm2 /\ match_env (restrict (as_inj mu') (vis mu')) e2 te2 /\ Mem.inject (as_inj mu') m2 tm2 /\ intern_incr mu mu' /\ sm_inject_separated mu mu' m1 tm1 /\ sm_locally_allocated mu mu' m1 tm1 m2 tm2 /\ SM_wd mu' /\ sm_valid mu' m2 tm2 /\ (REACH_closed m1 (vis mu) -> REACH_closed m2 (vis mu')).
Lemma match_tempenv_inject_incr: forall j e te (TENV : match_tempenv j e te) j' (INC: inject_incr j j'), match_tempenv j' e te.
Lemma match_tempenv_set: forall j le tle (TENV : match_tempenv j le tle) v tv (Inj : val_inject j v tv) x, match_tempenv j (PTree.set x v le) (PTree.set x tv tle).
Lemma create_undef_temps_match: forall temps, create_undef_temps (map fst temps) = Clight.create_undef_temps temps.
Lemma create_undef_temps_match_inject: forall temps j, match_tempenv j (Clight.create_undef_temps temps) (create_undef_temps (map fst temps)).
Lemma bind_parameter_temps_match_inject: forall vars vals le1 le2 (BP: Clight.bind_parameter_temps vars vals le1 = Some le2) j tle1 (TENV: match_tempenv j le1 tle1) tvals (Inj: val_list_inject j vals tvals), exists tle2, bind_parameters (map fst vars) tvals tle1 = Some tle2 /\ match_tempenv j le2 tle2.
Lemma unary_op_inject: forall op v ty u (SUO:sem_unary_operation op v ty = Some u) j tv (V: val_inject j v tv), val_inject j u u /\ sem_unary_operation op tv ty = Some u.
Lemma unary_op_inject': forall op v ty u (SUO:sem_unary_operation op v ty = Some u) j tv (V: val_inject j v tv), exists tu, val_inject j u tu /\ sem_unary_operation op tv ty = Some tu.
Lemma binary_op_inject: forall op v1 v2 ty1 ty2 m u (SBO:sem_binary_operation op v1 ty1 v2 ty2 m = Some u) j tm (MINJ : Mem.inject j m tm) tv1 (V1: val_inject j v1 tv1) tv2 (V2: val_inject j v2 tv2), exists tu, sem_binary_operation op tv1 ty1 tv2 ty2 tm = Some tu /\ val_inject j u tu.
Lemma deref_loc_inject: forall ty b ofs v (D:deref_loc ty m b ofs v) tb delta (J: j b = Some(tb,delta)), exists tv, val_inject j v tv /\ deref_loc ty tm tb (Int.add ofs (Int.repr delta)) tv.
Lemma transl_expr_lvalue_correct: (forall a v, Clight.eval_expr ge e le m a v -> forall ta (TR: transl_expr a = OK ta), exists tv, val_inject j v tv /\ Csharpminor.eval_expr tge te tle tm ta tv) /\(forall a b ofs, Clight.eval_lvalue ge e le m a b ofs -> forall ta (TR: transl_lvalue a = OK ta), exists tv, val_inject j (Vptr b ofs) tv /\ Csharpminor.eval_expr tge te tle tm ta tv).
Lemma transl_expr_correct: forall a v, Clight.eval_expr ge e le m a v -> forall ta, transl_expr a = OK ta -> exists tv, val_inject j v tv /\ eval_expr tge te tle tm ta tv.
Lemma transl_lvalue_correct: forall a b ofs, eval_lvalue ge e le m a b ofs -> forall ta, transl_lvalue a = OK ta -> exists tv, val_inject j (Vptr b ofs) tv /\ eval_expr tge te tle tm ta tv.
Lemma transl_arglist_correct: forall al tyl vl, Clight.eval_exprlist ge e le m al tyl vl -> forall tal, transl_arglist al tyl = OK tal -> exists tvl, val_list_inject j vl tvl /\ Csharpminor.eval_exprlist tge te tle tm tal tvl.
Lemma make_boolean_inject: forall a v ty b, Clight.eval_expr ge e le m a v -> bool_val v ty = Some b -> forall ta, transl_expr a = OK ta -> exists tv, Csharpminor.eval_expr tge te tle tm (make_boolean ta ty) tv /\ Val.bool_of_val tv b.
Lemma functions_translated: forall (v v': val) (f: Cminor.fundef) j, Genv.find_funct ge v = Some f -> val_inject j v v' -> globalfunction_ptr_inject j -> Genv.find_funct tge v' = Some (sel_fundef hf ge f).
Lemma sig_function_translated: forall f, funsig (sel_fundef hf ge f) = Cminor.funsig f.
Lemma varinfo_preserved: forall b, Genv.find_var_info tge b = Genv.find_var_info ge b.
Lemma helper_implements_preserved: forall id sg vargs vres, helper_implements ge id sg vargs vres -> helper_implements tge id sg vargs vres.
Lemma builtin_implements_preserved: forall id sg vargs vres, builtin_implements ge id sg vargs vres -> builtin_implements tge id sg vargs vres.
Lemma helpers_correct_preserved: forall h, i64_helpers_correct ge h -> i64_helpers_correct tge h.
Lemma eval_condexpr_of_expr: forall a le v b, eval_expr tge sp e m le a v -> Val.bool_of_val v b -> eval_condexpr tge sp e m le (condexpr_of_expr a) b.
Lemma eval_load: forall le a v chunk v', eval_expr tge sp e m le a v -> Mem.loadv chunk m v = Some v' -> eval_expr tge sp e m le (load chunk a) v'.
Lemma eval_coopstore: forall chunk a1 a2 v1 v2 f k m', eval_expr tge sp e m nil a1 v1 -> eval_expr tge sp e m nil a2 v2 -> Mem.storev chunk m v1 v2 = Some m' -> CMinSel_corestep tge (CMinSel_State f (store chunk a1 a2) k sp e) m (CMinSel_State f Sskip k sp e) m'.
Lemma eval_effstore: forall chunk a1 a2 v1 v2 f k m', eval_expr tge sp e m nil a1 v1 -> eval_expr tge sp e m nil a2 v2 -> Mem.storev chunk m v1 v2 = Some m' -> cminsel_effstep tge (StoreEffect v1 (encode_val chunk v2)) (CMinSel_State f (store chunk a1 a2) k sp e) m (CMinSel_State f Sskip k sp e) m'.
Lemma eval_sel_unop: forall le op a1 v1 v, eval_expr tge sp e m le a1 v1 -> eval_unop op v1 = Some v -> exists v', eval_expr tge sp e m le (sel_unop hf op a1) v' /\ Val.lessdef v v'.
Lemma eval_sel_binop: forall le op a1 a2 v1 v2 v, eval_expr tge sp e m le a1 v1 -> eval_expr tge sp e m le a2 v2 -> eval_binop op v1 v2 m = Some v -> exists v', eval_expr tge sp e m le (sel_binop hf op a1 a2) v' /\ Val.lessdef v v'.
Lemma expr_is_addrof_ident_correct: forall e id, expr_is_addrof_ident e = Some id -> e = Cminor.Econst (Cminor.Oaddrsymbol id Int.zero).
Lemma classify_call_correct: forall sp e m a v fd, Cminor.eval_expr ge sp e m a v -> Genv.find_funct ge v = Some fd -> match classify_call ge a with | Call_default => True | Call_imm id => exists b, Genv.find_symbol ge id = Some b /\ v = Vptr b Int.zero | Call_builtin ef => fd = External ef end.