[A64/Sequences] Centralize sequence registration

- Replace global table with a singleton accessor

- Switch registration to fold expressions with duplicate warnings

- Update SelectSequence signature and entrypoint lookup
This commit is contained in:
Will Martin
2026-01-21 10:57:09 +09:00
parent e3a2b1f9de
commit 683cc221c8
2 changed files with 31 additions and 18 deletions
+7 -5
View File
@@ -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<uint32_t, SequenceSelectFn> sequence_table;
// std::unordered_map<uint32_t, SequenceSelectFn> 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;
+24 -13
View File
@@ -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 <functional>
#include <iostream> // For logging
#include <unordered_map>
#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<uint32_t, SequenceSelectFn> sequence_table;
// Singleton accessor for sequence_table
inline std::unordered_map<uint32_t, SequenceSelectFn>& GetSequenceTable() {
static std::unordered_map<uint32_t, SequenceSelectFn> sequence_table;
return sequence_table;
}
// Registration Functions
template <typename T>
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 <typename T, typename Tn, typename... Ts>
static bool Register() {
bool b = true;
b = b && Register<T>(); // Call the above function
b = b && Register<Tn, Ts...>(); // Call ourself again (recursively)
return b;
template <typename... Ts>
bool RegisterAll() {
return (RegisterSingle<Ts>() && ...); // 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);