summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMaarten ter Huurne <maarten@treewalker.org>2008-08-22 12:17:55 +0000
committerMaarten ter Huurne <maarten@treewalker.org>2008-08-22 12:17:55 +0000
commit292120453efb33fe9130a4fac8c2804b7adf61bb (patch)
treea8ef665a131591e1a27ba38252c58c1e03b6f4a1 /Source/Core
parent954ea6956b7e44e06c003360168659f932f134fb (diff)
Implemented FPU rounding control for 32-bit non-Windows platforms. I renamed the _RC_* constants that were previously #defined, because the bit patterns used by the hardware do not match those used by Windows; the new constants match the hardware.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@271 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp31
1 files changed, 23 insertions, 8 deletions
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 <float.h>
#ifdef _WIN32
#include <intrin.h>
-#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 <xmmintrin.h>
#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);