Skip to content

Commit

Permalink
Experiment with Function Pointers for Cached Interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam-Belliveau committed May 2, 2024
1 parent 5817be7 commit 1463d10
Showing 1 changed file with 56 additions and 60 deletions.
116 changes: 56 additions & 60 deletions Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,86 @@

struct CachedInterpreter::Instruction
{
public:
using RunnerCallback = bool (Instruction::*)(Interpreter&, CachedInterpreter&) const;
using CommonCallback = void (*)(UGeckoInstruction);
using ConditionalCallback = bool (*)(u32);
using InterpreterCallback = void (*)(Interpreter&, UGeckoInstruction);
using CachedInterpreterCallback = void (*)(CachedInterpreter&, UGeckoInstruction);
using ConditionalCachedInterpreterCallback = bool (*)(CachedInterpreter&, u32);

Instruction() {}
bool abort_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
return true;
}

bool common_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
callback(instruction);
return false;
}

bool conditional_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
return conditional_callback(data);
}

bool interpreter_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
interpreter_callback(interpreter, instruction);
return false;
}

bool cached_interpreter_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
cached_interpreter_callback(cached_interpreter, instruction);
return false;
}

bool conditional_cached_interpreter_runner(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
return conditional_cached_interpreter_callback(cached_interpreter, data);
}

const RunnerCallback runner;

union {
const CommonCallback callback;
const ConditionalCallback conditional_callback;
const InterpreterCallback interpreter_callback;
const CachedInterpreterCallback cached_interpreter_callback;
const ConditionalCachedInterpreterCallback conditional_cached_interpreter_callback;
};

union {
const UGeckoInstruction instruction;
const u32 data;
};

Instruction() : runner{&Instruction::abort_runner}, callback{nullptr}, data{0} {}

Instruction(const CommonCallback c, UGeckoInstruction i)
: common_callback(c), data(i.hex), type(Type::Common)
: runner{&Instruction::common_runner}, callback{c}, instruction{i}
{
}

Instruction(const ConditionalCallback c, u32 d)
: conditional_callback(c), data(d), type(Type::Conditional)
: runner{&Instruction::conditional_runner}, conditional_callback{c}, instruction{0}
{
}

Instruction(const InterpreterCallback c, UGeckoInstruction i)
: interpreter_callback(c), data(i.hex), type(Type::Interpreter)
: runner{&Instruction::interpreter_runner}, interpreter_callback{c}, instruction{i}
{
}

Instruction(const CachedInterpreterCallback c, UGeckoInstruction i)
: cached_interpreter_callback(c), data(i.hex), type(Type::CachedInterpreter)
: runner{&Instruction::cached_interpreter_runner}, cached_interpreter_callback{c}, instruction{i}
{
}

Instruction(const ConditionalCachedInterpreterCallback c, u32 d)
: conditional_cached_interpreter_callback(c), data(d),
type(Type::ConditionalCachedInterpreter)
: runner{&Instruction::conditional_cached_interpreter_runner}, conditional_cached_interpreter_callback{c}, data{d}
{
}

enum class Type
{
Abort,
Common,
Conditional,
Interpreter,
CachedInterpreter,
ConditionalCachedInterpreter,
};

union
{
const CommonCallback common_callback = nullptr;
const ConditionalCallback conditional_callback;
const InterpreterCallback interpreter_callback;
const CachedInterpreterCallback cached_interpreter_callback;
const ConditionalCachedInterpreterCallback conditional_cached_interpreter_callback;
};

u32 data = 0;
Type type = Type::Abort;
bool run(Interpreter& interpreter, CachedInterpreter& cached_interpreter) const {
return (this->*runner)(interpreter, cached_interpreter);
}
};

CachedInterpreter::CachedInterpreter(Core::System& system) : JitBase(system)
Expand Down Expand Up @@ -116,39 +142,9 @@ void CachedInterpreter::ExecuteOneBlock()

const Instruction* code = reinterpret_cast<const Instruction*>(normal_entry);
auto& interpreter = m_system.GetInterpreter();
auto& cached_interpreter = *this;

for (; code->type != Instruction::Type::Abort; ++code)
{
switch (code->type)
{
case Instruction::Type::Common:
code->common_callback(UGeckoInstruction(code->data));
break;

case Instruction::Type::Conditional:
if (code->conditional_callback(code->data))
return;
break;

case Instruction::Type::Interpreter:
code->interpreter_callback(interpreter, UGeckoInstruction(code->data));
break;

case Instruction::Type::CachedInterpreter:
code->cached_interpreter_callback(*this, UGeckoInstruction(code->data));
break;

case Instruction::Type::ConditionalCachedInterpreter:
if (code->conditional_cached_interpreter_callback(*this, code->data))
return;
break;

default:
ERROR_LOG_FMT(POWERPC, "Unknown CachedInterpreter Instruction: {}",
static_cast<int>(code->type));
break;
}
}
for (; !code->run(interpreter, cached_interpreter); ++code){}
}

void CachedInterpreter::Run()
Expand Down

0 comments on commit 1463d10

Please sign in to comment.