Skip to content

Commit f6eef07

Browse files
committed
Revert "Eliminate the use of public_test_dep!"
[1] has not gone forward, so this needs to be reverted again in order to unblock a compiler-builtins upgrade that is necessary for the LLVM 20 upgrade. This reverts commit a2494f1. [1]: rust-lang/rust#135501
1 parent 6f96bcc commit f6eef07

File tree

8 files changed

+772
-763
lines changed

8 files changed

+772
-763
lines changed

src/float/mod.rs

+190-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
use core::ops;
2+
3+
use crate::int::{DInt, Int, MinInt};
4+
15
pub mod add;
26
pub mod cmp;
37
pub mod conv;
@@ -6,11 +10,192 @@ pub mod extend;
610
pub mod mul;
711
pub mod pow;
812
pub mod sub;
9-
pub(crate) mod traits;
1013
pub mod trunc;
1114

12-
#[cfg(not(feature = "public-test-deps"))]
13-
pub(crate) use traits::{Float, HalfRep};
15+
/// Wrapper to extract the integer type half of the float's size
16+
pub(crate) type HalfRep<F> = <<F as Float>::Int as DInt>::H;
17+
18+
public_test_dep! {
19+
/// Trait for some basic operations on floats
20+
#[allow(dead_code)]
21+
pub(crate) trait Float:
22+
Copy
23+
+ core::fmt::Debug
24+
+ PartialEq
25+
+ PartialOrd
26+
+ ops::AddAssign
27+
+ ops::MulAssign
28+
+ ops::Add<Output = Self>
29+
+ ops::Sub<Output = Self>
30+
+ ops::Div<Output = Self>
31+
+ ops::Rem<Output = Self>
32+
{
33+
/// A uint of the same width as the float
34+
type Int: Int<OtherSign = Self::SignedInt, UnsignedInt = Self::Int>;
35+
36+
/// A int of the same width as the float
37+
type SignedInt: Int + MinInt<OtherSign = Self::Int, UnsignedInt = Self::Int>;
38+
39+
/// An int capable of containing the exponent bits plus a sign bit. This is signed.
40+
type ExpInt: Int;
41+
42+
const ZERO: Self;
43+
const ONE: Self;
44+
45+
/// The bitwidth of the float type.
46+
const BITS: u32;
47+
48+
/// The bitwidth of the significand.
49+
const SIG_BITS: u32;
50+
51+
/// The bitwidth of the exponent.
52+
const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
53+
54+
/// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite
55+
/// representation.
56+
///
57+
/// This is in the rightmost position, use `EXP_MASK` for the shifted value.
58+
const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
59+
60+
/// The exponent bias value.
61+
const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
62+
63+
/// A mask for the sign bit.
64+
const SIGN_MASK: Self::Int;
65+
66+
/// A mask for the significand.
67+
const SIG_MASK: Self::Int;
68+
69+
/// The implicit bit of the float format.
70+
const IMPLICIT_BIT: Self::Int;
71+
72+
/// A mask for the exponent.
73+
const EXP_MASK: Self::Int;
74+
75+
/// Returns `self` transmuted to `Self::Int`
76+
fn to_bits(self) -> Self::Int;
77+
78+
/// Returns `self` transmuted to `Self::SignedInt`
79+
fn to_bits_signed(self) -> Self::SignedInt;
80+
81+
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
82+
/// represented in multiple different ways. This method returns `true` if two NaNs are
83+
/// compared.
84+
fn eq_repr(self, rhs: Self) -> bool;
85+
86+
/// Returns true if the sign is negative
87+
fn is_sign_negative(self) -> bool;
88+
89+
/// Returns the exponent, not adjusting for bias.
90+
fn exp(self) -> Self::ExpInt;
91+
92+
/// Returns the significand with no implicit bit (or the "fractional" part)
93+
fn frac(self) -> Self::Int;
94+
95+
/// Returns the significand with implicit bit
96+
fn imp_frac(self) -> Self::Int;
97+
98+
/// Returns a `Self::Int` transmuted back to `Self`
99+
fn from_bits(a: Self::Int) -> Self;
100+
101+
/// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
102+
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self;
103+
104+
fn abs(self) -> Self {
105+
let abs_mask = !Self::SIGN_MASK ;
106+
Self::from_bits(self.to_bits() & abs_mask)
107+
}
108+
109+
/// Returns (normalized exponent, normalized significand)
110+
fn normalize(significand: Self::Int) -> (i32, Self::Int);
111+
112+
/// Returns if `self` is subnormal
113+
fn is_subnormal(self) -> bool;
114+
}
115+
}
116+
117+
macro_rules! float_impl {
118+
($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => {
119+
impl Float for $ty {
120+
type Int = $ity;
121+
type SignedInt = $sity;
122+
type ExpInt = $expty;
123+
124+
const ZERO: Self = 0.0;
125+
const ONE: Self = 1.0;
126+
127+
const BITS: u32 = $bits;
128+
const SIG_BITS: u32 = $significand_bits;
129+
130+
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
131+
const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
132+
const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
133+
const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
134+
135+
fn to_bits(self) -> Self::Int {
136+
self.to_bits()
137+
}
138+
fn to_bits_signed(self) -> Self::SignedInt {
139+
self.to_bits() as Self::SignedInt
140+
}
141+
fn eq_repr(self, rhs: Self) -> bool {
142+
#[cfg(feature = "mangled-names")]
143+
fn is_nan(x: $ty) -> bool {
144+
// When using mangled-names, the "real" compiler-builtins might not have the
145+
// necessary builtin (__unordtf2) to test whether `f128` is NaN.
146+
// FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
147+
// x is NaN if all the bits of the exponent are set and the significand is non-0
148+
x.to_bits() & $ty::EXP_MASK == $ty::EXP_MASK && x.to_bits() & $ty::SIG_MASK != 0
149+
}
150+
#[cfg(not(feature = "mangled-names"))]
151+
fn is_nan(x: $ty) -> bool {
152+
x.is_nan()
153+
}
154+
if is_nan(self) && is_nan(rhs) {
155+
true
156+
} else {
157+
self.to_bits() == rhs.to_bits()
158+
}
159+
}
160+
fn is_sign_negative(self) -> bool {
161+
self.is_sign_negative()
162+
}
163+
fn exp(self) -> Self::ExpInt {
164+
((self.to_bits() & Self::EXP_MASK) >> Self::SIG_BITS) as Self::ExpInt
165+
}
166+
fn frac(self) -> Self::Int {
167+
self.to_bits() & Self::SIG_MASK
168+
}
169+
fn imp_frac(self) -> Self::Int {
170+
self.frac() | Self::IMPLICIT_BIT
171+
}
172+
fn from_bits(a: Self::Int) -> Self {
173+
Self::from_bits(a)
174+
}
175+
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self {
176+
Self::from_bits(
177+
((negative as Self::Int) << (Self::BITS - 1))
178+
| ((exponent << Self::SIG_BITS) & Self::EXP_MASK)
179+
| (significand & Self::SIG_MASK),
180+
)
181+
}
182+
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
183+
let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
184+
(
185+
1i32.wrapping_sub(shift as i32),
186+
significand << shift as Self::Int,
187+
)
188+
}
189+
fn is_subnormal(self) -> bool {
190+
(self.to_bits() & Self::EXP_MASK) == Self::Int::ZERO
191+
}
192+
}
193+
};
194+
}
14195

15-
#[cfg(feature = "public-test-deps")]
16-
pub use traits::{Float, HalfRep};
196+
#[cfg(f16_enabled)]
197+
float_impl!(f16, u16, i16, i8, 16, 10);
198+
float_impl!(f32, u32, i32, i16, 32, 23);
199+
float_impl!(f64, u64, i64, i16, 64, 52);
200+
#[cfg(f128_enabled)]
201+
float_impl!(f128, u128, i128, i16, 128, 112);

src/float/traits.rs

-189
This file was deleted.

0 commit comments

Comments
 (0)