Extend denormal protection through DAZ flag to all capable CPUs (#6167)

This commit is contained in:
Raine M. Ekman
2021-11-25 07:44:42 +02:00
committed by GitHub
parent eee1a81ff3
commit 6a716fa5fd

View File

@@ -4,27 +4,37 @@
#ifndef DENORMALS_H
#define DENORMALS_H
#ifdef __SSE__
#include <xmmintrin.h>
#endif
#ifdef __SSE3__
#include <pmmintrin.h>
#include <immintrin.h>
#ifdef __GNUC__
#include <x86intrin.h>
#endif
// Intel® 64 and IA-32 Architectures Software Developers Manual,
// Volume 1: Basic Architecture,
// 11.6.3 Checking for the DAZ Flag in the MXCSR Register
int inline can_we_daz() {
alignas(16) unsigned char buffer[512] = {0};
#if defined(LMMS_HOST_X86)
_fxsave(buffer);
#elif defined(LMMS_HOST_X86_64)
_fxsave64(buffer);
#endif
// Bit 6 of the MXCSR_MASK, i.e. in the lowest byte,
// tells if we can use the DAZ flag.
return ((buffer[28] & (1 << 6)) != 0);
}
#endif
// Set denormal protection for this thread.
// To be on the safe side, don't set the DAZ flag for SSE2 builds,
// even if most SSE2 CPUs can handle it.
void inline disable_denormals() {
#ifdef __SSE3__
/* DAZ flag */
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
#endif
#ifdef __SSE__
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
/* Setting DAZ might freeze systems not supporting it */
if (can_we_daz()) {
_MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
}
/* FTZ flag */
_MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
#endif
}