// However, std can't simply compare to zero to check for zero, either,
// as correctness requires avoiding equality tests that may be Subnormal == -0.0
// because it may be wrong under "denormals are zero" and "flush to zero" modes.
- // Most of std's targets don't use those, but they are used for thumbv7neon".
+ // Most of std's targets don't use those, but they are used for thumbv7neon.
// So, this does use bitpattern matching for the rest.
// SAFETY: f64 to u64 is fine. Usually.
FpCategory::Subnormal => {
panic!("const-eval error: cannot use f64::to_bits on a subnormal number")
}
- FpCategory::Infinite =>
- // SAFETY: Infinity per se is fine
- unsafe { mem::transmute::<f64, u64>(ct) },
- FpCategory::Zero | FpCategory::Normal => {
+ FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => {
// SAFETY: We have a normal floating point number. Now we transmute, i.e. do a bitcopy.
- let bits: u64 = unsafe { mem::transmute::<f64, u64>(ct) };
- // Let's doublecheck to make sure it wasn't a weird float by truncating it.
- if (bits >> 52) & 0x7FF == 0x7FF {
- panic!(
- "const-eval error: an unusually large x87 floating point value should not leak into const eval"
- )
- };
- bits
+ unsafe { mem::transmute::<f64, u64>(ct) }
}
}
}
// ...sorta.
//
// It turns out that at runtime, it is possible for a floating point number
- // to be subject to floating point modes that alters nonzero subnormal numbers
+ // to be subject to floating point modes that alter nonzero subnormal numbers
// to zero on reads and writes, aka "denormals are zero" and "flush to zero".
// This is not a problem usually, but at least one tier2 platform for Rust
- // actually exhibits an FTZ behavior kby default: thumbv7neon
+ // actually exhibits an FTZ behavior by default: thumbv7neon
// aka "the Neon FPU in AArch32 state"
//
// Even with this, not all instructions exhibit the FTZ behaviors on thumbv7neon,
const fn ct_u64_to_f64(ct: u64) -> f64 {
match f64::classify_bits(ct) {
FpCategory::Subnormal => {
- panic!("const-eval error: cannot use f64::from_bits on a subnormal number");
+ panic!("const-eval error: cannot use f64::from_bits on a subnormal number")
}
FpCategory::Nan => {
- panic!("const-eval error: cannot use f64::from_bits on NaN");
+ panic!("const-eval error: cannot use f64::from_bits on NaN")
+ }
+ FpCategory::Infinite | FpCategory::Normal | FpCategory::Zero => {
+ // SAFETY: It's not a frumious number
+ unsafe { mem::transmute::<u64, f64>(ct) }
}
- // SAFETY: It's not a frumious number
- _ => unsafe { mem::transmute::<u64, f64>(ct) },
}
}
// SAFETY: `u64` is a plain old datatype so we can always... uh...