diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b68abaa..de0bee0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Since there is no stable release yet, the changes are organized per day in reverse chronological order. The main purpose of this document in its current state is to list breaking changes. -## [2024-02-23] +## [2025-02-23] ### Breaking changes diff --git a/src/wrapper/util.rs b/src/wrapper/util.rs index b1f99fb3..26040fb3 100644 --- a/src/wrapper/util.rs +++ b/src/wrapper/util.rs @@ -9,6 +9,15 @@ pub(crate) mod buffer_management; #[cfg(debug_assertions)] pub(crate) mod context_checks; +/// The bit that controls flush-to-zero behavior for denormals in 32 and 64-bit floating point +/// numbers on x86 family architectures. Rust 1.75 deprecated the built in functions for controlling +/// these registers. As listed in section 10.2.3.3 (Flush-To-Zero), bit 15 of the MXCSR register +/// controls the FTZ behavior. +/// +/// +#[cfg(target_feature = "sse")] +const SSE_FTZ_BIT: u32 = 1 << 15; + /// The bit that controls flush-to-zero behavior for denormals in 32 and 64-bit floating point /// numbers on AArch64. /// @@ -207,25 +216,16 @@ impl ScopedFtz { { #[cfg(target_feature = "sse")] { - const X86_FTZ_BIT: u32 = 1 << 15; + // Rust 1.75 deprecated `_mm_setcsr()` and `_MM_SET_FLUSH_ZERO_MODE()`, so this now + // requires inline assembly. See sections 10.2.3 (MXCSR Control and Status Register) + // and 10.2.3.3 (Flush-To-Zero) from this document for more details: + // + // let mut mxcsr: u32 = 0; - unsafe { - std::arch::asm!( - "stmxcsr [{p}]", - p = in(reg) &mut mxcsr, - options(nostack, preserves_flags), - ); - } - let should_disable_again = (mxcsr & X86_FTZ_BIT) == 0; + unsafe { std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr) }; + let should_disable_again = mxcsr & SSE_FTZ_BIT == 0; if should_disable_again { - let new_mxcsr = mxcsr | X86_FTZ_BIT; - unsafe { - std::arch::asm!( - "ldmxcsr [{p}]", - p = in(reg) &new_mxcsr, - options(nostack, preserves_flags), - ); - } + unsafe { std::arch::asm!("ldmxcsr [{}]", in(reg) &(mxcsr | SSE_FTZ_BIT)) }; } return Self { @@ -268,21 +268,9 @@ impl Drop for ScopedFtz { if self.should_disable_again { #[cfg(target_feature = "sse")] { - const X86_FTZ_BIT: u32 = 1 << 15; let mut mxcsr: u32 = 0; - unsafe { - std::arch::asm!( - "stmxcsr [{p}]", - p = in(reg) &mut mxcsr, - options(nostack, preserves_flags), - ); - let new_mxcsr = mxcsr & !X86_FTZ_BIT; - std::arch::asm!( - "ldmxcsr [{p}]", - p = in(reg) &new_mxcsr, - options(nostack, preserves_flags), - ); - } + unsafe { std::arch::asm!("stmxcsr [{}]", in(reg) &mut mxcsr) }; + unsafe { std::arch::asm!("ldmxcsr [{}]", in(reg) &(mxcsr & !SSE_FTZ_BIT)) }; } #[cfg(target_arch = "aarch64")]