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:
parent
3917941ae1
commit
ee4de8a9b6
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue