@@ -9,6 +9,15 @@ pub(crate) mod buffer_management;
99#[ cfg( debug_assertions) ]
1010pub ( crate ) mod context_checks;
1111
12+ /// The bit that controls flush-to-zero behavior for denormals in 32 and 64-bit floating point
13+ /// numbers on x86 family architectures. Rust 1.75 deprecated the built in functions for controlling
14+ /// these registers. As listed in section 10.2.3.3 (Flush-To-Zero), bit 15 of the MXCSR register
15+ /// controls the FTZ behavior.
16+ ///
17+ /// <https://cdrdv2-public.intel.com/843823/252046-sdm-change-document-1.pdf>
18+ #[ cfg( target_feature = "sse" ) ]
19+ const SSE_FTZ_BIT : u32 = 1 << 15 ;
20+
1221/// The bit that controls flush-to-zero behavior for denormals in 32 and 64-bit floating point
1322/// numbers on AArch64.
1423///
@@ -207,25 +216,16 @@ impl ScopedFtz {
207216 {
208217 #[ cfg( target_feature = "sse" ) ]
209218 {
210- const X86_FTZ_BIT : u32 = 1 << 15 ;
219+ // Rust 1.75 deprecated `_mm_setcsr()` and `_MM_SET_FLUSH_ZERO_MODE()`, so this now
220+ // requires inline assembly. See sections 10.2.3 (MXCSR Control and Status Register)
221+ // and 10.2.3.3 (Flush-To-Zero) from this document for more details:
222+ //
223+ // <https://cdrdv2-public.intel.com/843823/252046-sdm-change-document-1.pdf>
211224 let mut mxcsr: u32 = 0 ;
212- unsafe {
213- std:: arch:: asm!(
214- "stmxcsr [{p}]" ,
215- p = in( reg) & mut mxcsr,
216- options( nostack, preserves_flags) ,
217- ) ;
218- }
219- let should_disable_again = ( mxcsr & X86_FTZ_BIT ) == 0 ;
225+ unsafe { std:: arch:: asm!( "stmxcsr [{}]" , in( reg) & mut mxcsr) } ;
226+ let should_disable_again = mxcsr & SSE_FTZ_BIT == 0 ;
220227 if should_disable_again {
221- let new_mxcsr = mxcsr | X86_FTZ_BIT ;
222- unsafe {
223- std:: arch:: asm!(
224- "ldmxcsr [{p}]" ,
225- p = in( reg) & new_mxcsr,
226- options( nostack, preserves_flags) ,
227- ) ;
228- }
228+ unsafe { std:: arch:: asm!( "ldmxcsr [{}]" , in( reg) & ( mxcsr | SSE_FTZ_BIT ) ) } ;
229229 }
230230
231231 return Self {
@@ -268,21 +268,9 @@ impl Drop for ScopedFtz {
268268 if self . should_disable_again {
269269 #[ cfg( target_feature = "sse" ) ]
270270 {
271- const X86_FTZ_BIT : u32 = 1 << 15 ;
272271 let mut mxcsr: u32 = 0 ;
273- unsafe {
274- std:: arch:: asm!(
275- "stmxcsr [{p}]" ,
276- p = in( reg) & mut mxcsr,
277- options( nostack, preserves_flags) ,
278- ) ;
279- let new_mxcsr = mxcsr & !X86_FTZ_BIT ;
280- std:: arch:: asm!(
281- "ldmxcsr [{p}]" ,
282- p = in( reg) & new_mxcsr,
283- options( nostack, preserves_flags) ,
284- ) ;
285- }
272+ unsafe { std:: arch:: asm!( "stmxcsr [{}]" , in( reg) & mut mxcsr) } ;
273+ unsafe { std:: arch:: asm!( "ldmxcsr [{}]" , in( reg) & ( mxcsr & !SSE_FTZ_BIT ) ) } ;
286274 }
287275
288276 #[ cfg( target_arch = "aarch64" ) ]
0 commit comments