diff --git a/src/xenia/cpu/backend/a64/a64_sequences.cc b/src/xenia/cpu/backend/a64/a64_sequences.cc index 3eb60510e..63269dbee 100644 --- a/src/xenia/cpu/backend/a64/a64_sequences.cc +++ b/src/xenia/cpu/backend/a64/a64_sequences.cc @@ -1,4 +1,4 @@ -/** +/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** @@ -53,7 +53,7 @@ using namespace xe::cpu::hir; using xe::cpu::hir::Instr; typedef bool (*SequenceSelectFn)(A64Emitter&, const Instr*); -std::unordered_map sequence_table; +// std::unordered_map sequence_table; Removed // ============================================================================ // OPCODE_COMMENT @@ -2769,10 +2769,12 @@ static int anchor_memory_dest = anchor_memory; extern volatile int anchor_vector; static int anchor_vector_dest = anchor_vector; -bool SelectSequence(A64Emitter* e, const Instr* i, const Instr** new_tail) { +bool SelectSequence(A64Emitter* e, const hir::Instr* i, + const hir::Instr** new_tail) { const InstrKey key(i); - auto it = sequence_table.find(key); - if (it != sequence_table.end()) { + auto& table = GetSequenceTable(); // Use the singleton accessor + auto it = table.find(key); + if (it != table.end()) { if (it->second(*e, i)) { *new_tail = i->next; return true; diff --git a/src/xenia/cpu/backend/a64/a64_sequences.h b/src/xenia/cpu/backend/a64/a64_sequences.h index b47382633..65d4adad3 100644 --- a/src/xenia/cpu/backend/a64/a64_sequences.h +++ b/src/xenia/cpu/backend/a64/a64_sequences.h @@ -10,9 +10,10 @@ #ifndef XENIA_CPU_BACKEND_A64_A64_SEQUENCES_H_ #define XENIA_CPU_BACKEND_A64_A64_SEQUENCES_H_ -#include "xenia/cpu/hir/instr.h" - +#include +#include // For logging #include +#include "xenia/cpu/hir/instr.h" namespace xe { namespace cpu { @@ -22,24 +23,34 @@ namespace a64 { class A64Emitter; typedef bool (*SequenceSelectFn)(A64Emitter&, const hir::Instr*); -extern std::unordered_map sequence_table; +// Singleton accessor for sequence_table +inline std::unordered_map& GetSequenceTable() { + static std::unordered_map sequence_table; + return sequence_table; +} + +// Registration Functions template -bool Register() { - sequence_table.insert({T::head_key(), T::Select}); - return true; +bool RegisterSingle() { + bool inserted = GetSequenceTable().emplace(T::head_key(), T::Select).second; + if (!inserted) { + std::cerr << "Warning: Duplicate head_key detected for key " + << T::head_key() << std::endl; + } + return inserted; } -template -static bool Register() { - bool b = true; - b = b && Register(); // Call the above function - b = b && Register(); // Call ourself again (recursively) - return b; +template +bool RegisterAll() { + return (RegisterSingle() && ...); // Fold expression (C++17) } + +// Macro for Registration #define EMITTER_OPCODE_TABLE(name, ...) \ - const auto A64_INSTR_##name = Register<__VA_ARGS__>(); + static const bool A64_INSTR_##name = RegisterAll<__VA_ARGS__>(); +// Function to Select Sequence bool SelectSequence(A64Emitter* e, const hir::Instr* i, const hir::Instr** new_tail);