Section EVAL_BUILTIN_ARG_EV.
Variable A: Type.
Variable ge: Senv.t.
Variable e: A -> val.
Variable sp: val.
Variable m: mem.
Inductive eval_builtin_arg_ev: builtin_arg A -> val -> list mem_event -> Prop :=
| eval_BA_ev: forall x,
eval_builtin_arg_ev (BA x) (e x) nil
| eval_BA_ev_int: forall n,
eval_builtin_arg_ev (BA_int n) (Vint n) nil
| eval_BA_ev_long: forall n,
eval_builtin_arg_ev (BA_long n) (Vlong n) nil
| eval_BA_ev_float: forall n,
eval_builtin_arg_ev (BA_float n) (Vfloat n) nil
| eval_BA_ev_single: forall n,
eval_builtin_arg_ev (BA_single n) (Vsingle n) nil
| eval_BA_ev_loadstack: forall chunk ofs v b z bytes,
Mem.loadv chunk m (Val.offset_ptr sp ofs) = Some v ->
(align_chunk chunk | (Ptrofs.unsigned z)) ->
Mem.loadbytes m b (Ptrofs.unsigned z) (size_chunk chunk) = Some bytes ->
v= decode_val chunk bytes ->
Val.offset_ptr sp ofs = Vptr b z ->
eval_builtin_arg_ev (BA_loadstack chunk ofs) v [Read b (Ptrofs.unsigned z) (size_chunk chunk) bytes]
| eval_BA_ev_addrstack: forall ofs,
eval_builtin_arg_ev (BA_addrstack ofs) (Val.offset_ptr sp ofs) nil
| eval_BA_ev_loadglobal: forall chunk id ofs v b z bytes,
Mem.loadv chunk m (Senv.symbol_address ge id ofs) = Some v ->
(align_chunk chunk | (Ptrofs.unsigned z)) ->
Mem.loadbytes m b (Ptrofs.unsigned z) (size_chunk chunk) = Some bytes ->
v= decode_val chunk bytes ->
Senv.symbol_address ge id ofs = Vptr b z ->
eval_builtin_arg_ev (BA_loadglobal chunk id ofs) v [Read b (Ptrofs.unsigned z) (size_chunk chunk) bytes]
| eval_BA_ev_addrglobal: forall id ofs,
eval_builtin_arg_ev (BA_addrglobal id ofs) (Senv.symbol_address ge id ofs) nil
| eval_BA_ev_splitlong: forall hi lo vhi vlo Thi Tlo,
eval_builtin_arg_ev hi vhi Thi -> eval_builtin_arg_ev lo vlo Tlo->
eval_builtin_arg_ev (BA_splitlong hi lo) (Val.longofwords vhi vlo) (Thi++Tlo)
| eval_BA_ev_addptr: forall a1 a2 v1 v2 T1 T2,
eval_builtin_arg_ev a1 v1 T1 -> eval_builtin_arg_ev a2 v2 T2->
eval_builtin_arg_ev (BA_addptr a1 a2) (if Archi.ptr64 then Val.addl v1 v2 else Val.add v1 v2) (T1++T2).
End EVAL_BUILTIN_ARG_EV.
Definition option_list_to_list {A} (x: option (list A)) : list A :=
match x with Some al => al | None => nil end.
Inductive builtin_event: external_function -> mem -> list val -> list mem_event -> Prop :=
BE_malloc: forall m n m'' b m'
(ALLOC: Mem.alloc m (-size_chunk Mptr) (Ptrofs.unsigned n) = (m'', b))
(ALGN : (align_chunk Mptr | (-size_chunk Mptr)))
(ST: Mem.storebytes m'' b (-size_chunk Mptr) (encode_val Mptr (Vptrofs n)) = Some m'),
builtin_event EF_malloc m [Vptrofs n]
[Alloc b (-size_chunk Mptr) (Ptrofs.unsigned n);
Write b (-size_chunk Mptr) (encode_val Mptr (Vptrofs n))]
| BE_free: forall m b lo bytes sz m'
(POS: Ptrofs.unsigned sz > 0)
(LB : Mem.loadbytes m b (Ptrofs.unsigned lo - size_chunk Mptr) (size_chunk Mptr) = Some bytes)
(FR: Mem.free m b (Ptrofs.unsigned lo - size_chunk Mptr) (Ptrofs.unsigned lo + Ptrofs.unsigned sz) = Some m')
(ALGN : (align_chunk Mptr | Ptrofs.unsigned lo - size_chunk Mptr))
(SZ : Vptrofs sz = decode_val Mptr bytes),
builtin_event EF_free m [Vptr b lo]
[Read b (Ptrofs.unsigned lo - size_chunk Mptr) (size_chunk Mptr) bytes;
Free [(b,Ptrofs.unsigned lo - size_chunk Mptr, Ptrofs.unsigned lo + Ptrofs.unsigned sz)]]
| BE_memcpy: forall m al bsrc bdst sz bytes osrc odst m'
(AL: al = 1 \/ al = 2 \/ al = 4 \/ al = 8)
(POS : sz >= 0)
(DIV : (al | sz))
(OSRC : sz > 0 -> (al | Ptrofs.unsigned osrc))
(ODST: sz > 0 -> (al | Ptrofs.unsigned odst))
(RNG: bsrc <> bdst \/
Ptrofs.unsigned osrc = Ptrofs.unsigned odst \/
Ptrofs.unsigned osrc + sz <= Ptrofs.unsigned odst \/ Ptrofs.unsigned odst + sz <= Ptrofs.unsigned osrc)
(LB: Mem.loadbytes m bsrc (Ptrofs.unsigned osrc) sz = Some bytes)
(ST: Mem.storebytes m bdst (Ptrofs.unsigned odst) bytes = Some m'),
builtin_event (EF_memcpy sz al) m [Vptr bdst odst; Vptr bsrc osrc]
[Read bsrc (Ptrofs.unsigned osrc) sz bytes;
Write bdst (Ptrofs.unsigned odst) bytes]
(*| BE_EFexternal: forall name sg m vargs, (*        I64Helpers.is_I64_helperS name sg ->*)
builtin_event (EF_external name sg) m vargs []
| BE_EFbuiltin: forall name sg m vargs, (*is_I64_builtinS name sg ->*)
builtin_event (EF_builtin name sg) m vargs []*)
| BE_other: forall ef m vargs,
match ef with EF_malloc | EF_free | EF_memcpy _ _ => False | _ => True end ->
builtin_event ef m vargs [].

Lemma builtin_event_determ ef m vargs T1 (BE1: builtin_event ef m vargs T1) T2 (BE2: builtin_event ef m vargs T2): T1=T2.