Local Open Scope logic.
Definition  binary_operation_to_comparison (op: Cop.binary_operation) :=
match op with
| Cop.Oeq => Some (@eq Z)
| Cop.One => Some Zne
| Cop.Olt => Some Z.lt
| Cop.Ole => Some Z.le
| Cop.Ogt => Some Z.gt
| Cop.Oge => Some Z.ge
| _ => None
end.
(* Lemma typed_true_binop_int: forall op op' e1 e2 Espec  {cs: compspecs} Delta P Q R c Post, binary_operation_to_comparison op = Some op' -> typeof e1 = tint -> typeof e2 = tint -> (PROPx P (LOCALx (tc_env Delta :: Q) (SEPx R))) |--  tc_expr Delta e1 -> (PROPx P (LOCALx (tc_env Delta :: Q) (SEPx R))) |-- tc_expr Delta e2 -> @semax cs Espec Delta (PROPx P (LOCALx (`op' (`force_signed_int (eval_expr e1)) (`force_signed_int (eval_expr e2)) :: Q) (SEPx R))) c Post -> @semax cs Espec Delta (PROPx P (LOCALx (`(typed_true (typeof (Ebinop op e1 e2 tint))) (eval_expr (Ebinop op e1 e2 tint)) :: Q) (SEPx R))) c Post. *)
Definition  binary_operation_to_opp_comparison (op: Cop.binary_operation) :=
match op with
| Cop.Oeq => Some Zne
| Cop.One => Some (@eq Z)
| Cop.Olt => Some Z.ge
| Cop.Ole => Some Z.gt
| Cop.Ogt => Some Z.le
| Cop.Oge => Some Z.lt
| _ => None
end.
(* Lemma typed_false_binop_int: forall op op' e1 e2 Espec  {cs: compspecs} Delta P Q R c Post, binary_operation_to_opp_comparison op = Some op' -> typeof e1 = tint -> typeof e2 = tint -> (PROPx P (LOCALx (tc_environ Delta :: Q) (SEPx R))) |-- (tc_expr Delta e1) -> (PROPx P (LOCALx (tc_environ Delta :: Q) (SEPx R))) |-- (tc_expr Delta e2) -> @semax cs Espec Delta (PROPx P (LOCALx (`op' (`force_signed_int (eval_expr e1)) (`force_signed_int (eval_expr e2)) :: Q) (SEPx R))) c Post -> @semax cs Espec Delta (PROPx P (LOCALx (`(typed_false (typeof (Ebinop op e1 e2 tint))) (eval_expr (Ebinop op e1 e2 tint)) :: Q) (SEPx R))) c Post. *)
(* Ltac simplify_typed_comparison := match goal with | |- semax _ (PROPx _ (LOCALx (`(typed_true _) ?A :: _) _)) _ _ => (eapply typed_true_binop_int; [reflexivity | reflexivity | reflexivity | try solve [go_lowerx; apply prop_right; auto ] | try solve [go_lowerx; apply prop_right; auto ] | ]) || (let a := fresh "a" in set (a:=A); simpl in a; unfold a; clear a; eapply local_entail_at_semax_0; [ first [ apply typed_true_Oeq_nullval | apply typed_true_One_nullval ] |  ]) | |- semax _ (PROPx _ (LOCALx (`(typed_false _) ?A :: _) _)) _ _ => (eapply typed_false_binop_int; [reflexivity | reflexivity | reflexivity | try solve [go_lowerx; apply prop_right; auto ] | try solve [go_lowerx; apply prop_right; auto ] | ]) || let a := fresh "a" in set (a:=A); simpl in a; unfold a; clear a; eapply local_entail_at_semax_0; [ first [ apply typed_false_Oeq_nullval | apply typed_false_One_nullval ] |  ] | |- _ => idtac end. *)
Definition compare_pp op p q :=
match p with
| Vptr b z =>
match q with
| Vptr b' z' => if eq_block b b'
then Vint (if Ptrofs.cmpu op z z' then Int.one else Int.zero)
else Vundef
| _ => Vundef
end
| _ => Vundef
end.

Lemma force_sem_cmp_pp:
forall op p q,
isptr p -> isptr q ->
force_val (sem_cmp_pp op p q) =
match op with
| Ceq => Vint (if eq_dec p q then Int.one else Int.zero)
| Cne => Vint (if eq_dec p q then Int.zero else Int.one)
| _ => compare_pp op p q
end.