diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 917b0b27eb..003dcc7b3f 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -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; }