FPControlWord.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Jolt/Core/NonCopyable.h>
  5. JPH_NAMESPACE_BEGIN
  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_CPU_ARM) && defined(JPH_COMPILER_MSVC)
  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 <unsigned int Value, unsigned int Mask>
  29. class FPControlWord : public NonCopyable
  30. {
  31. public:
  32. FPControlWord()
  33. {
  34. // Read state before change
  35. _controlfp_s(&mPrevState, 0, 0);
  36. // Update the state
  37. unsigned int dummy;
  38. _controlfp_s(&dummy, Value, Mask);
  39. }
  40. ~FPControlWord()
  41. {
  42. // Restore state
  43. unsigned int dummy;
  44. _controlfp_s(&dummy, mPrevState, Mask);
  45. }
  46. private:
  47. unsigned int mPrevState;
  48. };
  49. #elif defined(JPH_CPU_ARM)
  50. /// Helper class that needs to be put on the stack to update the state of the floating point control word.
  51. /// This state is kept per thread.
  52. template <uint64 Value, uint64 Mask>
  53. class FPControlWord : public NonCopyable
  54. {
  55. public:
  56. FPControlWord()
  57. {
  58. uint64 val;
  59. asm volatile("mrs %0, fpcr" : "=r" (val));
  60. mPrevState = val;
  61. val &= ~Mask;
  62. val |= Value;
  63. asm volatile("msr fpcr, %0" : /* no output */ : "r" (val));
  64. }
  65. ~FPControlWord()
  66. {
  67. uint64 val;
  68. asm volatile("mrs %0, fpcr" : "=r" (val));
  69. val &= ~Mask;
  70. val |= mPrevState & Mask;
  71. asm volatile("msr fpcr, %0" : /* no output */ : "r" (val));
  72. }
  73. private:
  74. uint64 mPrevState;
  75. };
  76. #elif defined(JPH_CPU_WASM)
  77. // Not supported
  78. #else
  79. #error Unsupported CPU architecture
  80. #endif
  81. JPH_NAMESPACE_END