intros. rename H into N.
destruct H0. destruct H. destruct H. destruct H0.
unfold mapsto_,mapsto in H0.  unfold mapsto in *.
destruct (readable_share_dec sh) as [H2 | H2].
* (* readable_share sh *)
rename H2 into RS.
destruct (access_mode t); try solve [ inv H0].
destruct (type_is_volatile t) eqn:VOL; try contradiction.
assert (exists v,  address_mapsto m v sh (b, Ptrofs.unsigned o) x).
destruct H0.
econstructor; apply H0. destruct H0 as [_ [v2' H0]]; exists v2'; apply H0.
clear H0; destruct H2 as [x1 H0].
pose proof mapsto_core_load m x1 sh (b, Ptrofs.unsigned o) (m_phi jm).
destruct H2. simpl; eauto.
simpl in H2.
destruct H2.
specialize (H3 (b, Ptrofs.unsigned o)).
if_tac in H3.
destruct H3.  destruct H3.
rewrite valid_pointer_nonempty_perm.
unfold perm.
assert (JMA := juicy_mem_access jm (b, Ptrofs.unsigned o)).
unfold access_at in *. simpl in JMA.
unfold perm_of_res in *.
rewrite H3 in JMA. simpl in JMA.
unfold perm_of_sh in *.
rewrite JMA.
repeat if_tac; try constructor. subst.
simpl in H3.
contradiction.
destruct H4.  repeat split. omega.
destruct m; simpl; omega.
* (* ~ readable_share sh *)
destruct (access_mode t) eqn:?; try contradiction.
destruct (type_is_volatile t); [inversion H0 |].
destruct H0 as [_ [? _]].
specialize (H0 (b, Ptrofs.unsigned o)).
simpl in H0.
rewrite if_true in H0
by (split; auto; pose proof (size_chunk_pos m); omega).
clear H1.
pose proof (resource_at_join _ _ _ (b, Ptrofs.unsigned o) H).
unfold resource_share in H0.
rewrite <- (Z.add_0_r (Ptrofs.unsigned o)).
apply (valid_pointer_dry b o 0 jm).
hnf.
rewrite Z.add_0_r.
destruct H0.
destruct  (x @ (b, Ptrofs.unsigned o)); inv H0; inv H1; simpl; auto.
intro.
apply split_identity in RJ; auto.
Qed.

(* Specifications: *)
Lemma mapsto_is_pointer : forall sh t m v,
mapsto_ sh t v m ->
exists b, exists o, v = Vptr b o.
Lemma pointer_cmp_eval:
forall (Delta : tycontext) (cmp : Cop.binary_operation) (e1 e2 : expr) sh1 sh2,
is_comparison cmp = true ->
forall (jm : juicy_mem) (rho : environ),
(tc_expr Delta e1 rho) (m_phi jm) ->
(tc_expr Delta e2 rho) (m_phi jm) ->
blocks_match cmp (eval_expr e1 rho) (eval_expr e2 rho) ->
typecheck_environ Delta rho ->
nonidentity sh1 ->
nonidentity sh2 ->
(mapsto_ sh1 (typeof e1) (eval_expr e1 rho) * TT)%pred (m_phi jm) ->
(mapsto_ sh2 (typeof e2) (eval_expr e2 rho) * TT)%pred (m_phi jm) ->
eqb_type (typeof e1) int_or_ptr_type = false ->
eqb_type (typeof e2) int_or_ptr_type = false ->
Cop.sem_binary_operation cenv_cs cmp (eval_expr e1 rho)
(typeof e1) (eval_expr e2 rho) (typeof e2) (m_dry jm) =
Some
(force_val
(sem_binary_operation' cmp (typeof e1) (typeof e2)
(eval_expr e1 rho) (eval_expr e2 rho))).
Lemma is_int_of_bool:
forall i s b, is_int i s (Val.of_bool b).
Lemma pointer_cmp_no_mem_bool_type:
forall (Delta : tycontext) cmp (e1 e2 : expr) sh1 sh2 x1 x b1 o1 b2 o2 i3 s3,
is_comparison cmp = true->
eqb_type (typeof e1) int_or_ptr_type = false ->
eqb_type (typeof e2) int_or_ptr_type = false ->
forall (rho : environ) phi,
eval_expr e1 rho = Vptr b1 o1 ->
eval_expr e2 rho = Vptr b2 o2 ->
blocks_match cmp (eval_expr e1 rho) (eval_expr e2 rho) ->
denote_tc_assert (typecheck_expr Delta e1) rho phi ->
denote_tc_assert (typecheck_expr Delta e2) rho phi ->
(mapsto_ sh1 (typeof e1)
(eval_expr e1 rho)) x ->
(mapsto_ sh2 (typeof e2)
(eval_expr e2 rho)) x1 ->
typecheck_environ Delta rho ->
is_int i3 s3
(force_val
(sem_binary_operation' cmp (typeof e1) (typeof e2)
(eval_expr e1 rho)
(eval_expr e2 rho))).