mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-22 16:25:39 +00:00
CPU/PGXP: Rewrite SLL handler
Shift flags as well as the values.
This commit is contained in:
parent
d4775e097e
commit
ef251d6147
|
@ -1328,41 +1328,43 @@ ALWAYS_INLINE_RELEASE void CPU::PGXP::CPU_SLL(Instruction instr, u32 rtVal, u32
|
||||||
{
|
{
|
||||||
const u32 rdVal = rtVal << sh;
|
const u32 rdVal = rtVal << sh;
|
||||||
PGXP_value& prtVal = ValidateAndGetRtValue(instr, rtVal);
|
PGXP_value& prtVal = ValidateAndGetRtValue(instr, rtVal);
|
||||||
|
PGXP_value& prdVal = GetRdValue(instr);
|
||||||
|
prdVal.z = prtVal.z;
|
||||||
|
prdVal.value = rdVal;
|
||||||
|
|
||||||
// TODO: Shift flags
|
if (sh >= 32) [[unlikely]]
|
||||||
double x = f16Unsign(prtVal.x);
|
|
||||||
double y = f16Unsign(prtVal.y);
|
|
||||||
if (sh >= 32)
|
|
||||||
{
|
{
|
||||||
x = 0.f;
|
prdVal.x = 0.0f;
|
||||||
y = 0.f;
|
prdVal.y = 0.0f;
|
||||||
|
prdVal.flags = prtVal.flags | VALID_XY | VALID_TAINTED_Z;
|
||||||
}
|
}
|
||||||
else if (sh == 16)
|
else if (sh == 16)
|
||||||
{
|
{
|
||||||
y = f16Sign(x);
|
prdVal.y = prtVal.x;
|
||||||
x = 0.f;
|
prdVal.x = 0.0f;
|
||||||
|
|
||||||
|
// Only set valid X if there's also a valid Y. We could use GetValidX() to pull it from the low precision value
|
||||||
|
// instead, need to investigate further. Spyro breaks if only X is set even if Y is not valid.
|
||||||
|
// prdVal.flags = (prtVal.flags & ~VALID_Y) | ((prtVal.flags & VALID_X) << 1) | VALID_X | VALID_TAINTED_Z;
|
||||||
|
prdVal.flags = (prtVal.flags | VALID_TAINTED_Z) | ((prtVal.flags & VALID_Y) >> 1);
|
||||||
}
|
}
|
||||||
else if (sh >= 16)
|
else if (sh >= 16)
|
||||||
{
|
{
|
||||||
y = x * static_cast<float>(1 << (sh - 16));
|
prdVal.y = static_cast<float>(f16Sign(f16Unsign(prtVal.x * static_cast<double>(1 << (sh - 16)))));
|
||||||
y = f16Sign(y);
|
prdVal.x = 0.0f;
|
||||||
x = 0.f;
|
|
||||||
|
// See above.
|
||||||
|
// prdVal.flags = (prtVal.flags & ~VALID_Y) | ((prtVal.flags & VALID_X) << 1) | VALID_X | VALID_TAINTED_Z;
|
||||||
|
prdVal.flags = (prtVal.flags | VALID_TAINTED_Z) | ((prtVal.flags & VALID_Y) >> 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
x = x * static_cast<float>(1 << sh);
|
const double x = f16Unsign(prtVal.x) * static_cast<double>(1 << sh);
|
||||||
y = y * static_cast<float>(1 << sh);
|
const double y = (f16Unsign(prtVal.y) * static_cast<double>(1 << sh)) + f16Overflow(x);
|
||||||
y += f16Overflow(x);
|
prdVal.x = static_cast<float>(f16Sign(x));
|
||||||
x = f16Sign(x);
|
prdVal.y = static_cast<float>(f16Sign(y));
|
||||||
y = f16Sign(y);
|
prdVal.flags = (prtVal.flags | VALID_TAINTED_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGXP_value& prdVal = GetRdValue(instr);
|
|
||||||
prdVal = prtVal;
|
|
||||||
prdVal.x = static_cast<float>(x);
|
|
||||||
prdVal.y = static_cast<float>(y);
|
|
||||||
prdVal.value = rdVal;
|
|
||||||
prdVal.flags |= VALID_TAINTED_Z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::PGXP::CPU_SLL(Instruction instr, u32 rtVal)
|
void CPU::PGXP::CPU_SLL(Instruction instr, u32 rtVal)
|
||||||
|
|
Loading…
Reference in a new issue