From 076bdf7a2441ecb342e5f4de50f643ac5ba88322 Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:52:48 -0700 Subject: [PATCH] Expression: Support All SPRs + MSR --- Source/Core/Core/PowerPC/Expression.cpp | 205 +++++++++++++++--- Source/Core/Core/PowerPC/Expression.h | 1 + .../DolphinQt/Debugger/BreakpointDialog.cpp | 7 +- 3 files changed, 180 insertions(+), 33 deletions(-) diff --git a/Source/Core/Core/PowerPC/Expression.cpp b/Source/Core/Core/PowerPC/Expression.cpp index 79307f4460..edbd3349e9 100644 --- a/Source/Core/Core/PowerPC/Expression.cpp +++ b/Source/Core/Core/PowerPC/Expression.cpp @@ -4,6 +4,7 @@ #include "Core/PowerPC/Expression.h" #include +#include #include #include #include @@ -219,40 +220,174 @@ void ExprVarListDeleter::operator()(expr_var_list* vars) const Expression::Expression(std::string_view text, ExprPointer ex, ExprVarListPointer vars) : m_text(text), m_expr(std::move(ex)), m_vars(std::move(vars)) { + using LookupKV = std::pair; + static constexpr auto sorted_lookup = []() consteval + { + using enum Expression::VarBindingType; + auto unsorted_lookup = std::to_array({ + {"r0", {GPR, 0}}, + {"r1", {GPR, 1}}, + {"r2", {GPR, 2}}, + {"r3", {GPR, 3}}, + {"r4", {GPR, 4}}, + {"r5", {GPR, 5}}, + {"r6", {GPR, 6}}, + {"r7", {GPR, 7}}, + {"r8", {GPR, 8}}, + {"r9", {GPR, 9}}, + {"r10", {GPR, 10}}, + {"r11", {GPR, 11}}, + {"r12", {GPR, 12}}, + {"r13", {GPR, 13}}, + {"r14", {GPR, 14}}, + {"r15", {GPR, 15}}, + {"r16", {GPR, 16}}, + {"r17", {GPR, 17}}, + {"r18", {GPR, 18}}, + {"r19", {GPR, 19}}, + {"r20", {GPR, 20}}, + {"r21", {GPR, 21}}, + {"r22", {GPR, 22}}, + {"r23", {GPR, 23}}, + {"r24", {GPR, 24}}, + {"r25", {GPR, 25}}, + {"r26", {GPR, 26}}, + {"r27", {GPR, 27}}, + {"r28", {GPR, 28}}, + {"r29", {GPR, 29}}, + {"r30", {GPR, 30}}, + {"r31", {GPR, 31}}, + {"f0", {FPR, 0}}, + {"f1", {FPR, 1}}, + {"f2", {FPR, 2}}, + {"f3", {FPR, 3}}, + {"f4", {FPR, 4}}, + {"f5", {FPR, 5}}, + {"f6", {FPR, 6}}, + {"f7", {FPR, 7}}, + {"f8", {FPR, 8}}, + {"f9", {FPR, 9}}, + {"f10", {FPR, 10}}, + {"f11", {FPR, 11}}, + {"f12", {FPR, 12}}, + {"f13", {FPR, 13}}, + {"f14", {FPR, 14}}, + {"f15", {FPR, 15}}, + {"f16", {FPR, 16}}, + {"f17", {FPR, 17}}, + {"f18", {FPR, 18}}, + {"f19", {FPR, 19}}, + {"f20", {FPR, 20}}, + {"f21", {FPR, 21}}, + {"f22", {FPR, 22}}, + {"f23", {FPR, 23}}, + {"f24", {FPR, 24}}, + {"f25", {FPR, 25}}, + {"f26", {FPR, 26}}, + {"f27", {FPR, 27}}, + {"f28", {FPR, 28}}, + {"f29", {FPR, 29}}, + {"f30", {FPR, 30}}, + {"f31", {FPR, 31}}, + {"pc", {PCtr}}, + {"msr", {MSR}}, + {"xer", {SPR, SPR_XER}}, + {"lr", {SPR, SPR_LR}}, + {"ctr", {SPR, SPR_CTR}}, + {"dsisr", {SPR, SPR_DSISR}}, + {"dar", {SPR, SPR_DAR}}, + {"dec", {SPR, SPR_DEC}}, + {"sdr1", {SPR, SPR_SDR}}, + {"srr0", {SPR, SPR_SRR0}}, + {"srr1", {SPR, SPR_SRR1}}, + {"tbl", {SPR, SPR_TL}}, + {"tbu", {SPR, SPR_TU}}, + {"pvr", {SPR, SPR_PVR}}, + {"sprg0", {SPR, SPR_SPRG0}}, + {"sprg1", {SPR, SPR_SPRG1}}, + {"sprg2", {SPR, SPR_SPRG2}}, + {"sprg3", {SPR, SPR_SPRG3}}, + {"ear", {SPR, SPR_EAR}}, + {"ibat0u", {SPR, SPR_IBAT0U}}, + {"ibat0l", {SPR, SPR_IBAT0L}}, + {"ibat1u", {SPR, SPR_IBAT1U}}, + {"ibat1l", {SPR, SPR_IBAT1L}}, + {"ibat2u", {SPR, SPR_IBAT2U}}, + {"ibat2l", {SPR, SPR_IBAT2L}}, + {"ibat3u", {SPR, SPR_IBAT3U}}, + {"ibat3l", {SPR, SPR_IBAT3L}}, + {"ibat4u", {SPR, SPR_IBAT4U}}, + {"ibat4l", {SPR, SPR_IBAT4L}}, + {"ibat5u", {SPR, SPR_IBAT5U}}, + {"ibat5l", {SPR, SPR_IBAT5L}}, + {"ibat6u", {SPR, SPR_IBAT6U}}, + {"ibat6l", {SPR, SPR_IBAT6L}}, + {"ibat7u", {SPR, SPR_IBAT7U}}, + {"ibat7l", {SPR, SPR_IBAT7L}}, + {"dbat0u", {SPR, SPR_DBAT0U}}, + {"dbat0l", {SPR, SPR_DBAT0L}}, + {"dbat1u", {SPR, SPR_DBAT1U}}, + {"dbat1l", {SPR, SPR_DBAT1L}}, + {"dbat2u", {SPR, SPR_DBAT2U}}, + {"dbat2l", {SPR, SPR_DBAT2L}}, + {"dbat3u", {SPR, SPR_DBAT3U}}, + {"dbat3l", {SPR, SPR_DBAT3L}}, + {"dbat4u", {SPR, SPR_DBAT4U}}, + {"dbat4l", {SPR, SPR_DBAT4L}}, + {"dbat5u", {SPR, SPR_DBAT5U}}, + {"dbat5l", {SPR, SPR_DBAT5L}}, + {"dbat6u", {SPR, SPR_DBAT6U}}, + {"dbat6l", {SPR, SPR_DBAT6L}}, + {"dbat7u", {SPR, SPR_DBAT7U}}, + {"dbat7l", {SPR, SPR_DBAT7L}}, + {"gqr0", {SPR, SPR_GQR0 + 0}}, + {"gqr1", {SPR, SPR_GQR0 + 1}}, + {"gqr2", {SPR, SPR_GQR0 + 2}}, + {"gqr3", {SPR, SPR_GQR0 + 3}}, + {"gqr4", {SPR, SPR_GQR0 + 4}}, + {"gqr5", {SPR, SPR_GQR0 + 5}}, + {"gqr6", {SPR, SPR_GQR0 + 6}}, + {"gqr7", {SPR, SPR_GQR0 + 7}}, + {"hid0", {SPR, SPR_HID0}}, + {"hid1", {SPR, SPR_HID1}}, + {"hid2", {SPR, SPR_HID2}}, + {"hid4", {SPR, SPR_HID4}}, + {"iabr", {SPR, SPR_IABR}}, + {"dabr", {SPR, SPR_DABR}}, + {"wpar", {SPR, SPR_WPAR}}, + {"dmau", {SPR, SPR_DMAU}}, + {"dmal", {SPR, SPR_DMAL}}, + {"ecid_u", {SPR, SPR_ECID_U}}, + {"ecid_m", {SPR, SPR_ECID_M}}, + {"ecid_l", {SPR, SPR_ECID_L}}, + {"usia", {SPR, SPR_USIA}}, + {"sia", {SPR, SPR_SIA}}, + {"l2cr", {SPR, SPR_L2CR}}, + {"ictc", {SPR, SPR_ICTC}}, + {"mmcr0", {SPR, SPR_MMCR0}}, + {"mmcr1", {SPR, SPR_MMCR1}}, + {"pmc1", {SPR, SPR_PMC1}}, + {"pmc2", {SPR, SPR_PMC2}}, + {"pmc3", {SPR, SPR_PMC3}}, + {"pmc4", {SPR, SPR_PMC4}}, + {"thrm1", {SPR, SPR_THRM1}}, + {"thrm2", {SPR, SPR_THRM2}}, + {"thrm3", {SPR, SPR_THRM3}}, + }); + std::ranges::sort(unsorted_lookup, {}, &LookupKV::first); + return unsorted_lookup; + } + (); + static_assert(std::ranges::adjacent_find(sorted_lookup, {}, &LookupKV::first) == + sorted_lookup.end(), + "Expression: Sorted lookup should not contain duplicate keys."); for (auto* v = m_vars->head; v != nullptr; v = v->next) { - const std::string_view name = v->name; - VarBinding bind; - - if (name.length() >= 2 && name.length() <= 3) - { - if (name[0] == 'r' || name[0] == 'f') - { - char* end = nullptr; - const int index = std::strtol(name.data() + 1, &end, 10); - if (index >= 0 && index <= 31 && end == name.data() + name.length()) - { - bind.type = name[0] == 'r' ? VarBindingType::GPR : VarBindingType::FPR; - bind.index = index; - } - } - else if (name == "lr") - { - bind.type = VarBindingType::SPR; - bind.index = SPR_LR; - } - else if (name == "ctr") - { - bind.type = VarBindingType::SPR; - bind.index = SPR_CTR; - } - else if (name == "pc") - { - bind.type = VarBindingType::PCtr; - } - } - - m_binds.emplace_back(bind); + const auto iter = std::ranges::lower_bound(sorted_lookup, v->name, {}, &LookupKV::first); + if (iter != sorted_lookup.end() && iter->first == v->name) + m_binds.emplace_back(iter->second); + else + m_binds.emplace_back(); } } @@ -313,6 +448,12 @@ void Expression::SynchronizeBindings(Core::System& system, SynchronizeDirection if (dir == SynchronizeDirection::From) v->value = static_cast(ppc_state.pc); break; + case VarBindingType::MSR: + if (dir == SynchronizeDirection::From) + v->value = static_cast(ppc_state.msr.Hex); + else + ppc_state.msr.Hex = static_cast(static_cast(v->value)); + break; } } } diff --git a/Source/Core/Core/PowerPC/Expression.h b/Source/Core/Core/PowerPC/Expression.h index d9799caa82..3c439f9e9e 100644 --- a/Source/Core/Core/PowerPC/Expression.h +++ b/Source/Core/Core/PowerPC/Expression.h @@ -55,6 +55,7 @@ private: FPR, SPR, PCtr, + MSR, }; struct VarBinding diff --git a/Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp b/Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp index 1675100bab..1899b42168 100644 --- a/Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp +++ b/Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp @@ -331,7 +331,12 @@ void BreakpointDialog::ShowConditionHelp() "\n" "Registers that can be referenced:\n" "GPRs : r0..r31\n" - "FPRs : f0..f31\n LR, CTR, PC\n" + "FPRs : f0..f31\n" + "SPRs : xer, lr, ctr, dsisr, dar, dec, sdr1, srr0, srr1, tbl, tbu, pvr, sprg0..sprg3, ear, " + "ibat0u..ibat7u, ibat0l..ibat7l, dbat0u..dbat7u, dbat0l..dbat07, gqr0..gqr7, hid0, hid1, " + "hid2, hid4, iabr, dabr, wpar, dmau, dmal, ecid_u, ecid_m, ecid_l, upmc1..upmc4, usia, sia, " + "l2cr, ictc, mmcr0, mmcr1, pmc1..pmc4, thrm1..thrm3\n" + "Other : pc, msr\n" "\n" "Functions:\n" "Set a register: r1 = 8\n"