diff --git a/library/compiler-builtins/libm/src/math/support/float_traits.rs b/library/compiler-builtins/libm/src/math/support/float_traits.rs index 7b3f6904b9df..68ba600309a9 100644 --- a/library/compiler-builtins/libm/src/math/support/float_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs @@ -38,6 +38,7 @@ pub trait Float: const MAX: Self; const MIN: Self; const PI: Self; + const NEG_PI: Self; const FRAC_PI_2: Self; /// The bitwidth of the float type @@ -71,7 +72,9 @@ pub trait Float: fn to_bits(self) -> Self::Int; /// Returns `self` transmuted to `Self::SignedInt` - fn to_bits_signed(self) -> Self::SignedInt; + fn to_bits_signed(self) -> Self::SignedInt { + self.to_bits().signed() + } /// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be /// represented in multiple different ways. This method returns `true` if two NaNs are @@ -158,7 +161,15 @@ pub trait Float: pub type IntTy = ::Int; macro_rules! float_impl { - ($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => { + ( + $ty:ident, + $ity:ident, + $sity:ident, + $expty:ident, + $bits:expr, + $significand_bits:expr, + $from_bits:path + ) => { impl Float for $ty { type Int = $ity; type SignedInt = $sity; @@ -173,13 +184,10 @@ macro_rules! float_impl { const NAN: Self = Self::NAN; const MAX: Self = -Self::MIN; // Sign bit set, saturated mantissa, saturated exponent with last bit zeroed - // FIXME(msrv): just use `from_bits` when available - // SAFETY: POD cast with no preconditions - const MIN: Self = unsafe { - mem::transmute::(Self::Int::MAX & !(1 << Self::SIG_BITS)) - }; + const MIN: Self = $from_bits(Self::Int::MAX & !(1 << Self::SIG_BITS)); const PI: Self = core::$ty::consts::PI; + const NEG_PI: Self = -Self::PI; const FRAC_PI_2: Self = core::$ty::consts::FRAC_PI_2; const BITS: u32 = $bits; @@ -193,9 +201,6 @@ macro_rules! float_impl { fn to_bits(self) -> Self::Int { self.to_bits() } - fn to_bits_signed(self) -> Self::SignedInt { - self.to_bits() as Self::SignedInt - } fn is_nan(self) -> bool { self.is_nan() } @@ -220,8 +225,22 @@ macro_rules! float_impl { } #[cfg(f16_enabled)] -float_impl!(f16, u16, i16, i8, 16, 10); -float_impl!(f32, u32, i32, i16, 32, 23); -float_impl!(f64, u64, i64, i16, 64, 52); +float_impl!(f16, u16, i16, i8, 16, 10, f16::from_bits); +float_impl!(f32, u32, i32, i16, 32, 23, f32_from_bits); +float_impl!(f64, u64, i64, i16, 64, 52, f64_from_bits); #[cfg(f128_enabled)] -float_impl!(f128, u128, i128, i16, 128, 112); +float_impl!(f128, u128, i128, i16, 128, 112, f128::from_bits); + +/* FIXME(msrv): vendor some things that are not const stable at our MSRV */ + +/// `f32::from_bits` +pub const fn f32_from_bits(bits: u32) -> f32 { + // SAFETY: POD cast with no preconditions + unsafe { mem::transmute::(bits) } +} + +/// `f64::from_bits` +pub const fn f64_from_bits(bits: u64) -> f64 { + // SAFETY: POD cast with no preconditions + unsafe { mem::transmute::(bits) } +} diff --git a/library/compiler-builtins/libm/src/math/support/hex_float.rs b/library/compiler-builtins/libm/src/math/support/hex_float.rs index 80434a5ec3e9..1666c6153608 100644 --- a/library/compiler-builtins/libm/src/math/support/hex_float.rs +++ b/library/compiler-builtins/libm/src/math/support/hex_float.rs @@ -2,6 +2,8 @@ #![allow(dead_code)] // FIXME: remove once this gets used +use super::{f32_from_bits, f64_from_bits}; + /// Construct a 32-bit float from hex float representation (C-style) pub const fn hf32(s: &str) -> f32 { f32_from_bits(parse_any(s, 32, 23) as u32) @@ -159,16 +161,6 @@ const fn hex_digit(c: u8) -> u8 { /* FIXME(msrv): vendor some things that are not const stable at our MSRV */ -/// `f32::from_bits` -const fn f32_from_bits(v: u32) -> f32 { - unsafe { core::mem::transmute(v) } -} - -/// `f64::from_bits` -const fn f64_from_bits(v: u64) -> f64 { - unsafe { core::mem::transmute(v) } -} - /// `u128::ilog2` const fn u128_ilog2(v: u128) -> u32 { assert!(v != 0); diff --git a/library/compiler-builtins/libm/src/math/support/mod.rs b/library/compiler-builtins/libm/src/math/support/mod.rs index 25681c307da4..e2f4e0e981d6 100644 --- a/library/compiler-builtins/libm/src/math/support/mod.rs +++ b/library/compiler-builtins/libm/src/math/support/mod.rs @@ -6,6 +6,7 @@ mod int_traits; #[allow(unused_imports)] pub use float_traits::{Float, IntTy}; +pub(crate) use float_traits::{f32_from_bits, f64_from_bits}; #[allow(unused_imports)] pub use hex_float::{hf32, hf64}; pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt};