From ed762a3edace1782a69d3f15da45872ee69537d1 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Fri, 28 Mar 2014 19:06:12 +0100 Subject: [PATCH 1/2] x64FPURoundMode: use fesetround() instead of asm --- Source/Core/Common/x64FPURoundMode.cpp | 37 +++++++------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/Source/Core/Common/x64FPURoundMode.cpp b/Source/Core/Common/x64FPURoundMode.cpp index 5d5261346e..403473ab1a 100644 --- a/Source/Core/Common/x64FPURoundMode.cpp +++ b/Source/Core/Common/x64FPURoundMode.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#include + #include "Common/Common.h" #include "Common/CPUDetect.h" #include "Common/FPURoundMode.h" @@ -20,33 +22,14 @@ namespace FPURoundMode void SetRoundMode(int mode) { - // Set FPU rounding mode to mimic the PowerPC's - #ifdef _M_X86_32 - // 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 - }; - _set_controlfp(_MCW_RC, table[mode]); - #else - const unsigned short X87_ROUND_MASK = 3 << 10; - const unsigned short x87_rounding_table[] = - { - 0 << 10, // nearest - 3 << 10, // zero - 2 << 10, // +inf - 1 << 10, // -inf - }; - unsigned short _mode; - asm ("fstcw %0" : "=m" (_mode)); - _mode = (_mode & ~X87_ROUND_MASK) | x87_rounding_table[mode]; - asm ("fldcw %0" : : "m" (_mode)); - #endif - #endif + // Convert PowerPC to native rounding mode. + const int rounding_mode_lut[] = { + FE_TONEAREST, + FE_TOWARDZERO, + FE_UPWARD, + FE_DOWNWARD + }; + fesetround(rounding_mode_lut[mode]); } void SetPrecisionMode(PrecisionMode mode) From 9de77b7c23252cbedaee993f7c56b2deb0ce2bef Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Wed, 2 Apr 2014 01:49:56 +0200 Subject: [PATCH 2/2] x64FPURoundMode: always set x87 precision Set the x87 precision, even on x64. Since we are using x87 instructions in the JIT now, we can't guarantee that x87 precision will never influence Dolphin on x64. --- Source/Core/Common/x64FPURoundMode.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Source/Core/Common/x64FPURoundMode.cpp b/Source/Core/Common/x64FPURoundMode.cpp index 403473ab1a..1dd2fd18f0 100644 --- a/Source/Core/Common/x64FPURoundMode.cpp +++ b/Source/Core/Common/x64FPURoundMode.cpp @@ -34,10 +34,6 @@ namespace FPURoundMode void SetPrecisionMode(PrecisionMode mode) { - #ifdef _M_X86_32 - // sets the floating-point lib to 53-bit - // PowerPC has a 53bit floating pipeline only - // eg: sscanf is very sensitive #ifdef _WIN32 _control87(_PC_53, MCW_PC); #else @@ -47,14 +43,10 @@ namespace FPURoundMode 2 << 8, // 53 bits 3 << 8, // 64 bits }; - unsigned short _mode; - asm ("fstcw %0" : "=m" (_mode)); - _mode = (_mode & ~PRECISION_MASK) | precision_table[mode]; - asm ("fldcw %0" : : "m" (_mode)); - #endif - #else - //x64 doesn't need this - fpu is done with SSE - //but still - set any useful sse options here + unsigned short cw; + asm ("fnstcw %0" : "=m" (cw)); + cw = (cw & ~PRECISION_MASK) | precision_table[mode]; + asm ("fldcw %0" : : "m" (cw)); #endif }