(** * External functions *)
(** For most languages, the functions composing the program are either internal functions, defined within the language, or external functions, defined outside.  External functions include system calls but also compiler built-in functions.  We define a type for external functions and associated operations. *)
Inductive external_function : Type :=
| EF_external (name: string) (sg: signature)
(** A system call or library function.  Produces an event in the trace. *)
| EF_builtin (name: string) (sg: signature)
(** A compiler built-in function.  Behaves like an external, but can be inlined by the compiler. *)
| EF_runtime (name: string) (sg: signature)
(** A function from the run-time library.  Behaves like an external, but must not be redefined. *)
| EF_vload (chunk: memory_chunk)
(** A volatile read operation.  If the adress given as first argument points within a volatile global variable, generate an event and return the value found in this event.  Otherwise, produce no event and behave like a regular memory load. *)
| EF_vstore (chunk: memory_chunk)
(** A volatile store operation.   If the adress given as first argument points within a volatile global variable, generate an event. Otherwise, produce no event and behave like a regular memory store. *)
| EF_malloc
(** Dynamic memory allocation.  Takes the requested size in bytes as argument; returns a pointer to a fresh block of the given size. Produces no observable event. *)
| EF_free
(** Dynamic memory deallocation.  Takes a pointer to a block allocated by an [EF_malloc] external call and frees the corresponding block. Produces no observable event. *)
| EF_memcpy (sz: Z) (al: Z)
(** Block copy, of [sz] bytes, between addresses that are [al]-aligned. *)
| EF_annot (kind: positive) (text: string) (targs: list typ)
(** A programmer-supplied annotation.  Takes zero, one or several arguments, produces an event carrying the text and the values of these arguments, and returns no value. *)
| EF_annot_val (kind: positive) (text: string) (targ: typ)
(** Another form of annotation that takes one argument, produces an event carrying the text and the value of this argument, and returns the value of the argument. *)
| EF_inline_asm (text: string) (sg: signature) (clobbers: list string)
(** Inline [asm] statements.  Semantically, treated like an annotation with no parameters ([EF_annot text nil]).  To be used with caution, as it can invalidate the semantic preservation theorem.  Generated only if [-finline-asm] is given. *)
| EF_debug (kind: positive) (text: ident) (targs: list typ).
(** Transport debugging information from the front-end to the generated assembly.  Takes zero, one or several arguments like [EF_annot]. Unlike [EF_annot], produces no observable event. *)
(** The type signature of an external function. *)
Definition ef_sig (ef: external_function): signature :=
match ef with
| EF_external name sg => sg
| EF_builtin name sg => sg
| EF_runtime name sg => sg
| EF_vload chunk => mksignature (Tptr :: nil) (Some (type_of_chunk chunk)) cc_default
| EF_vstore chunk => mksignature (Tptr :: type_of_chunk chunk :: nil) None cc_default
| EF_malloc => mksignature (Tptr :: nil) (Some Tptr) cc_default
| EF_free => mksignature (Tptr :: nil) None cc_default
| EF_memcpy sz al => mksignature (Tptr :: Tptr :: nil) None cc_default
| EF_annot kind text targs => mksignature targs None cc_default
| EF_annot_val kind text targ => mksignature (targ :: nil) (Some targ) cc_default
| EF_inline_asm text sg clob => sg
| EF_debug kind text targs => mksignature targs None cc_default
end.
(** Whether an external function should be inlined by the compiler. *)
Definition ef_inline (ef: external_function) : bool :=
match ef with
| EF_external name sg => false
| EF_builtin name sg => true
| EF_runtime name sg => false
| EF_vload chunk => true
| EF_vstore chunk => true
| EF_malloc => false
| EF_free => false
| EF_memcpy sz al => true
| EF_annot kind text targs => true
| EF_annot_val kind Text rg => true
| EF_inline_asm text sg clob => true
| EF_debug kind text targs => true
end.
(** Whether an external function must reload its arguments. *)
Definition ef_reloads (ef: external_function) : bool :=
match ef with
| EF_annot kind text targs => false
| EF_debug kind text targs => false
| _ => true
end.
(** Equality between external functions.  Used in module [Allocation]. *)
Definition external_function_eq: forall (ef1 ef2: external_function), {ef1=ef2} + {ef1<>ef2}.

Lemma in_regs_of_rpairs_inv:
forall (A: Type) (x: A) l, In x (regs_of_rpairs l) -> exists p, In p l /\ In x (regs_of_rpair p).