FPControlWord.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Core/NonCopyable.h>
  5. namespace JPH {
  6. #ifdef JPH_USE_SSE
  7. /// Helper class that needs to be put on the stack to update the state of the floating point control word.
  8. /// This state is kept per thread.
  9. template <uint Value, uint Mask>
  10. class FPControlWord : public NonCopyable
  11. {
  12. public:
  13. FPControlWord()
  14. {
  15. mPrevState = _mm_getcsr();
  16. _mm_setcsr((mPrevState & ~Mask) | Value);
  17. }
  18. ~FPControlWord()
  19. {
  20. _mm_setcsr((_mm_getcsr() & ~Mask) | (mPrevState & Mask));
  21. }
  22. private:
  23. uint mPrevState;
  24. };
  25. #elif defined(JPH_USE_NEON)
  26. /// Helper class that needs to be put on the stack to update the state of the floating point control word.
  27. /// This state is kept per thread.
  28. template <uint64 Value, uint64 Mask>
  29. class FPControlWord : public NonCopyable
  30. {
  31. public:
  32. FPControlWord()
  33. {
  34. uint64 val;
  35. asm volatile("mrs %0, fpcr" : "=r" (val));
  36. mPrevState = val;
  37. val &= ~Mask;
  38. val |= Value;
  39. asm volatile("msr fpcr, %0" : /* no output */ : "r" (val));
  40. }
  41. ~FPControlWord()
  42. {
  43. uint64 val;
  44. asm volatile("mrs %0, fpcr" : "=r" (val));
  45. val &= ~Mask;
  46. val |= mPrevState & Mask;
  47. asm volatile("msr fpcr, %0" : /* no output */ : "r" (val));
  48. }
  49. private:
  50. uint64 mPrevState;
  51. };
  52. #else
  53. #error Unsupported CPU architecture
  54. #endif
  55. } // JPH