Require Import Coqlib.
Require Import Integers.
Require Import Values.
Require Import Lia.
Require ExtFloats.
Open Scope Z_scope.
Fixpoint pos_highest_bit (
x :
positive) (
already :
nat) :
nat :=
match x with
|
xH =>
already
|
xI x' |
xO x' =>
pos_highest_bit x' (
S already)
end.
Lemma pos_highest_bit_range :
forall x p (
RANGE : (
x <
Pos.of_nat (2^
p)%
nat)%
positive)
already,
(
already <=
pos_highest_bit x already <
already +
p)%
nat.
Proof.
induction x;
intros;
cbn.
all:
destruct p;
cbn in RANGE; [
lia|
idtac].
3:
lia.
all:
rewrite Nat.add_0_r in RANGE.
all:
replace (2^
p + 2^
p)%
nat with (2 * (2^
p))%
nat in RANGE by lia.
{
assert (
S already <=
pos_highest_bit x (
S already) <
S already +
p)%
nat.
{
apply IHx.
lia. }
lia.
}
{
assert (
S already <=
pos_highest_bit x (
S already) <
S already +
p)%
nat.
{
apply IHx.
lia. }
lia.
}
Qed.
Definition highest_bit x :=
match x with
|
Zpos x =>
Z.of_nat (
pos_highest_bit x O)
| _ => 0%
Z
end.
Definition int_highest_bit (
x :
int) :
Z :=
highest_bit (
Int.unsigned x).
Opaque Pos.pow Nat.pow.
Lemma int_highest_bit_range :
forall x, 0 <=
int_highest_bit x <= 31.
Proof.
Fixpoint pos_lowest_bit (
x :
positive) (
already :
nat) :
nat :=
match x with
|
xH |
xI _ =>
already
|
xO x' =>
pos_lowest_bit x' (
S already)
end.
Transparent Pos.pow Nat.pow.
Lemma pos_lowest_bit_range :
forall x p (
RANGE : (
x <
Pos.of_nat (2^
p)%
nat)%
positive)
already,
(
already <=
pos_lowest_bit x already <
already +
p)%
nat.
Proof.
induction x;
intros;
cbn.
all:
destruct p;
cbn in RANGE; [
lia|
idtac].
1,3:
lia.
rewrite Nat.add_0_r in RANGE.
replace (2^
p + 2^
p)%
nat with (2 * (2^
p))%
nat in RANGE by lia.
assert (
S already <=
pos_lowest_bit x (
S already) <
S already +
p)%
nat.
{
apply IHx.
lia. }
lia.
Qed.
Definition lowest_bit x :=
match x with
|
Zpos x =>
Z.of_nat (
pos_lowest_bit x O)
| _ => 0%
Z
end.
Definition int_lowest_bit (
x :
int) :
Z :=
lowest_bit (
Int.unsigned x).
Opaque Pos.pow Nat.pow.
Lemma int_lowest_bit_range :
forall x, 0 <=
int_lowest_bit x <= 31.
Proof.
Lemma pos_highest_bit_bigger:
forall x a, (
a <=
pos_highest_bit x a)%
nat.
Proof.
induction x;
cbn;
intros.
1,2:
pose proof (
IHx (
S a));
lia.
lia.
Qed.
Lemma pos_lowest_highest_bit:
forall x a, (
pos_lowest_bit x a <=
pos_highest_bit x a)%
nat.
Proof.
Lemma lowest_highest_bit:
forall n,
lowest_bit n <=
highest_bit n.
Proof.
Lemma int_lowest_highest_bit:
forall n,
ExtValues.int_lowest_bit n <=
ExtValues.int_highest_bit n.
Proof.
Definition is_bitfield lsb sz :=
(
Int.unsigned lsb) + (
Int.unsigned sz) <=? 32.
Definition bitfield_mask lsb sz :=
Int.shl (
Int.repr (
Z.ones (
Int.unsigned sz)))
lsb.
Lemma zero_ext_shru_and_bitfield_mask_zero:
forall lsb sz i,
Int.ltu lsb Int.iwordsize =
true ->
Int.eq (
Int.zero_ext (
Int.unsigned sz) (
Int.shru i lsb))
Int.zero =
Int.eq (
Int.and i (
bitfield_mask lsb sz))
Int.zero.
Proof.
Lemma sign_ext_eq_zero_iff_zero_ext_eq_zero:
forall sz x,
Int.eq (
Int.sign_ext sz x)
Int.zero =
Int.eq (
Int.zero_ext sz x)
Int.zero.
Proof.
Lemma sign_ext_shru_and_bitfield_mask_zero:
forall lsb sz i,
Int.ltu lsb Int.iwordsize =
true ->
Int.eq (
Int.sign_ext (
Int.unsigned sz) (
Int.shru i lsb))
Int.zero =
Int.eq (
Int.and i (
bitfield_mask lsb sz))
Int.zero.
Proof.
Definition insf lsb sz prev fld :=
let mask :=
Vint (
bitfield_mask lsb sz)
in
if is_bitfield lsb sz
then
Val.or (
Val.and prev (
Val.notint mask))
(
Val.and (
Val.shl fld (
Vint lsb))
mask)
else Vundef.
Definition clearf lsb sz prev :=
let mask :=
Vint (
bitfield_mask lsb sz)
in
if is_bitfield lsb sz
then Val.and prev (
Val.notint mask)
else Vundef.
Definition zbitfield_mask zstop zstart :=
Z.shiftl (
Z.ones (
Z.succ (
zstop -
zstart)))
zstart.
bswap32 on values, lifted from Int.bswap32. Used as the
semantics of Obswap32 and Prev so the lowering correctness is
by construction; identical to the OR-of-shifts chain produced by
the canonical C byte-swap idiom.
Definition val_bswap32 (
v :
val) :
val :=
match v with
|
Vint n =>
Vint (
Int.bswap32 n)
| _ =>
Vundef
end.
Definition fast_isfinitef1 (
x :
val) :=
let mask :=
Vint (
Int.repr ExtFloats.isfinitef1_mask)
in
Val.cmp_bool Cne (
Val.and (
Val.bits_of_single x)
mask)
mask.
Lemma fast_isfinitef1_correct:
forall x,
fast_isfinitef1 x =
Val.isfinitef x.
Proof.
Definition fast_isfinitef2 (
x :
val) :=
let mask :=
Vint (
Int.repr ExtFloats.isfinitef2_mask)
in
Val.cmp_bool Cne (
Val.zero_ext 8 (
Val.shru (
Val.bits_of_single x) (
Vint (
Int.repr 23))))
mask.
Lemma fast_isfinitef2_correct:
forall x,
fast_isfinitef2 x =
Val.isfinitef x.
Proof.
Definition fast_isfinite (
x :
val) :=
let mask :=
Vint (
Int.repr ExtFloats.isfinite_mask)
in
Val.cmp_bool Cne (
Val.zero_ext 11 (
Val.shru (
Val.hiword (
Val.bits_of_float x)) (
Vint (
Int.repr 20))))
mask.
Lemma fast_isfinite_correct:
forall x,
fast_isfinite x =
Val.isfinite x.
Proof.