(** ** Access modes *)
(** The [access_mode] function describes how a l-value of the given type must be accessed: - [By_value ch]: access by value, i.e. by loading from the address of the l-value using the memory chunk [ch]; - [By_reference]: access by reference, i.e. by just returning the address of the l-value (used for arrays and functions); - [By_copy]: access is by reference, assignment is by copy (used for [struct] and [union] types) - [By_nothing]: no access is possible, e.g. for the [void] type. *)
Inductive mode: Type :=
| By_value: memory_chunk -> mode
| By_reference: mode
| By_copy: mode
| By_nothing: mode.
Definition access_mode (ty: type) : mode :=
match ty with
| Tint I8 Signed _ => By_value Mint8signed
| Tint I8 Unsigned _ => By_value Mint8unsigned
| Tint I16 Signed _ => By_value Mint16signed
| Tint I16 Unsigned _ => By_value Mint16unsigned
| Tint I32 _ _ => By_value Mint32
| Tint IBool _ _ => By_value Mint8unsigned
| Tlong _ _ => By_value Mint64
| Tfloat F32 _ => By_value Mfloat32
| Tfloat F64 _ => By_value Mfloat64
| Tvoid => By_nothing
| Tpointer _ _ => By_value Mptr
| Tarray _ _ _ => By_reference
| Tfunction _ _ _ => By_reference
| Tstruct _ _ => By_copy
| Tunion _ _ => By_copy
end.
(** For the purposes of the semantics and the compiler, a type denotes a volatile access if it carries the [volatile] attribute and it is accessed by value. *)
Definition type_is_volatile (ty: type) : bool :=
match access_mode ty with
| By_value _ => attr_volatile (attr_of_type ty)
| _          => false
end.
(** ** Alignment for block copy operations *)
(** A variant of [alignof] for use in block copy operations. Block copy operations do not support alignments greater than 8, and require the size to be an integral multiple of the alignment. *)
Fixpoint alignof_blockcopy (env: composite_env) (t: type) : Z :=
match t with
| Tvoid => 1
| Tint I8 _ _ => 1
| Tint I16 _ _ => 2
| Tint I32 _ _ => 4
| Tint IBool _ _ => 1
| Tlong _ _ => 8
| Tfloat F32 _ => 4
| Tfloat F64 _ => 8
| Tpointer _ _ => if Archi.ptr64 then 8 else 4
| Tarray t' _ _ => alignof_blockcopy env t'
| Tfunction _ _ _ => 1
| Tstruct id _ | Tunion id _ =>
match env!id with
| Some co => Z.min 8 (co_alignof co)
| None => 1
end
end.

(* Specifications: *)
Lemma alignof_blockcopy_1248:
forall env ty, let a := alignof_blockcopy env ty in a = 1 \/ a = 2 \/ a = 4 \/ a = 8.
Lemma alignof_blockcopy_pos:
forall env ty, alignof_blockcopy env ty > 0.
Lemma sizeof_alignof_blockcopy_compat:
forall env ty, (alignof_blockcopy env ty | sizeof env ty).
Lemma alignof_blockcopy_1248:
forall env ty, let a := alignof_blockcopy env ty in a = 1 \/ a = 2 \/ a = 4 \/ a = 8.
Lemma alignof_blockcopy_pos:
forall env ty, alignof_blockcopy env ty > 0.
Lemma sizeof_alignof_blockcopy_compat:
forall env ty, (alignof_blockcopy env ty | sizeof env ty).