Inductive val_content_inject (f: meminj): memory_chunk -> val -> val -> Prop :=
| val_content_inject_8_signed:
forall n1 n2, Int.sign_ext 8 n1 = Int.sign_ext 8 n2 ->
val_content_inject f Mint8signed (Vint n1) (Vint n2)
| val_content_inject_8_unsigned:
forall n1 n2, Int.zero_ext 8 n1 = Int.zero_ext 8 n2 ->
val_content_inject f Mint8unsigned (Vint n1) (Vint n2)
| val_content_inject_16_signed:
forall n1 n2, Int.sign_ext 16 n1 = Int.sign_ext 16 n2 ->
val_content_inject f Mint16signed (Vint n1) (Vint n2)
| val_content_inject_16_unsigned:
forall n1 n2, Int.zero_ext 16 n1 = Int.zero_ext 16 n2 ->
val_content_inject f Mint16unsigned (Vint n1) (Vint n2)
| val_content_inject_single:
forall n1 n2, Float.singleoffloat n1 = Float.singleoffloat n2 ->
val_content_inject f Mfloat32 (Vfloat n1) (Vfloat n2)
| val_content_inject_base:
forall chunk v1 v2, val_inject f v1 v2 ->
val_content_inject f chunk v1 v2.
Hint Resolve val_content_inject_base.

(* Specifications: *)
Lemma eval_store_arg:
forall f sp te tm a v va chunk,
eval_expr tge sp te tm a va ->
val_inject f v va ->
exists vb,
eval_expr tge sp te tm (store_arg chunk a) vb
/\ val_content_inject f chunk v vb.
Lemma storev_mapped_content_inject:
forall f chunk m1 a1 v1 n1 m2 a2 v2,
Mem.inject f m1 m2 ->
Mem.storev chunk m1 a1 v1 = Some n1 ->
val_inject f a1 a2 ->
val_content_inject f chunk v1 v2 ->
exists n2,
Mem.storev chunk m2 a2 v2 = Some n2 /\ Mem.inject f n1 n2.
Lemma make_store_correct:
forall f sp te tm addr tvaddr rhs tvrhs chunk m vaddr vrhs m' fn k,
eval_expr tge sp te tm addr tvaddr ->
eval_expr tge sp te tm rhs tvrhs ->
Mem.storev chunk m vaddr vrhs = Some m' ->
Mem.inject f m tm ->
val_inject f vaddr tvaddr ->
val_inject f vrhs tvrhs ->
exists tm', exists tvrhs',
step tge (State fn (make_store chunk addr rhs) k sp te tm)
E0 (State fn Sskip k sp te tm')
/\ Mem.storev chunk tm tvaddr tvrhs' = Some tm'
/\ Mem.inject f m' tm'.
Lemma eval_store_arg:
forall f sp te tm a v va chunk,
eval_expr tge sp te tm a va ->
val_inject f v va ->
exists vb,
eval_expr tge sp te tm (store_arg chunk a) vb
/\ val_content_inject f chunk v vb.
Lemma storev_mapped_content_inject:
forall f chunk m1 a1 v1 n1 m2 a2 v2,
Mem.inject f m1 m2 ->
Mem.storev chunk m1 a1 v1 = Some n1 ->
val_inject f a1 a2 ->
val_content_inject f chunk v1 v2 ->
exists n2,
Mem.storev chunk m2 a2 v2 = Some n2 /\ Mem.inject f n1 n2.
Lemma make_store_correct:
forall f sp te tm addr tvaddr rhs tvrhs chunk m vaddr vrhs m' fn k,
eval_expr tge sp te tm addr tvaddr ->
eval_expr tge sp te tm rhs tvrhs ->
Mem.storev chunk m vaddr vrhs = Some m' ->
Mem.inject f m tm ->
val_inject f vaddr tvaddr ->
val_inject f vrhs tvrhs ->
exists tm', exists tvrhs',
step tge (State fn (make_store chunk addr rhs) k sp te tm)
E0 (State fn Sskip k sp te tm')
/\ Mem.storev chunk tm tvaddr tvrhs' = Some tm'
/\ Mem.inject f m' tm'.