Interpreter: Install BranchWatch

This commit is contained in:
mitaclaw 2023-12-07 09:32:58 -08:00
parent 67f60bec7e
commit 2aa250a68a
1 changed files with 38 additions and 12 deletions

View File

@ -7,6 +7,7 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/Debugger/BranchWatch.h"
#include "Core/HLE/HLE.h" #include "Core/HLE/HLE.h"
#include "Core/PowerPC/Interpreter/ExceptionUtils.h" #include "Core/PowerPC/Interpreter/ExceptionUtils.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
@ -19,12 +20,13 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
if (inst.LK) if (inst.LK)
LR(ppc_state) = ppc_state.pc + 4; LR(ppc_state) = ppc_state.pc + 4;
const auto address = u32(SignExt26(inst.LI << 2)); u32 destination_addr = u32(SignExt26(inst.LI << 2));
if (!inst.AA)
destination_addr += ppc_state.pc;
ppc_state.npc = destination_addr;
if (inst.AA) if (auto& branch_watch = interpreter.m_branch_watch; branch_watch.GetRecordingActive())
ppc_state.npc = address; branch_watch.HitTrue(ppc_state.pc, destination_addr, inst, ppc_state.msr.IR);
else
ppc_state.npc = ppc_state.pc + address;
interpreter.m_end_block = true; interpreter.m_end_block = true;
} }
@ -33,6 +35,7 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
{ {
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
auto& branch_watch = interpreter.m_branch_watch;
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR(ppc_state)--; CTR(ppc_state)--;
@ -49,12 +52,17 @@ void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
if (inst.LK) if (inst.LK)
LR(ppc_state) = ppc_state.pc + 4; LR(ppc_state) = ppc_state.pc + 4;
const auto address = u32(SignExt16(s16(inst.BD << 2))); u32 destination_addr = u32(SignExt16(s16(inst.BD << 2)));
if (!inst.AA)
destination_addr += ppc_state.pc;
ppc_state.npc = destination_addr;
if (inst.AA) if (branch_watch.GetRecordingActive())
ppc_state.npc = address; branch_watch.HitTrue(ppc_state.pc, destination_addr, inst, ppc_state.msr.IR);
else }
ppc_state.npc = ppc_state.pc + address; else if (branch_watch.GetRecordingActive())
{
branch_watch.HitFalse(ppc_state.pc, ppc_state.pc + 4, inst, ppc_state.msr.IR);
} }
interpreter.m_end_block = true; interpreter.m_end_block = true;
@ -63,6 +71,7 @@ void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
{ {
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
auto& branch_watch = interpreter.m_branch_watch;
DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0, DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0,
"bcctrx with decrement and test CTR option is invalid!"); "bcctrx with decrement and test CTR option is invalid!");
@ -72,9 +81,17 @@ void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
if (condition != 0) if (condition != 0)
{ {
ppc_state.npc = CTR(ppc_state) & (~3); const u32 destination_addr = CTR(ppc_state) & (~3);
ppc_state.npc = destination_addr;
if (inst.LK_3) if (inst.LK_3)
LR(ppc_state) = ppc_state.pc + 4; LR(ppc_state) = ppc_state.pc + 4;
if (branch_watch.GetRecordingActive())
branch_watch.HitTrue(ppc_state.pc, destination_addr, inst, ppc_state.msr.IR);
}
else if (branch_watch.GetRecordingActive())
{
branch_watch.HitFalse(ppc_state.pc, ppc_state.pc + 4, inst, ppc_state.msr.IR);
} }
interpreter.m_end_block = true; interpreter.m_end_block = true;
@ -83,6 +100,7 @@ void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
{ {
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
auto& branch_watch = interpreter.m_branch_watch;
if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
CTR(ppc_state)--; CTR(ppc_state)--;
@ -93,9 +111,17 @@ void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
if ((counter & condition) != 0) if ((counter & condition) != 0)
{ {
ppc_state.npc = LR(ppc_state) & (~3); const u32 destination_addr = LR(ppc_state) & (~3);
ppc_state.npc = destination_addr;
if (inst.LK_3) if (inst.LK_3)
LR(ppc_state) = ppc_state.pc + 4; LR(ppc_state) = ppc_state.pc + 4;
if (branch_watch.GetRecordingActive())
branch_watch.HitTrue(ppc_state.pc, destination_addr, inst, ppc_state.msr.IR);
}
else if (branch_watch.GetRecordingActive())
{
branch_watch.HitFalse(ppc_state.pc, ppc_state.pc + 4, inst, ppc_state.msr.IR);
} }
interpreter.m_end_block = true; interpreter.m_end_block = true;