mirror of
https://github.com/izzy2lost/xenia-edge.git
synced 2026-07-06 00:20:26 -07:00
[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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user