Module Wordsize_8.
Definition wordsize := 8%nat.
Remark wordsize_not_zero: wordsize <> 0%nat.
Remark int_ltu_2_inv:
forall y z,
Int.ltu y iwordsize' = true ->
Int.ltu z iwordsize' = true ->
Int.unsigned (Int.add y z) <= Int.unsigned iwordsize' ->
let y' := repr (Int.unsigned y) in
let z' := repr (Int.unsigned z) in
Int.unsigned y = unsigned y'
/\ Int.unsigned z = unsigned z'
/\ ltu y' iwordsize = true
/\ ltu z' iwordsize = true
/\ Int.unsigned (Int.add y z) = unsigned (add y' z')
/\ add y' z' = repr (Int.unsigned (Int.add y z)).
(** Powers of two with exponents given as 32-bit ints *)
Definition one_bits' (x: int) : list Int.int :=
List.map Int.repr (Z_one_bits wordsize (unsigned x) 0).
Definition is_power2' (x: int) : option Int.int :=
match Z_one_bits wordsize (unsigned x) 0 with
| i :: nil => Some (Int.repr i)
| _ => None
end.
Fixpoint int_of_one_bits' (l: list Int.int) : int :=
match l with
| nil => zero
| a :: b => add (shl' one a) (int_of_one_bits' b)
end.
(** Decomposing 64-bit ints as pairs of 32-bit ints *)
Definition loword (n: int) : Int.int := Int.repr (unsigned n).
Definition hiword (n: int) : Int.int := Int.repr (unsigned (shru n (repr Int.zwordsize))).
Definition ofwords (hi lo: Int.int) : int :=
or (shl (repr (Int.unsigned hi)) (repr Int.zwordsize)) (repr (Int.unsigned lo)).
Remark eqm_mul_2p32:
forall x y, Int.eqm x y -> eqm (x * two_p 32) (y * two_p 32).
(** Expressing 64-bit operations in terms of 32-bit operations *)

Lemma decompose_bitwise_binop:
forall f f64 f32 xh xl yh yl,
(forall x y i, 0 <= i < zwordsize -> testbit (f64 x y) i = f (testbit x i) (testbit y i)) ->
(forall x y i, 0 <= i < Int.zwordsize -> Int.testbit (f32 x y) i = f (Int.testbit x i) (Int.testbit y i)) ->
f64 (ofwords xh xl) (ofwords yh yl) = ofwords (f32 xh yh) (f32 xl yl).