Definition denote_tc_assert' {CS: compspecs} (a: tc_assert) (rho: environ) : mpred.
pose (P := denote_tc_assert a rho).
unfold denote_tc_assert in P.
super_unfold_lift.
destruct a; apply P.
Defined.
Definition check_pp_int' e1 e2 op t e :=
match op with
| Cop.Oeq | Cop.One =>
tc_andp'
(tc_test_eq' e1 e2)
(tc_bool (is_int_type t) (op_result_type e))
| Cop.Ole | Cop.Olt | Cop.Oge | Cop.Ogt =>
tc_andp'
(tc_test_order' e1 e2)
(tc_bool (is_int_type t) (op_result_type e))
| _ => tc_noproof
end.
(* Definition check_pl_long' e2 op t e := match op with | Cop.Oeq | Cop.One => tc_andp' (tc_iszero' e2) (tc_bool (is_int_type t) (op_result_type e)) | _ => tc_noproof end. *)
Hint Rewrite @denote_tc_assert_andp' @denote_tc_assert_andp''
@denote_tc_assert_orp' @denote_tc_assert_orp''
@denote_tc_assert_iszero' @denote_tc_assert_nonzero'
@denote_tc_assert_nodivover' @denote_tc_assert_ilt' @denote_tc_assert_llt'
@denote_tc_assert_test_eq' @denote_tc_assert_test_order'
: dtca.
Ltac dtca := autorewrite with dtca; auto.
Definition stupid_typeconv ty :=
match ty with
| Tarray t _ a => Tpointer t a
| Tfunction _ _ _ => Tpointer ty noattr
| Tint _ _ _ => typeconv ty
| _ => ty
end.
Definition classify_sub' ty1 ty2 :=
match stupid_typeconv ty1 with
| Tpointer ty a =>
match stupid_typeconv ty2 with
| Tint _ si _ => sub_case_pi ty si
| Tlong _ _ => sub_case_pl ty
| Tpointer _ _ => sub_case_pp ty
| _ => sub_default
end
| _ => sub_default
end.
Definition classify_cmp' ty1 ty2 :=
match stupid_typeconv ty1, stupid_typeconv ty2 with
| Tpointer _ _ , Tpointer _ _ => cmp_case_pp
| Tpointer _ _ , Tint _ si _ => cmp_case_pi si
| Tint _ si _, Tpointer _ _ => cmp_case_ip si
| Tpointer _ _ , Tlong _ _ => cmp_case_pl
| Tlong _ _ , Tpointer _ _ => cmp_case_lp
| _, _ => cmp_default
end.
Definition classify_add' ty1 ty2 :=
match stupid_typeconv ty1 with
| Tint _ si _ =>
match stupid_typeconv ty2 with
| Tpointer ty a => add_case_ip si ty
|  _ => add_default
end
| Tlong _ _ =>
match stupid_typeconv ty2 with
| Tpointer ty a => add_case_lp ty
| _ => add_default
end
| Tpointer ty a =>
match stupid_typeconv ty2 with
| Tint _ si _ => add_case_pi ty si
| Tlong _ _ => add_case_pl ty
| _ => add_default
end
| _ => add_default
end.
Definition classify_shift' (ty1: type) (ty2: type) :=
match stupid_typeconv ty1, stupid_typeconv ty2 with
| Tint sz sg _, Tint _ _ _ => shift_case_ii
match sz, sg with
| I32, Unsigned => Unsigned
| _, _ => Signed
end
| Tint sz sg _, Tlong _ _ => shift_case_il
match sz, sg with
| I32, Unsigned => Unsigned
| _, _ => Signed
end
| Tlong s _, Tint _ _ _ => shift_case_li s
| Tlong s _, Tlong _ _ => shift_case_ll s
| _,_  => shift_default
end.
Definition classify_binarith' (ty1: type) (ty2: type) :=
match stupid_typeconv ty1, stupid_typeconv ty2 with
| Tint i1 s1 _, Tint i2 s2 _ => bin_case_i
match i1, s1, i2, s2 with
| I32, Unsigned, _, _ => Unsigned
| _, _, I32, Unsigned => Unsigned
| _, _, _, _ => Signed
end
| Tint _ _ _, Tlong s _ => bin_case_l s
| Tlong s _, Tint _ _ _ => bin_case_l s
| Tlong s1 _, Tlong s2 _ => bin_case_l
match s1, s2 with
| Signed, Signed => Signed
| _, _ => Unsigned
end
| Tfloat F32 _, Tfloat F32 _ => bin_case_s
| Tfloat _ _, Tfloat _ _ => bin_case_f
| Tfloat F64 _, (Tint _ _ _ | Tlong _ _) => bin_case_f
| (Tint _ _ _ | Tlong _ _), Tfloat F64 _ => bin_case_f
| Tfloat F32 _, (Tint _ _ _ | Tlong _ _) => bin_case_s
| (Tint _ _ _ | Tlong _ _), Tfloat F32 _ => bin_case_s
| _, _ => bin_default
end.
Definition binarithType' t1 t2 ty deferr reterr : tc_assert :=
match classify_binarith' t1 t2 with
| Cop.bin_case_i sg =>  tc_bool (is_int32_type ty) reterr
| Cop.bin_case_l sg => tc_bool (is_long_type ty) reterr
| Cop.bin_case_f   => tc_bool (is_float_type ty) reterr
| Cop.bin_case_s   => tc_bool (is_single_type ty) reterr
| Cop.bin_default => tc_FF deferr
end.
(* TODO: Improve this efficiency as well. *)
Definition tc_numeric_val (v: val) (t: type) : Prop :=
match v,t with
| Vint _, Tint _ _ _ => True
| Vlong _, Tlong _ _ => True
| Vfloat _, Tfloat F64 _ => True
| _, _ => False
end.

Lemma tc_val_sem_cmp:
forall op v1 t1 v2 t2 i3 s3 a3,
tc_numeric_val v1 t1 ->
tc_numeric_val v2 t2 ->
tc_val (Tint i3 s3 a3)
(force_val (Clight_Cop2.sem_cmp op t1 t2 v1 v2)).