Interpreter: Fix psq_l with QUANTIZE_FLOAT.

psq_l with QUANTIZE_FLOAT does not use the FPU, so it does not trim the precision of the u32 input data.
We already have the helper ConvertToDouble for floating point u32->u64 convertion used in lfs, so let's use it here as well.
This commit is contained in:
degasus 2019-04-11 09:40:05 +02:00
parent 849ede9d0a
commit 399768c91b
1 changed files with 11 additions and 10 deletions

View File

@ -226,7 +226,7 @@ static void Helper_Quantize(const PowerPC::PowerPCState* ppcs, u32 addr, u32 ins
} }
template <typename T> template <typename T>
std::pair<float, float> LoadAndDequantize(u32 addr, u32 instW, u32 ldScale) std::pair<double, double> LoadAndDequantize(u32 addr, u32 instW, u32 ldScale)
{ {
using U = std::make_unsigned_t<T>; using U = std::make_unsigned_t<T>;
@ -243,7 +243,8 @@ std::pair<float, float> LoadAndDequantize(u32 addr, u32 instW, u32 ldScale)
ps0 = (float)(T)(value.first) * m_dequantizeTable[ldScale]; ps0 = (float)(T)(value.first) * m_dequantizeTable[ldScale];
ps1 = (float)(T)(value.second) * m_dequantizeTable[ldScale]; ps1 = (float)(T)(value.second) * m_dequantizeTable[ldScale];
} }
return {ps0, ps1}; // ps0 and ps1 always contain finite and normal numbers. So we can just cast them to double
return {static_cast<double>(ps0), static_cast<double>(ps1)};
} }
static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, u32 instRD, static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, u32 instRD,
@ -253,8 +254,8 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
EQuantizeType ldType = gqr.ld_type; EQuantizeType ldType = gqr.ld_type;
unsigned int ldScale = gqr.ld_scale; unsigned int ldScale = gqr.ld_scale;
float ps0 = 0.0f; double ps0 = 0.0;
float ps1 = 0.0f; double ps1 = 0.0;
switch (ldType) switch (ldType)
{ {
@ -262,14 +263,14 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
if (instW) if (instW)
{ {
const u32 value = ReadUnpaired<u32>(addr); const u32 value = ReadUnpaired<u32>(addr);
ps0 = Common::BitCast<float>(value); ps0 = Common::BitCast<double>(ConvertToDouble(value));
ps1 = 1.0f; ps1 = 1.0;
} }
else else
{ {
const std::pair<u32, u32> value = ReadPair<u32>(addr); const std::pair<u32, u32> value = ReadPair<u32>(addr);
ps0 = Common::BitCast<float>(value.first); ps0 = Common::BitCast<double>(ConvertToDouble(value.first));
ps1 = Common::BitCast<float>(value.second); ps1 = Common::BitCast<double>(ConvertToDouble(value.second));
} }
break; break;
@ -293,8 +294,8 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI,
case QUANTIZE_INVALID2: case QUANTIZE_INVALID2:
case QUANTIZE_INVALID3: case QUANTIZE_INVALID3:
ASSERT_MSG(POWERPC, 0, "PS dequantize - unknown type to read"); ASSERT_MSG(POWERPC, 0, "PS dequantize - unknown type to read");
ps0 = 0.f; ps0 = 0.0;
ps1 = 0.f; ps1 = 0.0;
break; break;
} }