Interpreter: fix float conversions
Can't use simple casting, otherwise we get the same problems as in Jit64.
This commit is contained in:
parent
db196d8c5b
commit
f6897039c7
|
@ -231,3 +231,33 @@ inline u32 ConvertToSingleFTZ(u64 x)
|
|||
return (x >> 32) & 0x80000000;
|
||||
}
|
||||
}
|
||||
|
||||
inline u64 ConvertToDouble(u32 _x)
|
||||
{
|
||||
u64 x = _x;
|
||||
u64 exp = (x >> 23) & 0xff;
|
||||
u64 frac = x & 0x007fffff;
|
||||
if (exp || frac == 0)
|
||||
{
|
||||
// not denormalized
|
||||
u64 y = exp & 0x80;
|
||||
u64 z = y << 54 | y << 53 | y << 52;
|
||||
if (exp > 0 && exp < 255)
|
||||
{
|
||||
// not inf/nan/zero
|
||||
z = ~z;
|
||||
}
|
||||
return ((x & 0xc0000000) << 32) | z | ((x & 0x3fffffff) << 29);
|
||||
}
|
||||
else
|
||||
{
|
||||
// denormalized
|
||||
exp = 1023 - 126;
|
||||
do
|
||||
{
|
||||
frac <<= 1;
|
||||
exp -= 1;
|
||||
} while ((frac & 0x00800000) == 0);
|
||||
return ((x & 0x80000000) << 32) | (exp << 52) | ((frac & 0x007fffff) << 29);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,9 +93,9 @@ void Interpreter::lfs(UGeckoInstruction _inst)
|
|||
u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst));
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
double value = *(float*)&uTemp;
|
||||
rPS0(_inst.FD) = value;
|
||||
rPS1(_inst.FD) = value;
|
||||
u64 value = ConvertToDouble(uTemp);
|
||||
riPS0(_inst.FD) = value;
|
||||
riPS1(_inst.FD) = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,9 @@ void Interpreter::lfsu(UGeckoInstruction _inst)
|
|||
u32 uTemp = Memory::Read_U32(uAddress);
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
double value = *(float*)&uTemp;
|
||||
rPS0(_inst.FD) = value;
|
||||
rPS1(_inst.FD) = value;
|
||||
u64 value = ConvertToDouble(uTemp);
|
||||
riPS0(_inst.FD) = value;
|
||||
riPS1(_inst.FD) = value;
|
||||
m_GPR[_inst.RA] = uAddress;
|
||||
}
|
||||
|
||||
|
@ -119,9 +119,9 @@ void Interpreter::lfsux(UGeckoInstruction _inst)
|
|||
u32 uTemp = Memory::Read_U32(uAddress);
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
double value = *(float*)&uTemp;
|
||||
rPS0(_inst.FD) = value;
|
||||
rPS1(_inst.FD) = value;
|
||||
u64 value = ConvertToDouble(uTemp);
|
||||
riPS0(_inst.FD) = value;
|
||||
riPS1(_inst.FD) = value;
|
||||
m_GPR[_inst.RA] = uAddress;
|
||||
}
|
||||
}
|
||||
|
@ -131,9 +131,9 @@ void Interpreter::lfsx(UGeckoInstruction _inst)
|
|||
u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst));
|
||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||
{
|
||||
double value = *(float*)&uTemp;
|
||||
rPS0(_inst.FD) = value;
|
||||
rPS1(_inst.FD) = value;
|
||||
u64 value = ConvertToDouble(uTemp);
|
||||
riPS0(_inst.FD) = value;
|
||||
riPS1(_inst.FD) = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,9 +282,6 @@ void Interpreter::stfdu(UGeckoInstruction _inst)
|
|||
|
||||
void Interpreter::stfs(UGeckoInstruction _inst)
|
||||
{
|
||||
//double value = rPS0(_inst.FS);
|
||||
//float fTemp = (float)value;
|
||||
//Memory::Write_U32(*(u32*)&fTemp, Helper_Get_EA(_inst));
|
||||
Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_inst));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue