(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*          Sandrine Blazy, ENSIIE and INRIA Paris-Rocquencourt        *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** In-memory representation of values. *)
Require Archi.
(** * Properties of memory chunks *)
(** Memory reads and writes are performed by quantities called memory chunks, encoding the type, size and signedness of the chunk being addressed. The following functions extract the size information from a chunk. *)
Definition size_chunk (chunk: memory_chunk) : Z :=
match chunk with
| Mint8signed => 1
| Mint8unsigned => 1
| Mint16signed => 2
| Mint16unsigned => 2
| Mint32 => 4
| Mint64 => 8
| Mfloat32 => 4
| Mfloat64 => 8
| Many32 => 4
| Many64 => 8
end.
Definition size_chunk_nat (chunk: memory_chunk) : nat :=
Z.to_nat(size_chunk chunk).
(** Memory reads and writes must respect alignment constraints: the byte offset of the location being addressed should be an exact multiple of the natural alignment for the chunk being addressed. This natural alignment is defined by the following [align_chunk] function.  Some target architectures (e.g. PowerPC and x86) have no alignment constraints, which we could reflect by taking [align_chunk chunk = 1].  However, other architectures have stronger alignment requirements.  The following definition is appropriate for PowerPC, ARM and x86. *)
Definition align_chunk (chunk: memory_chunk) : Z :=
match chunk with
| Mint8signed => 1
| Mint8unsigned => 1
| Mint16signed => 2
| Mint16unsigned => 2
| Mint32 => 4
| Mint64 => 8
| Mfloat32 => 4
| Mfloat64 => 4
| Many32 => 4
| Many64 => 4
end.

Lemma align_le_divides:
forall chunk1 chunk2,
align_chunk chunk1 <= align_chunk chunk2 -> (align_chunk chunk1 | align_chunk chunk2).