Section SEMAX_SC.
Context {cs: compspecs}.
End SEMAX_SC.
(************************************************  The set, load, cast-load and store rules will be used in the future.  ************************************************)
Inductive Ptrofs_eqm_unsigned: ptrofs -> Z -> Prop :=
| Ptrofs_eqm_unsigned_repr: forall z, Ptrofs_eqm_unsigned (Ptrofs.repr z) z.
Ltac solve_Ptrofs_eqm_unsigned :=
solve
[ autorewrite with norm;
rewrite ?Ptrofs_repr_Int_unsigned_special by reflexivity;
rewrite ?Ptrofs_repr_Int64_unsigned_special by reflexivity;
match goal with
| |- Ptrofs_eqm_unsigned ?V _ =>
match V with
| Ptrofs.repr _ => idtac
| Ptrofs.sub _ _ => unfold Ptrofs.sub at 1
| Ptrofs.add _ _ => unfold Ptrofs.add at 1
| Ptrofs.mul _ _ => unfold Ptrofs.mul at 1
| Ptrofs.and _ _ => unfold Ptrofs.and at 1
| Ptrofs.or _ _ => unfold Ptrofs.or at 1
(*      | Int.shl _ _ => unfold Int.shl at 1 | Int.shr _ _ => unfold Int.shr at 1*)
| _ => rewrite <- (Ptrofs.repr_unsigned V) at 1
end
end;
rewrite ?ptrofs_unsigned_ofint64_repr by reflexivity;
apply Ptrofs_eqm_unsigned_repr
].
Inductive msubst_efield_denote {cs: compspecs} (Delta: tycontext) (T1: PTree.t val) (T2: PTree.t (type * val)) (GV: option globals): list efield -> list gfield -> Prop :=
| msubst_efield_denote_nil: msubst_efield_denote Delta T1 T2 GV nil nil
| msubst_efield_denote_cons_array: forall ei i i' efs gfs,
is_int_type (typeof ei) = true ->
msubst_eval_expr Delta T1 T2 GV  ei = Some (Vint i) ->
int_signed_or_unsigned (typeof ei) i = i' ->
msubst_efield_denote Delta T1 T2 GV efs gfs ->
msubst_efield_denote Delta T1 T2 GV (eArraySubsc ei :: efs) (ArraySubsc i' :: gfs)
| msubst_efield_denote_cons_array_ptrofs: forall ei i i' efs gfs,
is_ptrofs_type (typeof ei) = true ->
msubst_eval_expr Delta T1 T2 GV  ei = Some (Vptrofs i) ->
Ptrofs_eqm_unsigned i i' ->
msubst_efield_denote Delta T1 T2 GV efs gfs ->
msubst_efield_denote Delta T1 T2 GV (eArraySubsc ei :: efs) (ArraySubsc i' :: gfs)
| msubst_efield_denote_cons_struct: forall i efs gfs,
msubst_efield_denote Delta T1 T2 GV efs gfs ->
msubst_efield_denote Delta T1 T2 GV (eStructField i :: efs) (StructField i :: gfs)
| msubst_efield_denote_cons_union: forall i efs gfs,
msubst_efield_denote Delta T1 T2 GV efs gfs ->
msubst_efield_denote Delta T1 T2 GV (eUnionField i :: efs) (UnionField i :: gfs).

Lemma msubst_efield_denote_eq: forall {cs: compspecs} Delta P T1 T2 GV R efs gfs,
msubst_efield_denote Delta T1 T2 GV efs gfs ->
ENTAIL Delta, PROPx P (LOCALx (LocalD T1 T2 GV) (SEPx R)) |-- local (efield_denote efs gfs).