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
This commit is contained in:
LinesPrower 2009-04-30 17:07:25 +00:00
parent 3917941ae1
commit ee4de8a9b6
2 changed files with 38 additions and 1 deletions

View File

@ -135,15 +135,34 @@ void Helper_UpdateCR1(double _fValue)
PanicAlert("CR1"); PanicAlert("CR1");
} }
bool IsNAN(double _dValue) inline bool IsNAN(double _dValue)
{ {
return _dValue != _dValue; return _dValue != _dValue;
} }
inline bool _IsNAN(float x) {
//return ((*(u32*)&x) & 0x7f800000UL) == 0x7f800000UL && ((*(u32*)&x) & 0x007fffffUL);
return x != x;
}
void fcmpo(UGeckoInstruction _inst) 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 fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB); double fb = rPS0(_inst.FB);
u32 compareResult; u32 compareResult;
if (IsNAN(fa) || IsNAN(fb)) compareResult = 1; if (IsNAN(fa) || IsNAN(fb)) compareResult = 1;
else if (fa < fb) compareResult = 8; else if (fa < fb) compareResult = 8;
@ -164,6 +183,21 @@ void fcmpo(UGeckoInstruction _inst)
void fcmpu(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 fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB); double fb = rPS0(_inst.FB);

View File

@ -102,6 +102,9 @@
void Jit64::fcmpx(UGeckoInstruction inst) void Jit64::fcmpx(UGeckoInstruction inst)
{ {
// @TODO: conform this to the new fcmpo
Default(inst); return;
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(FloatingPoint) JITDISABLE(FloatingPoint)
IREmitter::InstLoc lhs, rhs, res; IREmitter::InstLoc lhs, rhs, res;