PPCAnalyst: Apply "bitexact" analysis to fprIsSingle

This lets us set fprIsSingle to true in more cases.
This commit is contained in:
JosJuice 2021-05-15 16:28:36 +02:00
parent b3bceb2c11
commit 77afb0f4c3
1 changed files with 18 additions and 11 deletions

View File

@ -979,6 +979,18 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, std:
op.fprIsStoreSafeBeforeInst = fprIsStoreSafe;
if (op.fregOut >= 0)
{
BitSet32 bitexact_inputs;
if (op.opinfo->flags &
(FL_IN_FLOAT_A_BITEXACT | FL_IN_FLOAT_B_BITEXACT | FL_IN_FLOAT_C_BITEXACT))
{
if (op.opinfo->flags & FL_IN_FLOAT_A_BITEXACT)
bitexact_inputs[op.inst.FA] = true;
if (op.opinfo->flags & FL_IN_FLOAT_B_BITEXACT)
bitexact_inputs[op.inst.FB] = true;
if (op.opinfo->flags & FL_IN_FLOAT_C_BITEXACT)
bitexact_inputs[op.inst.FC] = true;
}
if (op.opinfo->type == OpType::SingleFP)
{
fprIsSingle[op.fregOut] = true;
@ -989,6 +1001,11 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, std:
fprIsSingle[op.fregOut] = true;
fprIsDuplicated[op.fregOut] = true;
}
else if (bitexact_inputs)
{
fprIsSingle[op.fregOut] = (fprIsSingle & bitexact_inputs) == bitexact_inputs;
fprIsDuplicated[op.fregOut] = false;
}
else if (op.opinfo->type == OpType::PS || op.opinfo->type == OpType::LoadPS)
{
fprIsSingle[op.fregOut] = true;
@ -1007,20 +1024,10 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, std:
// So, discard all information we have.
fprIsStoreSafe = BitSet32(0);
}
else if (op.opinfo->flags &
(FL_IN_FLOAT_A_BITEXACT | FL_IN_FLOAT_B_BITEXACT | FL_IN_FLOAT_C_BITEXACT))
else if (bitexact_inputs)
{
// If the instruction copies bits between registers (without flushing denormals to zero
// or turning SNaN into QNaN), the output is store-safe if the inputs are.
BitSet32 bitexact_inputs;
if (op.opinfo->flags & FL_IN_FLOAT_A_BITEXACT)
bitexact_inputs[op.inst.FA] = true;
if (op.opinfo->flags & FL_IN_FLOAT_B_BITEXACT)
bitexact_inputs[op.inst.FB] = true;
if (op.opinfo->flags & FL_IN_FLOAT_C_BITEXACT)
bitexact_inputs[op.inst.FC] = true;
fprIsStoreSafe[op.fregOut] = (fprIsStoreSafe & bitexact_inputs) == bitexact_inputs;
}
else