summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLinesPrower <LinesPrower@gmail.com>2009-04-30 17:07:25 +0000
committerLinesPrower <LinesPrower@gmail.com>2009-04-30 17:07:25 +0000
commitee4de8a9b66dd2c94c538a884fb6590673ae29bc (patch)
tree668d3aaeb5292158eca1b7225305a42bbae408a8 /Source/Core
parent3917941ae1ed902897fd0f0e84be1dfc606dd793 (diff)
Try to fix problems caused by incorrect denormalized floats handling. Fixes issue 398 (Sonic Unleashed hanging)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3110 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp36
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp3
2 files changed, 38 insertions, 1 deletions
diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp
index e3f80cd9b6..8d5388b470 100644
--- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp
+++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp
@@ -135,15 +135,34 @@ void Helper_UpdateCR1(double _fValue)
PanicAlert("CR1");
}
-bool IsNAN(double _dValue)
+inline bool IsNAN(double _dValue)
{
return _dValue != _dValue;
}
+inline bool _IsNAN(float x) {
+ //return ((*(u32*)&x) & 0x7f800000UL) == 0x7f800000UL && ((*(u32*)&x) & 0x007fffffUL);
+ return x != x;
+}
+
void fcmpo(UGeckoInstruction _inst)
{
+ /*
+ float fa = static_cast<float>(rPS0(_inst.FA));
+ float fb = static_cast<float>(rPS0(_inst.FB));
+ // normalize
+ if (((*(u32*)&fa) & 0x7f800000UL) == 0) (*(u32*)&fa) &= 0x80000000UL;
+ if (((*(u32*)&fb) & 0x7f800000UL) == 0) (*(u32*)&fb) &= 0x80000000UL;
+ */
+
+ // normalize if conversion to float gives denormalized number
+ if ((riPS0(_inst.FA) & 0x7ff0000000000000ULL) < 0x3800000000000000ULL)
+ riPS0(_inst.FA) &= 0x8000000000000000ULL;
+ if ((riPS0(_inst.FB) & 0x7ff0000000000000ULL) < 0x3800000000000000ULL)
+ riPS0(_inst.FB) &= 0x8000000000000000ULL;
double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB);
+
u32 compareResult;
if (IsNAN(fa) || IsNAN(fb)) compareResult = 1;
else if (fa < fb) compareResult = 8;
@@ -164,6 +183,21 @@ void fcmpo(UGeckoInstruction _inst)
void fcmpu(UGeckoInstruction _inst)
{
+
+
+ /*
+ float fa = static_cast<float>(rPS0(_inst.FA));
+ float fb = static_cast<float>(rPS0(_inst.FB));
+ // normalize
+ if (((*(u32*)&fa) & 0x7f800000UL) == 0) (*(u32*)&fa) &= 0x80000000UL;
+ if (((*(u32*)&fb) & 0x7f800000UL) == 0) (*(u32*)&fb) &= 0x80000000UL;
+ */
+
+ // normalize if conversion to float gives denormalized number
+ if ((riPS0(_inst.FA) & 0x7ff0000000000000ULL) < 0x3800000000000000ULL)
+ riPS0(_inst.FA) &= 0x8000000000000000ULL;
+ if ((riPS0(_inst.FB) & 0x7ff0000000000000ULL) < 0x3800000000000000ULL)
+ riPS0(_inst.FB) &= 0x8000000000000000ULL;
double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp
index b3f1f4829e..30d3a749fb 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp
@@ -102,6 +102,9 @@
void Jit64::fcmpx(UGeckoInstruction inst)
{
+ // @TODO: conform this to the new fcmpo
+ Default(inst); return;
+
INSTRUCTION_START
JITDISABLE(FloatingPoint)
IREmitter::InstLoc lhs, rhs, res;