1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29#include "PsFPU.h"
30
31#if !(defined(__CYGWIN__) || PX_ANDROID || PX_PS4)
32#include <fenv.h>
33PX_COMPILE_TIME_ASSERT(8 * sizeof(uint32_t) >= sizeof(fenv_t));
34#endif
35
36#if PX_OSX && !defined(PX_ARM_FAMILY)
37// osx defines SIMD as standard for floating point operations.
38#include <xmmintrin.h>
39#endif
40
41physx::shdfnd::FPUGuard::FPUGuard()
42{
43#if defined(__CYGWIN__)
44#pragma message "FPUGuard::FPUGuard() is not implemented"
45#elif PX_ANDROID
46// not supported unless ARM_HARD_FLOAT is enabled.
47#elif PX_PS4
48 // not supported
49 PX_UNUSED(mControlWords);
50#elif PX_OSX && !defined(PX_ARM_FAMILY)
51 mControlWords[0] = _mm_getcsr();
52 // set default (disable exceptions: _MM_MASK_MASK) and FTZ (_MM_FLUSH_ZERO_ON), DAZ (_MM_DENORMALS_ZERO_ON: (1<<6))
53 _mm_setcsr(_MM_MASK_MASK | _MM_FLUSH_ZERO_ON | (1 << 6));
54#elif defined(__EMSCRIPTEN__)
55// not supported
56#else
57 PX_COMPILE_TIME_ASSERT(sizeof(fenv_t) <= sizeof(mControlWords));
58
59 fegetenv(envp: reinterpret_cast<fenv_t*>(mControlWords));
60 fesetenv(FE_DFL_ENV);
61
62#if PX_LINUX && __GLIBC__
63 // need to explicitly disable exceptions because fesetenv does not modify
64 // the sse control word on 32bit linux (64bit is fine, but do it here just be sure)
65 fedisableexcept(FE_ALL_EXCEPT);
66#endif
67
68#endif
69}
70
71physx::shdfnd::FPUGuard::~FPUGuard()
72{
73#if defined(__CYGWIN__)
74#pragma message "FPUGuard::~FPUGuard() is not implemented"
75#elif PX_ANDROID
76// not supported unless ARM_HARD_FLOAT is enabled.
77#elif PX_PS4
78// not supported
79#elif PX_OSX && !defined(PX_ARM_FAMILY)
80 // restore control word and clear exception flags
81 // (setting exception state flags cause exceptions on the first following fp operation)
82 _mm_setcsr(mControlWords[0] & ~_MM_EXCEPT_MASK);
83#elif defined(__EMSCRIPTEN__)
84// not supported
85#else
86 fesetenv(envp: reinterpret_cast<fenv_t*>(mControlWords));
87#endif
88}
89
90PX_FOUNDATION_API void physx::shdfnd::enableFPExceptions()
91{
92#if (PX_LINUX && __GLIBC__) && !defined(__EMSCRIPTEN__)
93 feclearexcept(FE_ALL_EXCEPT);
94 feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW);
95#elif PX_OSX && !defined(PX_ARM_FAMILY)
96 // clear any pending exceptions
97 // (setting exception state flags cause exceptions on the first following fp operation)
98 uint32_t control = _mm_getcsr() & ~_MM_EXCEPT_MASK;
99
100 // enable all fp exceptions except inexact and underflow (common, benign)
101 // note: denorm has to be disabled as well because underflow can create denorms
102 _mm_setcsr((control & ~_MM_MASK_MASK) | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_DENORM);
103
104#endif
105}
106
107PX_FOUNDATION_API void physx::shdfnd::disableFPExceptions()
108{
109#if (PX_LINUX && __GLIBC__) && !defined(__EMSCRIPTEN__)
110 fedisableexcept(FE_ALL_EXCEPT);
111#elif PX_OSX && !defined(PX_ARM_FAMILY)
112 // clear any pending exceptions
113 // (setting exception state flags cause exceptions on the first following fp operation)
114 uint32_t control = _mm_getcsr() & ~_MM_EXCEPT_MASK;
115 _mm_setcsr(control | _MM_MASK_MASK);
116#endif
117}
118

source code of qtquick3dphysics/src/3rdparty/PhysX/source/foundation/src/unix/PsUnixFPU.cpp