(** ** Properties related to [loadbytes] *)

(* Specifications: *)
Theorem range_perm_loadbytes:
forall m b ofs len,
range_perm m b ofs (ofs + len) Cur Readable ->
exists bytes, loadbytes m b ofs len = Some bytes.
Theorem loadbytes_range_perm:
forall m b ofs len bytes,
loadbytes m b ofs len = Some bytes ->
range_perm m b ofs (ofs + len) Cur Readable.
Theorem loadbytes_load:
forall chunk m b ofs bytes,
loadbytes m b ofs (size_chunk chunk) = Some bytes ->
(align_chunk chunk | ofs) ->
load chunk m b ofs = Some(decode_val chunk bytes).
Theorem load_loadbytes:
forall chunk m b ofs v,
load chunk m b ofs = Some v ->
exists bytes, loadbytes m b ofs (size_chunk chunk) = Some bytes
/\ v = decode_val chunk bytes.
Lemma getN_length:
forall c n p, length (getN n p c) = n.
Theorem loadbytes_length:
forall m b ofs n bytes,
loadbytes m b ofs n = Some bytes ->
length bytes = nat_of_Z n.
Theorem loadbytes_empty:
forall m b ofs n,
n <= 0 -> loadbytes m b ofs n = Some nil.
Lemma getN_concat:
forall c n1 n2 p,
getN (n1 + n2)%nat p c = getN n1 p c ++ getN n2 (p + Z.of_nat n1) c.
Theorem loadbytes_concat:
forall m b ofs n1 n2 bytes1 bytes2,
loadbytes m b ofs n1 = Some bytes1 ->
loadbytes m b (ofs + n1) n2 = Some bytes2 ->
n1 >= 0 -> n2 >= 0 ->
loadbytes m b ofs (n1 + n2) = Some(bytes1 ++ bytes2).
Theorem loadbytes_split:
forall m b ofs n1 n2 bytes,
loadbytes m b ofs (n1 + n2) = Some bytes ->
n1 >= 0 -> n2 >= 0 ->
exists bytes1, exists bytes2,
loadbytes m b ofs n1 = Some bytes1
/\ loadbytes m b (ofs + n1) n2 = Some bytes2
/\ bytes = bytes1 ++ bytes2.
Theorem load_rep:
forall ch m1 m2 b ofs v1 v2,
(forall z, 0 <= z < size_chunk ch -> ZMap.get (ofs + z) m1.(mem_contents)#b = ZMap.get (ofs + z) m2.(mem_contents)#b) ->
load ch m1 b ofs = Some v1 ->
load ch m2 b ofs = Some v2 ->
v1 = v2.
Theorem load_int64_split:
forall m b ofs v,
load Mint64 m b ofs = Some v -> Archi.ptr64 = false ->
exists v1 v2,
load Mint32 m b ofs = Some (if Archi.big_endian then v1 else v2)
/\ load Mint32 m b (ofs + 4) = Some (if Archi.big_endian then v2 else v1)
/\ Val.lessdef v (Val.longofwords v1 v2).
Lemma addressing_int64_split:
forall i,
Archi.ptr64 = false ->
(8 | Ptrofs.unsigned i) ->
Ptrofs.unsigned (Ptrofs.add i (Ptrofs.of_int (Int.repr 4))) = Ptrofs.unsigned i + 4.
Theorem loadv_int64_split:
forall m a v,
loadv Mint64 m a = Some v -> Archi.ptr64 = false ->
exists v1 v2,
loadv Mint32 m a = Some (if Archi.big_endian then v1 else v2)
/\ loadv Mint32 m (Val.add a (Vint (Int.repr 4))) = Some (if Archi.big_endian then v2 else v1)
/\ Val.lessdef v (Val.longofwords v1 v2).
Theorem range_perm_loadbytes:
forall m b ofs len,
range_perm m b ofs (ofs + len) Cur Readable ->
exists bytes, loadbytes m b ofs len = Some bytes.
Theorem loadbytes_range_perm:
forall m b ofs len bytes,
loadbytes m b ofs len = Some bytes ->
range_perm m b ofs (ofs + len) Cur Readable.
Theorem loadbytes_load:
forall chunk m b ofs bytes,
loadbytes m b ofs (size_chunk chunk) = Some bytes ->
(align_chunk chunk | ofs) ->
load chunk m b ofs = Some(decode_val chunk bytes).
Theorem load_loadbytes:
forall chunk m b ofs v,
load chunk m b ofs = Some v ->
exists bytes, loadbytes m b ofs (size_chunk chunk) = Some bytes
/\ v = decode_val chunk bytes.
Lemma getN_length:
forall c n p, length (getN n p c) = n.
Theorem loadbytes_length:
forall m b ofs n bytes,
loadbytes m b ofs n = Some bytes ->
length bytes = nat_of_Z n.
Theorem loadbytes_empty:
forall m b ofs n,
n <= 0 -> loadbytes m b ofs n = Some nil.
Lemma getN_concat:
forall c n1 n2 p,
getN (n1 + n2)%nat p c = getN n1 p c ++ getN n2 (p + Z.of_nat n1) c.
Theorem loadbytes_concat:
forall m b ofs n1 n2 bytes1 bytes2,
loadbytes m b ofs n1 = Some bytes1 ->
loadbytes m b (ofs + n1) n2 = Some bytes2 ->
n1 >= 0 -> n2 >= 0 ->
loadbytes m b ofs (n1 + n2) = Some(bytes1 ++ bytes2).
Theorem loadbytes_split:
forall m b ofs n1 n2 bytes,
loadbytes m b ofs (n1 + n2) = Some bytes ->
n1 >= 0 -> n2 >= 0 ->
exists bytes1, exists bytes2,
loadbytes m b ofs n1 = Some bytes1
/\ loadbytes m b (ofs + n1) n2 = Some bytes2
/\ bytes = bytes1 ++ bytes2.
Theorem load_rep:
forall ch m1 m2 b ofs v1 v2,
(forall z, 0 <= z < size_chunk ch -> ZMap.get (ofs + z) m1.(mem_contents)#b = ZMap.get (ofs + z) m2.(mem_contents)#b) ->
load ch m1 b ofs = Some v1 ->
load ch m2 b ofs = Some v2 ->
v1 = v2.
Theorem load_int64_split:
forall m b ofs v,
load Mint64 m b ofs = Some v -> Archi.ptr64 = false ->
exists v1 v2,
load Mint32 m b ofs = Some (if Archi.big_endian then v1 else v2)
/\ load Mint32 m b (ofs + 4) = Some (if Archi.big_endian then v2 else v1)
/\ Val.lessdef v (Val.longofwords v1 v2).
Lemma addressing_int64_split:
forall i,
Archi.ptr64 = false ->
(8 | Ptrofs.unsigned i) ->
Ptrofs.unsigned (Ptrofs.add i (Ptrofs.of_int (Int.repr 4))) = Ptrofs.unsigned i + 4.
Theorem loadv_int64_split:
forall m a v,
loadv Mint64 m a = Some v -> Archi.ptr64 = false ->
exists v1 v2,
loadv Mint32 m a = Some (if Archi.big_endian then v1 else v2)
/\ loadv Mint32 m (Val.add a (Vint (Int.repr 4))) = Some (if Archi.big_endian then v2 else v1)
/\ Val.lessdef v (Val.longofwords v1 v2).