better representation (inspired by fleroviux's Lunatic)
This commit is contained in:
42
src/backend/core/JIT/IR/Opcode.hpp
Normal file
42
src/backend/core/JIT/IR/Opcode.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
enum class IROpcodeClass {
|
||||
Normal, Special, Regimm, COP0, COP1
|
||||
};
|
||||
|
||||
struct IROpcode {
|
||||
virtual ~IROpcode() = default;
|
||||
virtual auto GetClass() const -> IROpcodeClass = 0;
|
||||
virtual auto Reads (IRVariable const& var) -> bool = 0;
|
||||
virtual auto Writes(IRVariable const& var) -> bool = 0;
|
||||
virtual void Repoint(IRVariable const& var_old, IRVariable const& var_new) = 0;
|
||||
virtual void PropagateConstant(IRVariable const& var, IRConstant const& constant) {}
|
||||
};
|
||||
|
||||
template<IROpcodeClass _class>
|
||||
struct IROpcodeBase : IROpcode {
|
||||
auto GetClass() const -> IROpcodeClass override { return _class; }
|
||||
};
|
||||
|
||||
struct IRNoOp final : IROpcodeBase<IROpcodeClass::NOP> {
|
||||
auto Reads(IRVariable const& var) -> bool override {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Writes(IRVariable const& var) -> bool override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Repoint(
|
||||
IRVariable const& var_old,
|
||||
IRVariable const& var_new
|
||||
) override {
|
||||
}
|
||||
|
||||
auto ToString() -> std::string override {
|
||||
return "nop";
|
||||
}
|
||||
};
|
||||
}
|
||||
11
src/backend/core/JIT/IR/Register.hpp
Normal file
11
src/backend/core/JIT/IR/Register.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct IRGuestReg {
|
||||
IRGuestReg(u8 reg) : reg(reg) {}
|
||||
|
||||
/// The ARM general purpose register
|
||||
const u8 reg;
|
||||
};
|
||||
}
|
||||
98
src/backend/core/JIT/IR/Value.hpp
Normal file
98
src/backend/core/JIT/IR/Value.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
enum IRPrimitive {
|
||||
Uint32, Sint32, Uint64, Sint32, Uint128, Sint128
|
||||
};
|
||||
|
||||
struct IRVariable {
|
||||
IRVariable(IRPrimitive type, const u32 id, char const* const label) : type(type), id(id), label(label) {}
|
||||
private:
|
||||
IRPrimitive type;
|
||||
const u32 id;
|
||||
char const* const label;
|
||||
};
|
||||
|
||||
struct IRConstant {
|
||||
IRConstant() {}
|
||||
IRConstant(IRPrimitive type, u128 value) : type(type), value(value) {}
|
||||
private:
|
||||
IRPrimitive type = Uint128;
|
||||
u128 value = 0;
|
||||
};
|
||||
|
||||
struct IRAnyRef {
|
||||
IRAnyRef() {}
|
||||
IRAnyRef(IRVariable const& variable) : type(Type::Variable), var(&variable) {}
|
||||
IRAnyRef(IRConstant const& constant) : type(Type::Constant), constant(constant) {}
|
||||
|
||||
auto operator=(IRAnyRef const& other) -> IRAnyRef& {
|
||||
type = other.type;
|
||||
if (IsConstant()) {
|
||||
constant = other.constant;
|
||||
} else {
|
||||
var = other.var;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsNull() const { return type == Type::Null; }
|
||||
bool IsVariable() const { return type == Type::Variable; }
|
||||
bool IsConstant() const { return type == Type::Constant; }
|
||||
|
||||
auto GetVar() const -> IRVariable const& {
|
||||
if (!IsVariable()) {
|
||||
Util::panic("called GetVar() but value is a constant or null");
|
||||
}
|
||||
return *var;
|
||||
}
|
||||
|
||||
auto GetConst() const -> IRConstant const& {
|
||||
if (!IsConstant()) {
|
||||
Util::panic("called GetConst() but value is a variable or null");
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
|
||||
void Repoint(IRVariable const& var_old, IRVariable const& var_new) {
|
||||
if (IsVariable() && (&GetVar() == &var_old)) {
|
||||
var = &var_new;
|
||||
}
|
||||
}
|
||||
|
||||
void PropagateConstant(IRVariable const& var, IRConstant const& constant) {
|
||||
if (IsVariable() && (&GetVar() == &var)) {
|
||||
type = Type::Constant;
|
||||
this->constant = constant;
|
||||
}
|
||||
}
|
||||
private:
|
||||
enum Type {
|
||||
Null, Variable, Constant
|
||||
};
|
||||
|
||||
Type type;
|
||||
|
||||
union {
|
||||
IRVariable const* var;
|
||||
IRConstant constant;
|
||||
};
|
||||
};
|
||||
|
||||
struct IRVarRef {
|
||||
IRVarRef(IRVariable const& var) : p_var(&var) {}
|
||||
|
||||
auto Get() const -> IRVariable const& {
|
||||
return *p_var;
|
||||
}
|
||||
|
||||
void Repoint(IRVariable const& var_old, IRVariable const& var_new) {
|
||||
if (&var_old == p_var) {
|
||||
p_var = &var_new;
|
||||
}
|
||||
}
|
||||
private:
|
||||
IRVariable const* p_var;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user