Merge pull request #12811 from JosJuice/ppcanalyst-refactor-mtspr

PPCAnalyst: Refactor mtspr handling code
This commit is contained in:
JosJuice 2024-08-11 15:33:46 +02:00 committed by GitHub
commit 6cc2133f27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 22 deletions

View File

@ -202,21 +202,27 @@ static void AnalyzeFunction2(PPCSymbolDB* func_db, Common::Symbol* func)
func->flags = flags;
}
static bool IsMfspr(UGeckoInstruction inst)
{
return inst.OPCD == 31 && inst.SUBOP10 == 339;
}
static bool IsMtspr(UGeckoInstruction inst)
{
return inst.OPCD == 31 && inst.SUBOP10 == 467;
}
static bool IsSprInstructionUsingMmcr(UGeckoInstruction inst)
static u32 GetSPRIndex(UGeckoInstruction inst)
{
const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
return index == SPR_MMCR0 || index == SPR_MMCR1;
DEBUG_ASSERT(IsMfspr(inst) || IsMtspr(inst));
return (inst.SPRU << 5) | (inst.SPRL & 0x1F);
}
static bool InstructionCanEndBlock(const CodeOp& op)
{
return (op.opinfo->flags & FL_ENDBLOCK) &&
(!IsMtspr(op.inst) || IsSprInstructionUsingMmcr(op.inst));
(!IsMtspr(op.inst) || GetSPRIndex(op.inst) == SPR_MMCR0 ||
GetSPRIndex(op.inst) == SPR_MMCR1);
}
bool PPCAnalyzer::CanSwapAdjacentOps(const CodeOp& a, const CodeOp& b) const
@ -637,10 +643,10 @@ void PPCAnalyzer::SetInstructionStats(CodeBlock* block, CodeOp* code,
// mfspr/mtspr can affect/use XER, so be super careful here
// we need to note specifically that mfspr needs CA in XER, not in the x86 carry flag
if (code->inst.OPCD == 31 && code->inst.SUBOP10 == 339) // mfspr
code->wantsCA = ((code->inst.SPRU << 5) | (code->inst.SPRL & 0x1F)) == SPR_XER;
if (code->inst.OPCD == 31 && code->inst.SUBOP10 == 467) // mtspr
code->outputCA = ((code->inst.SPRU << 5) | (code->inst.SPRL & 0x1F)) == SPR_XER;
if (IsMfspr(code->inst))
code->wantsCA = GetSPRIndex(code->inst) == SPR_XER;
if (IsMtspr(code->inst))
code->outputCA = GetSPRIndex(code->inst) == SPR_XER;
code->regsIn = BitSet32(0);
code->regsOut = BitSet32(0);
@ -892,7 +898,7 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer,
// Through it would be easy to track the upper level of call/return,
// we can't guarantee the LR value. The PPC ABI forces all functions to push
// the LR value on the stack as there are no spare registers. So we'd need
// to check all store instruction to not alias with the stack.
// to check all store instructions to not alias with the stack.
follow = true;
found_call = false;
code[i].skip = true;
@ -901,16 +907,10 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer,
code[caller].skipLRStack = true;
}
}
else if (inst.OPCD == 31 && inst.SUBOP10 == 467)
else if (IsMtspr(inst) && GetSPRIndex(inst) == SPR_LR)
{
// mtspr, skip CALL/RET merging as LR is overwritten.
const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F);
if (index == SPR_LR)
{
// We give up to follow the return address
// because we have to check the register usage.
found_call = false;
}
// LR has been overwritten, so we give up on following the return address.
found_call = false;
}
}
@ -962,8 +962,8 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer,
}
if (conditional_continue)
{
// If we skip any conditional branch, we can't garantee to get the matching CALL/RET pair.
// So we stop inling the RET here and let the BLR optitmization handle this case.
// If we skip any conditional branch, we can't guarantee to get the matching CALL/RET pair.
// So we stop inlining the RET here and let the BLR optimization handle this case.
found_call = false;
}
}
@ -1142,9 +1142,9 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer,
gqrUsed[gqr] = true;
}
if (op.inst.OPCD == 31 && op.inst.SUBOP10 == 467) // mtspr
if (IsMtspr(op.inst))
{
const int gqr = ((op.inst.SPRU << 5) | op.inst.SPRL) - SPR_GQR0;
const int gqr = GetSPRIndex(op.inst) - SPR_GQR0;
if (gqr >= 0 && gqr <= 7)
gqrModified[gqr] = true;
}