denormals.h 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. // Denormals stripping.
  2. // These snippets should be common enough to be considered public domain.
  3. #ifndef DENORMALS_H
  4. #define DENORMALS_H
  5. #ifdef __SSE__
  6. #include <immintrin.h>
  7. #ifdef __GNUC__
  8. #include <x86intrin.h>
  9. #endif
  10. // Intel® 64 and IA-32 Architectures Software Developer’s Manual,
  11. // Volume 1: Basic Architecture,
  12. // 11.6.3 Checking for the DAZ Flag in the MXCSR Register
  13. int inline can_we_daz() {
  14. alignas(16) unsigned char buffer[512] = {0};
  15. #if defined(LMMS_HOST_X86)
  16. _fxsave(buffer);
  17. #elif defined(LMMS_HOST_X86_64)
  18. _fxsave64(buffer);
  19. #endif
  20. // Bit 6 of the MXCSR_MASK, i.e. in the lowest byte,
  21. // tells if we can use the DAZ flag.
  22. return ((buffer[28] & (1 << 6)) != 0);
  23. }
  24. #endif
  25. // Set denormal protection for this thread.
  26. void inline disable_denormals() {
  27. #ifdef __SSE__
  28. /* Setting DAZ might freeze systems not supporting it */
  29. if (can_we_daz()) {
  30. _MM_SET_DENORMALS_ZERO_MODE( _MM_DENORMALS_ZERO_ON );
  31. }
  32. /* FTZ flag */
  33. _MM_SET_FLUSH_ZERO_MODE( _MM_FLUSH_ZERO_ON );
  34. #endif
  35. }
  36. #endif