Corollary xor_interval:
  forall a b, 0 <= unsigned (xor a b) < two_p (Z.max (size a) (size b)).Definition wordsize := 32%nat.Remark wordsize_not_zero: wordsize <> 0%nat.Module Int := Make(Wordsize_32).Notation int := Int.int.Remark int_wordsize_divides_modulus:
  Z.divide (Z.of_nat Int.wordsize) Int.modulus.Definition wordsize := 8%nat.Remark wordsize_not_zero: wordsize <> 0%nat.Module Byte := Make(Wordsize_8).Notation byte := Byte.int.Definition wordsize := 64%nat.Remark wordsize_not_zero: wordsize <> 0%nat.(** Shifts with amount given as a 32-bit integer *)

Definition iwordsize': Int.int := Int.repr zwordsize.Definition shl' (x: int) (y: Int.int): int :=
  repr (Z.shiftl (unsigned x) (Int.unsigned y)).Definition shru' (x: int) (y: Int.int): int :=
  repr (Z.shiftr (unsigned x) (Int.unsigned y)).Definition shr' (x: int) (y: Int.int): int :=
  repr (Z.shiftr (signed x) (Int.unsigned y)).Definition rol' (x: int) (y: Int.int): int :=
  rol x (repr (Int.unsigned y)).Definition shrx' (x: int) (y: Int.int): int :=
  divs x (shl' one y).Definition shr_carry' (x: int) (y: Int.int): int :=
  if lt x zero && negb (eq (and x (sub (shl' one y) one)) zero)
  then one else zero.

(* Specifications: *)
Lemma bits_shl': forall x y i, 0 <= i < zwordsize -> testbit (shl' x y) i = if zlt i (Int.unsigned y) then false else testbit x (i - Int.unsigned y).
Lemma bits_shru': forall x y i, 0 <= i < zwordsize -> testbit (shru' x y) i = if zlt (i + Int.unsigned y) zwordsize then testbit x (i + Int.unsigned y) else false.
Lemma bits_shr': forall x y i, 0 <= i < zwordsize -> testbit (shr' x y) i = testbit x (if zlt (i + Int.unsigned y) zwordsize then i + Int.unsigned y else zwordsize - 1).
Lemma shl'_mul_two_p: forall x y, shl' x y = mul x (repr (two_p (Int.unsigned y))).
Lemma shl'_one_two_p: forall y, shl' one y = repr (two_p (Int.unsigned y)).
Theorem shl'_mul: forall x y, shl' x y = mul x (shl' one y).
Theorem shl'_zero: forall x, shl' x Int.zero = x.
Theorem shru'_zero : forall x, shru' x Int.zero = x.
Theorem shr'_zero : forall x, shr' x Int.zero = x.
Theorem shrx'_zero: forall x, shrx' x Int.zero = x.
Theorem shrx'_carry: forall x y, Int.ltu y (Int.repr 63) = true -> shrx' x y = add (shr' x y) (shr_carry' x y).
Theorem shrx'_shr_2: forall x y, Int.ltu y (Int.repr 63) = true -> shrx' x y = shr' (add x (shru' (shr' x (Int.repr 63)) (Int.sub (Int.repr 64) y))) y.
Lemma bits_shl': forall x y i, 0 <= i < zwordsize -> testbit (shl' x y) i = if zlt i (Int.unsigned y) then false else testbit x (i - Int.unsigned y).
Lemma bits_shru': forall x y i, 0 <= i < zwordsize -> testbit (shru' x y) i = if zlt (i + Int.unsigned y) zwordsize then testbit x (i + Int.unsigned y) else false.
Lemma bits_shr': forall x y i, 0 <= i < zwordsize -> testbit (shr' x y) i = testbit x (if zlt (i + Int.unsigned y) zwordsize then i + Int.unsigned y else zwordsize - 1).
Lemma shl'_mul_two_p: forall x y, shl' x y = mul x (repr (two_p (Int.unsigned y))).
Lemma shl'_one_two_p: forall y, shl' one y = repr (two_p (Int.unsigned y)).
Theorem shl'_mul: forall x y, shl' x y = mul x (shl' one y).
Theorem shl'_zero: forall x, shl' x Int.zero = x.
Theorem shru'_zero : forall x, shru' x Int.zero = x.
Theorem shr'_zero : forall x, shr' x Int.zero = x.
Theorem shrx'_zero: forall x, shrx' x Int.zero = x.
Theorem shrx'_carry: forall x y, Int.ltu y (Int.repr 63) = true -> shrx' x y = add (shr' x y) (shr_carry' x y).
Theorem shrx'_shr_2: forall x y, Int.ltu y (Int.repr 63) = true -> shrx' x y = shr' (add x (shru' (shr' x (Int.repr 63)) (Int.sub (Int.repr 64) y))) y.