#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct FlushToZeroDenormalsAreZeroFlags {
original_flags: u32,
}
impl FlushToZeroDenormalsAreZeroFlags {
#[cfg(not(all(
not(feature = "enhanced-determinism"),
any(target_arch = "x86_64", target_arch = "x86"),
target_feature = "sse"
)))]
pub fn flush_denormal_to_zero() -> Self {
Self { original_flags: 0 }
}
#[cfg(all(
not(feature = "enhanced-determinism"),
any(target_arch = "x86", target_arch = "x86_64"),
target_feature = "sse"
))]
#[allow(deprecated)] pub fn flush_denormal_to_zero() -> Self {
unsafe {
#[cfg(target_arch = "x86")]
use std::arch::x86::{_MM_FLUSH_ZERO_ON, _mm_getcsr, _mm_setcsr};
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::{_MM_FLUSH_ZERO_ON, _mm_getcsr, _mm_setcsr};
let original_flags = _mm_getcsr();
_mm_setcsr(original_flags | _MM_FLUSH_ZERO_ON | (1 << 6));
Self { original_flags }
}
}
}
#[cfg(all(
not(feature = "enhanced-determinism"),
any(target_arch = "x86", target_arch = "x86_64"),
target_feature = "sse"
))]
impl Drop for FlushToZeroDenormalsAreZeroFlags {
#[allow(deprecated)] fn drop(&mut self) {
#[cfg(target_arch = "x86")]
unsafe {
std::arch::x86::_mm_setcsr(self.original_flags)
}
#[cfg(target_arch = "x86_64")]
unsafe {
std::arch::x86_64::_mm_setcsr(self.original_flags)
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct DisableFloatingPointExceptionsFlags {
#[cfg(feature = "debug-disable-legitimate-fe-exceptions")]
original_flags: [u8; 256],
}
#[cfg(feature = "debug-disable-legitimate-fe-exceptions")]
extern "C" {
fn feholdexcept(env: *mut std::ffi::c_void);
fn fesetenv(env: *const std::ffi::c_void);
}
impl DisableFloatingPointExceptionsFlags {
#[cfg(not(feature = "debug-disable-legitimate-fe-exceptions"))]
#[allow(dead_code)]
pub fn disable_floating_point_exceptions() -> Self {
Self {}
}
#[cfg(feature = "debug-disable-legitimate-fe-exceptions")]
pub fn disable_floating_point_exceptions() -> Self {
unsafe {
let mut original_flags = [0; 256];
feholdexcept(original_flags.as_mut_ptr() as *mut _);
Self { original_flags }
}
}
}
#[cfg(feature = "debug-disable-legitimate-fe-exceptions")]
impl Drop for DisableFloatingPointExceptionsFlags {
fn drop(&mut self) {
unsafe {
fesetenv(self.original_flags.as_ptr() as *const _);
}
}
}