From d3a6de3f867fc617190de317c26ed599e9e2c88d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 29 Sep 2011 05:10:15 -0700 Subject: [PATCH] Set the FPU into single-precision mode for mixer updates --- CMakeLists.txt | 1 + OpenAL32/Include/alMain.h | 4 ++++ OpenAL32/Include/alu.h | 28 ++++++++++++++++++++-------- config.h.in | 3 +++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f4902bb..14492387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,6 +215,7 @@ CHECK_C_SOURCE_COMPILES("int foo(const char *str, ...) __attribute__((format(pri int main() {return 0;}" HAVE_GCC_FORMAT) CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H) +CHECK_INCLUDE_FILE(fpu_control.h HAVE_FPU_CONTROL_H) CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H) CHECK_INCLUDE_FILE(ieeefp.h HAVE_IEEEFP_H) CHECK_INCLUDE_FILE(guiddef.h HAVE_GUIDDEF_H) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 88478a88..f69ea967 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -9,6 +9,10 @@ #include #endif +#ifdef HAVE_FPU_CONTROL_H +#include +#endif + #include "AL/al.h" #include "AL/alc.h" #include "AL/alext.h" diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 6c09d32f..bd00e86d 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -198,23 +198,35 @@ static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat static __inline int SetMixerFPUMode(void) { - int fpuState = 0; -#if defined(HAVE_FESETROUND) +#if defined(_FPU_GETCW) && defined(_FPU_SETCW) + fpu_control_t fpuState, newState; + _FPU_GETCW(fpuState); + newState = fpuState&~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE | + _FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO); + newState |= _FPU_SINGLE | _FPU_RC_ZERO; + _FPU_SETCW(newState); +#else + int fpuState; +#if defined(HAVE__CONTROLFP) + fpuState = _controlfp(0, 0); + (void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC); +#elif defined(HAVE_FESETROUND) fpuState = fegetround(); fesetround(FE_TOWARDZERO); -#elif defined(HAVE__CONTROLFP) - fpuState = _controlfp(0, 0); - (void)_controlfp(_RC_CHOP, _MCW_RC); +#endif #endif return fpuState; } static __inline void RestoreFPUMode(int state) { -#if defined(HAVE_FESETROUND) - fesetround(state); +#if defined(_FPU_GETCW) && defined(_FPU_SETCW) + fpu_control_t fpuState = state; + _FPU_SETCW(fpuState); #elif defined(HAVE__CONTROLFP) - _controlfp(state, _MCW_RC); + _controlfp(state, _MCW_RC|_MCW_PC); +#elif defined(HAVE_FESETROUND) + fesetround(state); #endif } diff --git a/config.h.in b/config.h.in index 3cafe8d2..54bc9672 100644 --- a/config.h.in +++ b/config.h.in @@ -119,6 +119,9 @@ /* Define if we have float.h */ #cmakedefine HAVE_FLOAT_H +/* Define if we have fpu_control.h */ +#cmakedefine HAVE_FPU_CONTROL_H + /* Define if we have fenv.h */ #cmakedefine HAVE_FENV_H -- 2.11.4.GIT