diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 73d23191eb..b71b8c32ba 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -18,11 +18,12 @@ #include #ifdef _WIN32 #include -#else -#define _RC_NEAR (0<<10) -#define _RC_DOWN (1<<10) -#define _RC_UP (2<<10) -#define _RC_CHOP (3<<10) +#else +static const unsigned short FPU_ROUND_NEAR = 0 << 10; +static const unsigned short FPU_ROUND_DOWN = 1 << 10; +static const unsigned short FPU_ROUND_UP = 2 << 10; +static const unsigned short FPU_ROUND_CHOP = 3 << 10; +static const unsigned short FPU_ROUND_MASK = 3 << 10; #include #endif @@ -73,15 +74,29 @@ void UpdateFPSCR(UReg_FPSCR fp) // Set FPU rounding mode to mimic the PowerPC's int round = fp.RN; #ifdef _M_IX86 + // This shouldn't really be needed anymore since we use SSE +#ifdef _WIN32 const int table[4] = { _RC_NEAR, _RC_CHOP, _RC_UP, _RC_DOWN - }; - // This shouldn't really be needed anymore since we use SSE - _set_controlfp(_MCW_RC, table[round]); + }; + _set_controlfp(_MCW_RC, table[round]); +#else + const unsigned short table[4] = + { + FPU_ROUND_NEAR, + FPU_ROUND_CHOP, + FPU_ROUND_UP, + FPU_ROUND_DOWN + }; + unsigned short mode; + asm ("fstcw %0" : : "m" (mode)); + mode = (mode & ~FPU_ROUND_MASK) | table[round]; + asm ("fldcw %0" : : "m" (mode)); +#endif #endif // Also corresponding SSE rounding mode setting UpdateSSEState(round, fp.NI ? true : false);