From 3a00ff625e826bece6825af9a058e3fe97d7d735 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 19 Nov 2023 11:26:38 +0100 Subject: [PATCH] PPCAnalyst: Don't discard registers across HLE'd functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure if this was causing correctness issues – it depends on whether the HLE code was actually reading the discarded registers – but it was at least causing annoying assert messages in one piece of homebrew. --- Source/Core/Core/PowerPC/PPCAnalyst.cpp | 32 ++++++++++++++++++------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index 78a80e80a2..30134420bb 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -18,6 +18,7 @@ #include "Core/Config/MainSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/HLE/HLE.h" #include "Core/PowerPC/JitCommon/JitBase.h" #include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PPCSymbolDB.h" @@ -970,15 +971,18 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, fprDiscardable = BitSet32{}; } + const bool hle = !!HLE::TryReplaceFunction(op.address); + const bool may_exit_block = hle || op.canEndBlock || op.canCauseException; + const BitSet8 opWantsCR = op.wantsCR; const bool opWantsFPRF = op.wantsFPRF; const bool opWantsCA = op.wantsCA; - op.wantsCR = wantsCR | BitSet8(op.canEndBlock || op.canCauseException ? 0xFF : 0); - op.wantsFPRF = wantsFPRF || op.canEndBlock || op.canCauseException; - op.wantsCA = wantsCA || op.canEndBlock || op.canCauseException; - wantsCR |= opWantsCR | BitSet8(op.canEndBlock || op.canCauseException ? 0xFF : 0); - wantsFPRF |= opWantsFPRF || op.canEndBlock || op.canCauseException; - wantsCA |= opWantsCA || op.canEndBlock || op.canCauseException; + op.wantsCR = wantsCR | BitSet8(may_exit_block ? 0xFF : 0); + op.wantsFPRF = wantsFPRF || may_exit_block; + op.wantsCA = wantsCA || may_exit_block; + wantsCR |= opWantsCR | BitSet8(may_exit_block ? 0xFF : 0); + wantsFPRF |= opWantsFPRF || may_exit_block; + wantsCA |= opWantsCA || may_exit_block; wantsCR &= ~op.outputCR | opWantsCR; wantsFPRF &= !op.outputFPRF || opWantsFPRF; wantsCA &= !op.outputCA || opWantsCA; @@ -989,7 +993,19 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, op.fprInXmm = fprInXmm; gprInUse |= op.regsIn | op.regsOut; fprInUse |= op.fregsIn | op.GetFregsOut(); - if (op.canEndBlock || op.canCauseException) + + if (strncmp(op.opinfo->opname, "stfd", 4)) + fprInXmm |= op.fregsIn; + + if (hle) + { + gprInUse = BitSet32{}; + fprInUse = BitSet32{}; + fprInXmm = BitSet32{}; + gprDiscardable = BitSet32{}; + fprDiscardable = BitSet32{}; + } + else if (op.canEndBlock || op.canCauseException) { gprDiscardable = BitSet32{}; fprDiscardable = BitSet32{}; @@ -1001,8 +1017,6 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, fprDiscardable |= op.GetFregsOut(); fprDiscardable &= ~op.fregsIn; } - if (strncmp(op.opinfo->opname, "stfd", 4)) - fprInXmm |= op.fregsIn; } // Forward scan, for flags that need the other direction for calculation.