(** ** Semantics of [memcpy] operations. *)
Inductive extcall_memcpy_sem (sz al: Z) (ge: Senv.t):
list val -> mem -> trace -> val -> mem -> Prop :=
| extcall_memcpy_sem_intro: forall bdst odst bsrc osrc m bytes m',
al = 1 \/ al = 2 \/ al = 4 \/ al = 8 -> sz >= 0 -> (al | sz) ->
(sz > 0 -> (al | Ptrofs.unsigned osrc)) ->
(sz > 0 -> (al | Ptrofs.unsigned odst)) ->
bsrc <> bdst \/ Ptrofs.unsigned osrc = Ptrofs.unsigned odst
\/ Ptrofs.unsigned osrc + sz <= Ptrofs.unsigned odst
\/ Ptrofs.unsigned odst + sz <= Ptrofs.unsigned osrc ->
Mem.loadbytes m bsrc (Ptrofs.unsigned osrc) sz = Some bytes ->
Mem.storebytes m bdst (Ptrofs.unsigned odst) bytes = Some m' ->
extcall_memcpy_sem sz al ge (Vptr bdst odst :: Vptr bsrc osrc :: nil) m E0 Vundef m'.

(* Specifications: *)
Lemma extcall_memcpy_ok:
forall sz al,
extcall_properties (extcall_memcpy_sem sz al)
(mksignature (Tptr :: Tptr :: nil) None cc_default).
Lemma extcall_memcpy_ok:
forall sz al,
extcall_properties (extcall_memcpy_sem sz al)
(mksignature (Tptr :: Tptr :: nil) None cc_default).