diff options
| author | LinesPrower <LinesPrower@gmail.com> | 2009-04-30 17:07:25 +0000 |
|---|---|---|
| committer | LinesPrower <LinesPrower@gmail.com> | 2009-04-30 17:07:25 +0000 |
| commit | ee4de8a9b66dd2c94c538a884fb6590673ae29bc (patch) | |
| tree | 668d3aaeb5292158eca1b7225305a42bbae408a8 /Source/Core | |
| parent | 3917941ae1ed902897fd0f0e84be1dfc606dd793 (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.cpp | 36 | ||||
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/Jit64IL/Jit_FloatingPoint.cpp | 3 |
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; |
