Split PPCTables from Interpreter_Tables
This also allows use of constexpr in both places. Some additional work was needed in PPCTables due to mutable data associated with each opcode.
This commit is contained in:
1 parent
cd627d1232
commit
164ea57790
12 files changed
+1077
-574
No files matched your search
@@ -34,14 +34,6 @@ u32 last_pc;
|
||||
|
||||
bool Interpreter::m_end_block;
|
||||
|
||||
// function tables
|
||||
std::array<Interpreter::Instruction, 64> Interpreter::m_op_table;
|
||||
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table4;
|
||||
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table19;
|
||||
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table31;
|
||||
std::array<Interpreter::Instruction, 32> Interpreter::m_op_table59;
|
||||
std::array<Interpreter::Instruction, 1024> Interpreter::m_op_table63;
|
||||
|
||||
namespace
|
||||
{
|
||||
// Determines whether or not the given instruction is one where its execution
|
||||
@@ -79,30 +71,8 @@ void UpdatePC()
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void Interpreter::RunTable4(UGeckoInstruction inst)
|
||||
{
|
||||
m_op_table4[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable19(UGeckoInstruction inst)
|
||||
{
|
||||
m_op_table19[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable31(UGeckoInstruction inst)
|
||||
{
|
||||
m_op_table31[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable59(UGeckoInstruction inst)
|
||||
{
|
||||
m_op_table59[inst.SUBOP5](inst);
|
||||
}
|
||||
void Interpreter::RunTable63(UGeckoInstruction inst)
|
||||
{
|
||||
m_op_table63[inst.SUBOP10](inst);
|
||||
}
|
||||
|
||||
void Interpreter::Init()
|
||||
{
|
||||
InitializeInstructionTables();
|
||||
m_end_block = false;
|
||||
}
|
||||
|
||||
@@ -150,7 +120,7 @@ int Interpreter::SingleStepInner()
|
||||
if (HandleFunctionHooking(PowerPC::ppcState.pc))
|
||||
{
|
||||
UpdatePC();
|
||||
return PPCTables::GetOpInfo(m_prev_inst)->numCycles;
|
||||
return PPCTables::GetOpInfo(m_prev_inst)->num_cycles;
|
||||
}
|
||||
|
||||
PowerPC::ppcState.npc = PowerPC::ppcState.pc + sizeof(UGeckoInstruction);
|
||||
@@ -181,7 +151,7 @@ int Interpreter::SingleStepInner()
|
||||
}
|
||||
else if (PowerPC::ppcState.msr.FP)
|
||||
{
|
||||
m_op_table[m_prev_inst.OPCD](m_prev_inst);
|
||||
RunInterpreterOp(m_prev_inst);
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
@@ -197,7 +167,7 @@ int Interpreter::SingleStepInner()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_op_table[m_prev_inst.OPCD](m_prev_inst);
|
||||
RunInterpreterOp(m_prev_inst);
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
@@ -214,9 +184,9 @@ int Interpreter::SingleStepInner()
|
||||
UpdatePC();
|
||||
|
||||
const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst);
|
||||
PowerPC::UpdatePerformanceMonitor(opinfo->numCycles, (opinfo->flags & FL_LOADSTORE) != 0,
|
||||
PowerPC::UpdatePerformanceMonitor(opinfo->num_cycles, (opinfo->flags & FL_LOADSTORE) != 0,
|
||||
(opinfo->flags & FL_USE_FPU) != 0, PowerPC::ppcState);
|
||||
return opinfo->numCycles;
|
||||
return opinfo->num_cycles;
|
||||
}
|
||||
|
||||
void Interpreter::SingleStep()
|
||||
|
||||
@@ -262,12 +262,9 @@ public:
|
||||
static void isync(UGeckoInstruction inst);
|
||||
|
||||
using Instruction = void (*)(UGeckoInstruction inst);
|
||||
static std::array<Instruction, 64> m_op_table;
|
||||
static std::array<Instruction, 1024> m_op_table4;
|
||||
static std::array<Instruction, 1024> m_op_table19;
|
||||
static std::array<Instruction, 1024> m_op_table31;
|
||||
static std::array<Instruction, 32> m_op_table59;
|
||||
static std::array<Instruction, 1024> m_op_table63;
|
||||
|
||||
static Instruction GetInterpreterOp(UGeckoInstruction inst);
|
||||
static void RunInterpreterOp(UGeckoInstruction inst);
|
||||
|
||||
// singleton
|
||||
static Interpreter* getInstance();
|
||||
@@ -283,8 +280,6 @@ public:
|
||||
private:
|
||||
void CheckExceptions();
|
||||
|
||||
static void InitializeInstructionTables();
|
||||
|
||||
static bool HandleFunctionHooking(u32 address);
|
||||
|
||||
// flag helper
|
||||
|
||||
@@ -5,492 +5,492 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/TypeUtils.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/PPCTables.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct GekkoOPTemplate
|
||||
struct InterpreterOpTemplate
|
||||
{
|
||||
int opcode;
|
||||
Interpreter::Instruction Inst;
|
||||
GekkoOPInfo opinfo;
|
||||
u32 opcode;
|
||||
Interpreter::Instruction fn;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// clang-format off
|
||||
static GekkoOPInfo unknownopinfo = { "unknown_instruction", OpType::Unknown, FL_ENDBLOCK, 0, 0, 0, 0 };
|
||||
constexpr std::array<InterpreterOpTemplate, 54> s_primary_table{{
|
||||
{4, Interpreter::RunTable4}, // RunTable4
|
||||
{19, Interpreter::RunTable19}, // RunTable19
|
||||
{31, Interpreter::RunTable31}, // RunTable31
|
||||
{59, Interpreter::RunTable59}, // RunTable59
|
||||
{63, Interpreter::RunTable63}, // RunTable63
|
||||
|
||||
static std::array<GekkoOPTemplate, 54> primarytable =
|
||||
{{
|
||||
{4, Interpreter::RunTable4, {"RunTable4", OpType::Subtable, 0, 0, 0, 0, 0}},
|
||||
{19, Interpreter::RunTable19, {"RunTable19", OpType::Subtable, 0, 0, 0, 0, 0}},
|
||||
{31, Interpreter::RunTable31, {"RunTable31", OpType::Subtable, 0, 0, 0, 0, 0}},
|
||||
{59, Interpreter::RunTable59, {"RunTable59", OpType::Subtable, 0, 0, 0, 0, 0}},
|
||||
{63, Interpreter::RunTable63, {"RunTable63", OpType::Subtable, 0, 0, 0, 0, 0}},
|
||||
{16, Interpreter::bcx}, // bcx
|
||||
{18, Interpreter::bx}, // bx
|
||||
|
||||
{16, Interpreter::bcx, {"bcx", OpType::Branch, FL_ENDBLOCK | FL_READ_CR_BI, 1, 0, 0, 0}},
|
||||
{18, Interpreter::bx, {"bx", OpType::Branch, FL_ENDBLOCK, 1, 0, 0, 0}},
|
||||
{3, Interpreter::twi}, // twi
|
||||
{17, Interpreter::sc}, // sc
|
||||
|
||||
{3, Interpreter::twi, {"twi", OpType::System, FL_IN_A | FL_ENDBLOCK, 1, 0, 0, 0}},
|
||||
{17, Interpreter::sc, {"sc", OpType::System, FL_ENDBLOCK, 2, 0, 0, 0}},
|
||||
{7, Interpreter::mulli}, // mulli
|
||||
{8, Interpreter::subfic}, // subfic
|
||||
{10, Interpreter::cmpli}, // cmpli
|
||||
{11, Interpreter::cmpi}, // cmpi
|
||||
{12, Interpreter::addic}, // addic
|
||||
{13, Interpreter::addic_rc}, // addic_rc
|
||||
{14, Interpreter::addi}, // addi
|
||||
{15, Interpreter::addis}, // addis
|
||||
|
||||
{7, Interpreter::mulli, {"mulli", OpType::Integer, FL_OUT_D | FL_IN_A, 3, 0, 0, 0}},
|
||||
{8, Interpreter::subfic, {"subfic", OpType::Integer, FL_OUT_D | FL_IN_A | FL_SET_CA, 1, 0, 0, 0}},
|
||||
{10, Interpreter::cmpli, {"cmpli", OpType::Integer, FL_IN_A | FL_SET_CRn, 1, 0, 0, 0}},
|
||||
{11, Interpreter::cmpi, {"cmpi", OpType::Integer, FL_IN_A | FL_SET_CRn, 1, 0, 0, 0}},
|
||||
{12, Interpreter::addic, {"addic", OpType::Integer, FL_OUT_D | FL_IN_A | FL_SET_CA, 1, 0, 0, 0}},
|
||||
{13, Interpreter::addic_rc, {"addic_rc", OpType::Integer, FL_OUT_D | FL_IN_A | FL_SET_CA | FL_SET_CR0, 1, 0, 0, 0}},
|
||||
{14, Interpreter::addi, {"addi", OpType::Integer, FL_OUT_D | FL_IN_A0, 1, 0, 0, 0}},
|
||||
{15, Interpreter::addis, {"addis", OpType::Integer, FL_OUT_D | FL_IN_A0, 1, 0, 0, 0}},
|
||||
{20, Interpreter::rlwimix}, // rlwimix
|
||||
{21, Interpreter::rlwinmx}, // rlwinmx
|
||||
{23, Interpreter::rlwnmx}, // rlwnmx
|
||||
|
||||
{20, Interpreter::rlwimix, {"rlwimix", OpType::Integer, FL_OUT_A | FL_IN_A | FL_IN_S | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{21, Interpreter::rlwinmx, {"rlwinmx", OpType::Integer, FL_OUT_A | FL_IN_S | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{23, Interpreter::rlwnmx, {"rlwnmx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{24, Interpreter::ori}, // ori
|
||||
{25, Interpreter::oris}, // oris
|
||||
{26, Interpreter::xori}, // xori
|
||||
{27, Interpreter::xoris}, // xoris
|
||||
{28, Interpreter::andi_rc}, // andi_rc
|
||||
{29, Interpreter::andis_rc}, // andis_rc
|
||||
|
||||
{24, Interpreter::ori, {"ori", OpType::Integer, FL_OUT_A | FL_IN_S, 1, 0, 0, 0}},
|
||||
{25, Interpreter::oris, {"oris", OpType::Integer, FL_OUT_A | FL_IN_S, 1, 0, 0, 0}},
|
||||
{26, Interpreter::xori, {"xori", OpType::Integer, FL_OUT_A | FL_IN_S, 1, 0, 0, 0}},
|
||||
{27, Interpreter::xoris, {"xoris", OpType::Integer, FL_OUT_A | FL_IN_S, 1, 0, 0, 0}},
|
||||
{28, Interpreter::andi_rc, {"andi_rc", OpType::Integer, FL_OUT_A | FL_IN_S | FL_SET_CR0, 1, 0, 0, 0}},
|
||||
{29, Interpreter::andis_rc, {"andis_rc", OpType::Integer, FL_OUT_A | FL_IN_S | FL_SET_CR0, 1, 0, 0, 0}},
|
||||
{32, Interpreter::lwz}, // lwz
|
||||
{33, Interpreter::lwzu}, // lwzu
|
||||
{34, Interpreter::lbz}, // lbz
|
||||
{35, Interpreter::lbzu}, // lbzu
|
||||
{40, Interpreter::lhz}, // lhz
|
||||
{41, Interpreter::lhzu}, // lhzu
|
||||
|
||||
{32, Interpreter::lwz, {"lwz", OpType::Load, FL_OUT_D | FL_IN_A0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{33, Interpreter::lwzu, {"lwzu", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{34, Interpreter::lbz, {"lbz", OpType::Load, FL_OUT_D | FL_IN_A0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{35, Interpreter::lbzu, {"lbzu", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{40, Interpreter::lhz, {"lhz", OpType::Load, FL_OUT_D | FL_IN_A0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{41, Interpreter::lhzu, {"lhzu", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{42, Interpreter::lha}, // lha
|
||||
{43, Interpreter::lhau}, // lhau
|
||||
|
||||
{42, Interpreter::lha, {"lha", OpType::Load, FL_OUT_D | FL_IN_A0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{43, Interpreter::lhau, {"lhau", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{44, Interpreter::sth}, // sth
|
||||
{45, Interpreter::sthu}, // sthu
|
||||
{36, Interpreter::stw}, // stw
|
||||
{37, Interpreter::stwu}, // stwu
|
||||
{38, Interpreter::stb}, // stb
|
||||
{39, Interpreter::stbu}, // stbu
|
||||
|
||||
{44, Interpreter::sth, {"sth", OpType::Store, FL_IN_A0 | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{45, Interpreter::sthu, {"sthu", OpType::Store, FL_OUT_A | FL_IN_A | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{36, Interpreter::stw, {"stw", OpType::Store, FL_IN_A0 | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{37, Interpreter::stwu, {"stwu", OpType::Store, FL_OUT_A | FL_IN_A | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{38, Interpreter::stb, {"stb", OpType::Store, FL_IN_A0 | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{39, Interpreter::stbu, {"stbu", OpType::Store, FL_OUT_A | FL_IN_A | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{46, Interpreter::lmw}, // lmw
|
||||
{47, Interpreter::stmw}, // stmw
|
||||
|
||||
{46, Interpreter::lmw, {"lmw", OpType::System, FL_EVIL | FL_IN_A0 | FL_LOADSTORE, 11, 0, 0, 0}},
|
||||
{47, Interpreter::stmw, {"stmw", OpType::System, FL_EVIL | FL_IN_A0 | FL_LOADSTORE, 11, 0, 0, 0}},
|
||||
{48, Interpreter::lfs}, // lfs
|
||||
{49, Interpreter::lfsu}, // lfsu
|
||||
{50, Interpreter::lfd}, // lfd
|
||||
{51, Interpreter::lfdu}, // lfdu
|
||||
|
||||
{48, Interpreter::lfs, {"lfs", OpType::LoadFP, FL_OUT_FLOAT_D | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{49, Interpreter::lfsu, {"lfsu", OpType::LoadFP, FL_OUT_FLOAT_D | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{50, Interpreter::lfd, {"lfd", OpType::LoadFP, FL_INOUT_FLOAT_D | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{51, Interpreter::lfdu, {"lfdu", OpType::LoadFP, FL_INOUT_FLOAT_D | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{52, Interpreter::stfs}, // stfs
|
||||
{53, Interpreter::stfsu}, // stfsu
|
||||
{54, Interpreter::stfd}, // stfd
|
||||
{55, Interpreter::stfdu}, // stfdu
|
||||
|
||||
{52, Interpreter::stfs, {"stfs", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_A0 | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{53, Interpreter::stfsu, {"stfsu", OpType::StoreFP, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{54, Interpreter::stfd, {"stfd", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_A0 | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{55, Interpreter::stfdu, {"stfdu", OpType::StoreFP, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{56, Interpreter::psq_l}, // psq_l
|
||||
{57, Interpreter::psq_lu}, // psq_lu
|
||||
{60, Interpreter::psq_st}, // psq_st
|
||||
{61, Interpreter::psq_stu}, // psq_stu
|
||||
|
||||
{56, Interpreter::psq_l, {"psq_l", OpType::LoadPS, FL_OUT_FLOAT_D | FL_IN_A0 | FL_USE_FPU | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{57, Interpreter::psq_lu, {"psq_lu", OpType::LoadPS, FL_OUT_FLOAT_D | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{60, Interpreter::psq_st, {"psq_st", OpType::StorePS, FL_IN_FLOAT_S | FL_IN_A0 | FL_USE_FPU | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{61, Interpreter::psq_stu, {"psq_stu", OpType::StorePS, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_A | FL_USE_FPU | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
|
||||
//missing: 0, 1, 2, 5, 6, 9, 22, 30, 62, 58
|
||||
// missing: 0, 1, 2, 5, 6, 9, 22, 30, 62, 58
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 13> table4 =
|
||||
{{ //SUBOP10
|
||||
{0, Interpreter::ps_cmpu0, {"ps_cmpu0", OpType::PS, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{32, Interpreter::ps_cmpo0, {"ps_cmpo0", OpType::PS, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{40, Interpreter::ps_neg, {"ps_neg", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{136, Interpreter::ps_nabs, {"ps_nabs", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{264, Interpreter::ps_abs, {"ps_abs", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{64, Interpreter::ps_cmpu1, {"ps_cmpu1", OpType::PS, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{72, Interpreter::ps_mr, {"ps_mr", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{96, Interpreter::ps_cmpo1, {"ps_cmpo1", OpType::PS, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{528, Interpreter::ps_merge00, {"ps_merge00", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_IN_FLOAT_AB_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{560, Interpreter::ps_merge01, {"ps_merge01", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_IN_FLOAT_AB_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{592, Interpreter::ps_merge10, {"ps_merge10", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_IN_FLOAT_AB_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{624, Interpreter::ps_merge11, {"ps_merge11", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_IN_FLOAT_AB_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 13> s_table4{{
|
||||
// SUBOP10
|
||||
{0, Interpreter::ps_cmpu0}, // ps_cmpu0
|
||||
{32, Interpreter::ps_cmpo0}, // ps_cmpo0
|
||||
{40, Interpreter::ps_neg}, // ps_neg
|
||||
{136, Interpreter::ps_nabs}, // ps_nabs
|
||||
{264, Interpreter::ps_abs}, // ps_abs
|
||||
{64, Interpreter::ps_cmpu1}, // ps_cmpu1
|
||||
{72, Interpreter::ps_mr}, // ps_mr
|
||||
{96, Interpreter::ps_cmpo1}, // ps_cmpo1
|
||||
{528, Interpreter::ps_merge00}, // ps_merge00
|
||||
{560, Interpreter::ps_merge01}, // ps_merge01
|
||||
{592, Interpreter::ps_merge10}, // ps_merge10
|
||||
{624, Interpreter::ps_merge11}, // ps_merge11
|
||||
|
||||
{1014, Interpreter::dcbz_l, {"dcbz_l", OpType::System, FL_IN_A0B | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{1014, Interpreter::dcbz_l}, // dcbz_l
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 17> table4_2 =
|
||||
{{
|
||||
{10, Interpreter::ps_sum0, {"ps_sum0", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{11, Interpreter::ps_sum1, {"ps_sum1", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{12, Interpreter::ps_muls0, {"ps_muls0", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{13, Interpreter::ps_muls1, {"ps_muls1", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{14, Interpreter::ps_madds0, {"ps_madds0", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{15, Interpreter::ps_madds1, {"ps_madds1", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{18, Interpreter::ps_div, {"ps_div", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 17, 0, 0, 0}},
|
||||
{20, Interpreter::ps_sub, {"ps_sub", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{21, Interpreter::ps_add, {"ps_add", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{23, Interpreter::ps_sel, {"ps_sel", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_IN_FLOAT_BC_BITEXACT | FL_RC_BIT_F | FL_USE_FPU | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{24, Interpreter::ps_res, {"ps_res", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 1, 0, 0, 0}},
|
||||
{25, Interpreter::ps_mul, {"ps_mul", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_AC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{26, Interpreter::ps_rsqrte, {"ps_rsqrte", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 2, 0, 0, 0}},
|
||||
{28, Interpreter::ps_msub, {"ps_msub", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{29, Interpreter::ps_madd, {"ps_madd", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{30, Interpreter::ps_nmsub, {"ps_nmsub", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{31, Interpreter::ps_nmadd, {"ps_nmadd", OpType::PS, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 17> s_table4_2{{
|
||||
{10, Interpreter::ps_sum0}, // ps_sum0
|
||||
{11, Interpreter::ps_sum1}, // ps_sum1
|
||||
{12, Interpreter::ps_muls0}, // ps_muls0
|
||||
{13, Interpreter::ps_muls1}, // ps_muls1
|
||||
{14, Interpreter::ps_madds0}, // ps_madds0
|
||||
{15, Interpreter::ps_madds1}, // ps_madds1
|
||||
{18, Interpreter::ps_div}, // ps_div
|
||||
{20, Interpreter::ps_sub}, // ps_sub
|
||||
{21, Interpreter::ps_add}, // ps_add
|
||||
{23, Interpreter::ps_sel}, // ps_sel
|
||||
{24, Interpreter::ps_res}, // ps_res
|
||||
{25, Interpreter::ps_mul}, // ps_mul
|
||||
{26, Interpreter::ps_rsqrte}, // ps_rsqrte
|
||||
{28, Interpreter::ps_msub}, // ps_msub
|
||||
{29, Interpreter::ps_madd}, // ps_madd
|
||||
{30, Interpreter::ps_nmsub}, // ps_nmsub
|
||||
{31, Interpreter::ps_nmadd}, // ps_nmadd
|
||||
}};
|
||||
|
||||
|
||||
static std::array<GekkoOPTemplate, 4> table4_3 =
|
||||
{{
|
||||
{6, Interpreter::psq_lx, {"psq_lx", OpType::LoadPS, FL_OUT_FLOAT_D | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{7, Interpreter::psq_stx, {"psq_stx", OpType::StorePS, FL_IN_FLOAT_S | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{38, Interpreter::psq_lux, {"psq_lux", OpType::LoadPS, FL_OUT_FLOAT_D | FL_OUT_A | FL_IN_AB | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{39, Interpreter::psq_stux, {"psq_stux", OpType::StorePS, FL_IN_FLOAT_S | FL_OUT_A | FL_IN_AB | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 4> s_table4_3{{
|
||||
{6, Interpreter::psq_lx}, // psq_lx
|
||||
{7, Interpreter::psq_stx}, // psq_stx
|
||||
{38, Interpreter::psq_lux}, // psq_lux
|
||||
{39, Interpreter::psq_stux}, // psq_stux
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 13> table19 =
|
||||
{{
|
||||
{528, Interpreter::bcctrx, {"bcctrx", OpType::Branch, FL_ENDBLOCK | FL_READ_CR_BI, 1, 0, 0, 0}},
|
||||
{16, Interpreter::bclrx, {"bclrx", OpType::Branch, FL_ENDBLOCK | FL_READ_CR_BI, 1, 0, 0, 0}},
|
||||
{257, Interpreter::crand, {"crand", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{129, Interpreter::crandc, {"crandc", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{289, Interpreter::creqv, {"creqv", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{225, Interpreter::crnand, {"crnand", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{33, Interpreter::crnor, {"crnor", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{449, Interpreter::cror, {"cror", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{417, Interpreter::crorc, {"crorc", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
{193, Interpreter::crxor, {"crxor", OpType::CR, FL_EVIL, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 13> s_table19{{
|
||||
{528, Interpreter::bcctrx}, // bcctrx
|
||||
{16, Interpreter::bclrx}, // bclrx
|
||||
{257, Interpreter::crand}, // crand
|
||||
{129, Interpreter::crandc}, // crandc
|
||||
{289, Interpreter::creqv}, // creqv
|
||||
{225, Interpreter::crnand}, // crnand
|
||||
{33, Interpreter::crnor}, // crnor
|
||||
{449, Interpreter::cror}, // cror
|
||||
{417, Interpreter::crorc}, // crorc
|
||||
{193, Interpreter::crxor}, // crxor
|
||||
|
||||
{150, Interpreter::isync, {"isync", OpType::InstructionCache, FL_EVIL, 1, 0, 0, 0}},
|
||||
{0, Interpreter::mcrf, {"mcrf", OpType::System, FL_EVIL | FL_SET_CRn | FL_READ_CRn, 1, 0, 0, 0}},
|
||||
{150, Interpreter::isync}, // isync
|
||||
{0, Interpreter::mcrf}, // mcrf
|
||||
|
||||
{50, Interpreter::rfi, {"rfi", OpType::System, FL_ENDBLOCK | FL_CHECKEXCEPTIONS | FL_PROGRAMEXCEPTION, 2, 0, 0, 0}},
|
||||
{50, Interpreter::rfi}, // rfi
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 107> table31 =
|
||||
{{
|
||||
{266, Interpreter::addx, {"addx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{778, Interpreter::addx, {"addox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{10, Interpreter::addcx, {"addcx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{522, Interpreter::addcx, {"addcox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{138, Interpreter::addex, {"addex", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{650, Interpreter::addex, {"addeox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{234, Interpreter::addmex, {"addmex", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{746, Interpreter::addmex, {"addmeox", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{202, Interpreter::addzex, {"addzex", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{714, Interpreter::addzex, {"addzeox", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{491, Interpreter::divwx, {"divwx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 40, 0, 0, 0}},
|
||||
{1003, Interpreter::divwx, {"divwox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT | FL_SET_OE, 40, 0, 0, 0}},
|
||||
{459, Interpreter::divwux, {"divwux", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 40, 0, 0, 0}},
|
||||
{971, Interpreter::divwux, {"divwuox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT | FL_SET_OE, 40, 0, 0, 0}},
|
||||
{75, Interpreter::mulhwx, {"mulhwx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 5, 0, 0, 0}},
|
||||
{11, Interpreter::mulhwux, {"mulhwux", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 5, 0, 0, 0}},
|
||||
{235, Interpreter::mullwx, {"mullwx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 5, 0, 0, 0}},
|
||||
{747, Interpreter::mullwx, {"mullwox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT | FL_SET_OE, 5, 0, 0, 0}},
|
||||
{104, Interpreter::negx, {"negx", OpType::Integer, FL_OUT_D | FL_IN_A | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{616, Interpreter::negx, {"negox", OpType::Integer, FL_OUT_D | FL_IN_A | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{40, Interpreter::subfx, {"subfx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{552, Interpreter::subfx, {"subfox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{8, Interpreter::subfcx, {"subfcx", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{520, Interpreter::subfcx, {"subfcox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{136, Interpreter::subfex, {"subfex", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{648, Interpreter::subfex, {"subfeox", OpType::Integer, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{232, Interpreter::subfmex, {"subfmex", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{744, Interpreter::subfmex, {"subfmeox",OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
{200, Interpreter::subfzex, {"subfzex", OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{712, Interpreter::subfzex, {"subfzeox",OpType::Integer, FL_OUT_D | FL_IN_A | FL_READ_CA | FL_SET_CA | FL_RC_BIT | FL_SET_OE, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 107> s_table31{{
|
||||
{266, Interpreter::addx}, // addx
|
||||
{778, Interpreter::addx}, // addox
|
||||
{10, Interpreter::addcx}, // addcx
|
||||
{522, Interpreter::addcx}, // addcox
|
||||
{138, Interpreter::addex}, // addex
|
||||
{650, Interpreter::addex}, // addeox
|
||||
{234, Interpreter::addmex}, // addmex
|
||||
{746, Interpreter::addmex}, // addmeox
|
||||
{202, Interpreter::addzex}, // addzex
|
||||
{714, Interpreter::addzex}, // addzeox
|
||||
{491, Interpreter::divwx}, // divwx
|
||||
{1003, Interpreter::divwx}, // divwox
|
||||
{459, Interpreter::divwux}, // divwux
|
||||
{971, Interpreter::divwux}, // divwuox
|
||||
{75, Interpreter::mulhwx}, // mulhwx
|
||||
{11, Interpreter::mulhwux}, // mulhwux
|
||||
{235, Interpreter::mullwx}, // mullwx
|
||||
{747, Interpreter::mullwx}, // mullwox
|
||||
{104, Interpreter::negx}, // negx
|
||||
{616, Interpreter::negx}, // negox
|
||||
{40, Interpreter::subfx}, // subfx
|
||||
{552, Interpreter::subfx}, // subfox
|
||||
{8, Interpreter::subfcx}, // subfcx
|
||||
{520, Interpreter::subfcx}, // subfcox
|
||||
{136, Interpreter::subfex}, // subfex
|
||||
{648, Interpreter::subfex}, // subfeox
|
||||
{232, Interpreter::subfmex}, // subfmex
|
||||
{744, Interpreter::subfmex}, // subfmeox
|
||||
{200, Interpreter::subfzex}, // subfzex
|
||||
{712, Interpreter::subfzex}, // subfzeox
|
||||
|
||||
{28, Interpreter::andx, {"andx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{60, Interpreter::andcx, {"andcx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{444, Interpreter::orx, {"orx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{124, Interpreter::norx, {"norx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{316, Interpreter::xorx, {"xorx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{412, Interpreter::orcx, {"orcx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{476, Interpreter::nandx, {"nandx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{284, Interpreter::eqvx, {"eqvx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{0, Interpreter::cmp, {"cmp", OpType::Integer, FL_IN_AB | FL_SET_CRn, 1, 0, 0, 0}},
|
||||
{32, Interpreter::cmpl, {"cmpl", OpType::Integer, FL_IN_AB | FL_SET_CRn, 1, 0, 0, 0}},
|
||||
{26, Interpreter::cntlzwx, {"cntlzwx",OpType::Integer, FL_OUT_A | FL_IN_S | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{922, Interpreter::extshx, {"extshx", OpType::Integer, FL_OUT_A | FL_IN_S | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{954, Interpreter::extsbx, {"extsbx", OpType::Integer, FL_OUT_A | FL_IN_S | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{536, Interpreter::srwx, {"srwx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{792, Interpreter::srawx, {"srawx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{824, Interpreter::srawix, {"srawix", OpType::Integer, FL_OUT_A | FL_IN_S | FL_SET_CA | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{24, Interpreter::slwx, {"slwx", OpType::Integer, FL_OUT_A | FL_IN_SB | FL_RC_BIT, 1, 0, 0, 0}},
|
||||
{28, Interpreter::andx}, // andx
|
||||
{60, Interpreter::andcx}, // andcx
|
||||
{444, Interpreter::orx}, // orx
|
||||
{124, Interpreter::norx}, // norx
|
||||
{316, Interpreter::xorx}, // xorx
|
||||
{412, Interpreter::orcx}, // orcx
|
||||
{476, Interpreter::nandx}, // nandx
|
||||
{284, Interpreter::eqvx}, // eqvx
|
||||
{0, Interpreter::cmp}, // cmp
|
||||
{32, Interpreter::cmpl}, // cmpl
|
||||
{26, Interpreter::cntlzwx}, // cntlzwx
|
||||
{922, Interpreter::extshx}, // extshx
|
||||
{954, Interpreter::extsbx}, // extsbx
|
||||
{536, Interpreter::srwx}, // srwx
|
||||
{792, Interpreter::srawx}, // srawx
|
||||
{824, Interpreter::srawix}, // srawix
|
||||
{24, Interpreter::slwx}, // slwx
|
||||
|
||||
{54, Interpreter::dcbst, {"dcbst", OpType::DataCache, FL_IN_A0B | FL_LOADSTORE, 5, 0, 0, 0}},
|
||||
{86, Interpreter::dcbf, {"dcbf", OpType::DataCache, FL_IN_A0B | FL_LOADSTORE, 5, 0, 0, 0}},
|
||||
{246, Interpreter::dcbtst, {"dcbtst", OpType::DataCache, 0, 2, 0, 0, 0}},
|
||||
{278, Interpreter::dcbt, {"dcbt", OpType::DataCache, 0, 2, 0, 0, 0}},
|
||||
{470, Interpreter::dcbi, {"dcbi", OpType::DataCache, FL_IN_A0B | FL_LOADSTORE | FL_PROGRAMEXCEPTION, 5, 0, 0, 0}},
|
||||
{758, Interpreter::dcba, {"dcba", OpType::DataCache, 0, 5, 0, 0, 0}},
|
||||
{1014, Interpreter::dcbz, {"dcbz", OpType::DataCache, FL_IN_A0B | FL_LOADSTORE, 5, 0, 0, 0}},
|
||||
{54, Interpreter::dcbst}, // dcbst
|
||||
{86, Interpreter::dcbf}, // dcbf
|
||||
{246, Interpreter::dcbtst}, // dcbtst
|
||||
{278, Interpreter::dcbt}, // dcbt
|
||||
{470, Interpreter::dcbi}, // dcbi
|
||||
{758, Interpreter::dcba}, // dcba
|
||||
{1014, Interpreter::dcbz}, // dcbz
|
||||
|
||||
//load word
|
||||
{23, Interpreter::lwzx, {"lwzx", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{55, Interpreter::lwzux, {"lwzux", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load word
|
||||
{23, Interpreter::lwzx}, // lwzx
|
||||
{55, Interpreter::lwzux}, // lwzux
|
||||
|
||||
//load halfword
|
||||
{279, Interpreter::lhzx, {"lhzx", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{311, Interpreter::lhzux, {"lhzux", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load halfword
|
||||
{279, Interpreter::lhzx}, // lhzx
|
||||
{311, Interpreter::lhzux}, // lhzux
|
||||
|
||||
//load halfword signextend
|
||||
{343, Interpreter::lhax, {"lhax", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{375, Interpreter::lhaux, {"lhaux", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load halfword signextend
|
||||
{343, Interpreter::lhax}, // lhax
|
||||
{375, Interpreter::lhaux}, // lhaux
|
||||
|
||||
//load byte
|
||||
{87, Interpreter::lbzx, {"lbzx", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{119, Interpreter::lbzux, {"lbzux", OpType::Load, FL_OUT_D | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load byte
|
||||
{87, Interpreter::lbzx}, // lbzx
|
||||
{119, Interpreter::lbzux}, // lbzux
|
||||
|
||||
//load byte reverse
|
||||
{534, Interpreter::lwbrx, {"lwbrx", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{790, Interpreter::lhbrx, {"lhbrx", OpType::Load, FL_OUT_D | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load byte reverse
|
||||
{534, Interpreter::lwbrx}, // lwbrx
|
||||
{790, Interpreter::lhbrx}, // lhbrx
|
||||
|
||||
// Conditional load/store (Wii SMP)
|
||||
{150, Interpreter::stwcxd, {"stwcxd", OpType::Store, FL_EVIL | FL_IN_S | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{20, Interpreter::lwarx, {"lwarx", OpType::Load, FL_EVIL | FL_OUT_D | FL_IN_A0B | FL_SET_CR0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// Conditional load/store (Wii SMP)
|
||||
{150, Interpreter::stwcxd}, // stwcxd
|
||||
{20, Interpreter::lwarx}, // lwarx
|
||||
|
||||
//load string (Inst these)
|
||||
{533, Interpreter::lswx, {"lswx", OpType::Load, FL_EVIL | FL_IN_A0B | FL_OUT_D | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{597, Interpreter::lswi, {"lswi", OpType::Load, FL_EVIL | FL_IN_A0 | FL_OUT_D | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// load string (Inst these)
|
||||
{533, Interpreter::lswx}, // lswx
|
||||
{597, Interpreter::lswi}, // lswi
|
||||
|
||||
//store word
|
||||
{151, Interpreter::stwx, {"stwx", OpType::Store, FL_IN_S | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{183, Interpreter::stwux, {"stwux", OpType::Store, FL_IN_S | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// store word
|
||||
{151, Interpreter::stwx}, // stwx
|
||||
{183, Interpreter::stwux}, // stwux
|
||||
|
||||
//store halfword
|
||||
{407, Interpreter::sthx, {"sthx", OpType::Store, FL_IN_S | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{439, Interpreter::sthux, {"sthux", OpType::Store, FL_IN_S | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// store halfword
|
||||
{407, Interpreter::sthx}, // sthx
|
||||
{439, Interpreter::sthux}, // sthux
|
||||
|
||||
//store byte
|
||||
{215, Interpreter::stbx, {"stbx", OpType::Store, FL_IN_S | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{247, Interpreter::stbux, {"stbux", OpType::Store, FL_IN_S | FL_OUT_A | FL_IN_AB | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// store byte
|
||||
{215, Interpreter::stbx}, // stbx
|
||||
{247, Interpreter::stbux}, // stbux
|
||||
|
||||
//store bytereverse
|
||||
{662, Interpreter::stwbrx, {"stwbrx", OpType::Store, FL_IN_S | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{918, Interpreter::sthbrx, {"sthbrx", OpType::Store, FL_IN_S | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// store bytereverse
|
||||
{662, Interpreter::stwbrx}, // stwbrx
|
||||
{918, Interpreter::sthbrx}, // sthbrx
|
||||
|
||||
{661, Interpreter::stswx, {"stswx", OpType::Store, FL_EVIL | FL_IN_A0B | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{725, Interpreter::stswi, {"stswi", OpType::Store, FL_EVIL | FL_IN_A0 | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{661, Interpreter::stswx}, // stswx
|
||||
{725, Interpreter::stswi}, // stswi
|
||||
|
||||
// fp load/store
|
||||
{535, Interpreter::lfsx, {"lfsx", OpType::LoadFP, FL_OUT_FLOAT_D | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{567, Interpreter::lfsux, {"lfsux", OpType::LoadFP, FL_OUT_FLOAT_D | FL_IN_AB | FL_OUT_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{599, Interpreter::lfdx, {"lfdx", OpType::LoadFP, FL_INOUT_FLOAT_D | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{631, Interpreter::lfdux, {"lfdux", OpType::LoadFP, FL_INOUT_FLOAT_D | FL_IN_AB | FL_OUT_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
// fp load/store
|
||||
{535, Interpreter::lfsx}, // lfsx
|
||||
{567, Interpreter::lfsux}, // lfsux
|
||||
{599, Interpreter::lfdx}, // lfdx
|
||||
{631, Interpreter::lfdux}, // lfdux
|
||||
|
||||
{663, Interpreter::stfsx, {"stfsx", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{695, Interpreter::stfsux, {"stfsux", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_AB | FL_OUT_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{727, Interpreter::stfdx, {"stfdx", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{759, Interpreter::stfdux, {"stfdux", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_AB | FL_OUT_A | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{983, Interpreter::stfiwx, {"stfiwx", OpType::StoreFP, FL_IN_FLOAT_S | FL_IN_A0B | FL_USE_FPU | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{663, Interpreter::stfsx}, // stfsx
|
||||
{695, Interpreter::stfsux}, // stfsux
|
||||
{727, Interpreter::stfdx}, // stfdx
|
||||
{759, Interpreter::stfdux}, // stfdux
|
||||
{983, Interpreter::stfiwx}, // stfiwx
|
||||
|
||||
{19, Interpreter::mfcr, {"mfcr", OpType::System, FL_OUT_D | FL_READ_ALL_CR, 1, 0, 0, 0}},
|
||||
{83, Interpreter::mfmsr, {"mfmsr", OpType::System, FL_OUT_D | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{144, Interpreter::mtcrf, {"mtcrf", OpType::System, FL_IN_S | FL_SET_ALL_CR | FL_READ_ALL_CR, 1, 0, 0, 0}},
|
||||
{146, Interpreter::mtmsr, {"mtmsr", OpType::System, FL_IN_S | FL_ENDBLOCK | FL_PROGRAMEXCEPTION | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{210, Interpreter::mtsr, {"mtsr", OpType::System, FL_IN_S | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{242, Interpreter::mtsrin, {"mtsrin", OpType::System, FL_IN_SB | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{339, Interpreter::mfspr, {"mfspr", OpType::SPR, FL_OUT_D | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{467, Interpreter::mtspr, {"mtspr", OpType::SPR, FL_IN_S | FL_PROGRAMEXCEPTION, 2, 0, 0, 0}},
|
||||
{371, Interpreter::mftb, {"mftb", OpType::System, FL_OUT_D | FL_TIMER | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{512, Interpreter::mcrxr, {"mcrxr", OpType::System, FL_SET_CRn | FL_READ_CA | FL_SET_CA, 1, 0, 0, 0}},
|
||||
{595, Interpreter::mfsr, {"mfsr", OpType::System, FL_OUT_D | FL_PROGRAMEXCEPTION, 3, 0, 0, 0}},
|
||||
{659, Interpreter::mfsrin, {"mfsrin", OpType::System, FL_OUT_D | FL_IN_B | FL_PROGRAMEXCEPTION, 3, 0, 0, 0}},
|
||||
{19, Interpreter::mfcr}, // mfcr
|
||||
{83, Interpreter::mfmsr}, // mfmsr
|
||||
{144, Interpreter::mtcrf}, // mtcrf
|
||||
{146, Interpreter::mtmsr}, // mtmsr
|
||||
{210, Interpreter::mtsr}, // mtsr
|
||||
{242, Interpreter::mtsrin}, // mtsrin
|
||||
{339, Interpreter::mfspr}, // mfspr
|
||||
{467, Interpreter::mtspr}, // mtspr
|
||||
{371, Interpreter::mftb}, // mftb
|
||||
{512, Interpreter::mcrxr}, // mcrxr
|
||||
{595, Interpreter::mfsr}, // mfsr
|
||||
{659, Interpreter::mfsrin}, // mfsrin
|
||||
|
||||
{4, Interpreter::tw, {"tw", OpType::System, FL_IN_AB | FL_ENDBLOCK, 2, 0, 0, 0}},
|
||||
{598, Interpreter::sync, {"sync", OpType::System, 0, 3, 0, 0, 0}},
|
||||
{982, Interpreter::icbi, {"icbi", OpType::System, FL_IN_A0B | FL_ENDBLOCK | FL_LOADSTORE, 4, 0, 0, 0}},
|
||||
{4, Interpreter::tw}, // tw
|
||||
{598, Interpreter::sync}, // sync
|
||||
{982, Interpreter::icbi}, // icbi
|
||||
|
||||
// Unused instructions on GC
|
||||
{310, Interpreter::eciwx, {"eciwx", OpType::System, FL_IN_A0B | FL_OUT_D | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{438, Interpreter::ecowx, {"ecowx", OpType::System, FL_IN_A0B | FL_IN_S | FL_LOADSTORE, 1, 0, 0, 0}},
|
||||
{854, Interpreter::eieio, {"eieio", OpType::System, 0, 1, 0, 0, 0}},
|
||||
{306, Interpreter::tlbie, {"tlbie", OpType::System, FL_IN_B | FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
{566, Interpreter::tlbsync, {"tlbsync", OpType::System, FL_PROGRAMEXCEPTION, 1, 0, 0, 0}},
|
||||
// Unused instructions on GC
|
||||
{310, Interpreter::eciwx}, // eciwx
|
||||
{438, Interpreter::ecowx}, // ecowx
|
||||
{854, Interpreter::eieio}, // eieio
|
||||
{306, Interpreter::tlbie}, // tlbie
|
||||
{566, Interpreter::tlbsync}, // tlbsync
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 9> table59 =
|
||||
{{
|
||||
{18, Interpreter::fdivsx, {"fdivsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 17, 0, 0, 0}}, // TODO
|
||||
{20, Interpreter::fsubsx, {"fsubsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{21, Interpreter::faddsx, {"faddsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{24, Interpreter::fresx, {"fresx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 1, 0, 0, 0}},
|
||||
{25, Interpreter::fmulsx, {"fmulsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_AC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{28, Interpreter::fmsubsx, {"fmsubsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{29, Interpreter::fmaddsx, {"fmaddsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{30, Interpreter::fnmsubsx, {"fnmsubsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{31, Interpreter::fnmaddsx, {"fnmaddsx", OpType::SingleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 9> s_table59{{
|
||||
{18, Interpreter::fdivsx}, // fdivsx // TODO
|
||||
{20, Interpreter::fsubsx}, // fsubsx
|
||||
{21, Interpreter::faddsx}, // faddsx
|
||||
{24, Interpreter::fresx}, // fresx
|
||||
{25, Interpreter::fmulsx}, // fmulsx
|
||||
{28, Interpreter::fmsubsx}, // fmsubsx
|
||||
{29, Interpreter::fmaddsx}, // fmaddsx
|
||||
{30, Interpreter::fnmsubsx}, // fnmsubsx
|
||||
{31, Interpreter::fnmaddsx}, // fnmaddsx
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 15> table63 =
|
||||
{{
|
||||
{264, Interpreter::fabsx, {"fabsx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 15> s_table63{{
|
||||
{264, Interpreter::fabsx}, // fabsx
|
||||
{32, Interpreter::fcmpo}, // fcmpo
|
||||
{0, Interpreter::fcmpu}, // fcmpu
|
||||
{14, Interpreter::fctiwx}, // fctiwx
|
||||
{15, Interpreter::fctiwzx}, // fctiwzx
|
||||
{72, Interpreter::fmrx}, // fmrx
|
||||
{136, Interpreter::fnabsx}, // fnabsx
|
||||
{40, Interpreter::fnegx}, // fnegx
|
||||
{12, Interpreter::frspx}, // frspx
|
||||
|
||||
// FIXME: fcmp modifies the FPRF flags, but if the flags are clobbered later,
|
||||
// we don't actually need to calculate or store them here. So FL_READ_FPRF and FL_SET_FPRF is not
|
||||
// an ideal representation of fcmp's effect on FPRF flags and might result in
|
||||
// slightly sub-optimal code.
|
||||
{32, Interpreter::fcmpo, {"fcmpo", OpType::DoubleFP, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{0, Interpreter::fcmpu, {"fcmpu", OpType::DoubleFP, FL_IN_FLOAT_AB | FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
|
||||
{14, Interpreter::fctiwx, {"fctiwx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{15, Interpreter::fctiwzx, {"fctiwzx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{72, Interpreter::fmrx, {"fmrx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_IN_FLOAT_B_BITEXACT | FL_RC_BIT_F | FL_USE_FPU, 1, 0, 0, 0}},
|
||||
{136, Interpreter::fnabsx, {"fnabsx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_IN_FLOAT_B_BITEXACT | FL_USE_FPU, 1, 0, 0, 0}},
|
||||
{40, Interpreter::fnegx, {"fnegx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_IN_FLOAT_B_BITEXACT | FL_USE_FPU, 1, 0, 0, 0}},
|
||||
{12, Interpreter::frspx, {"frspx", OpType::DoubleFP, FL_OUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
|
||||
{64, Interpreter::mcrfs, {"mcrfs", OpType::SystemFP, FL_SET_CRn | FL_USE_FPU | FL_READ_FPRF, 1, 0, 0, 0}},
|
||||
{583, Interpreter::mffsx, {"mffsx", OpType::SystemFP, FL_RC_BIT_F | FL_INOUT_FLOAT_D | FL_USE_FPU | FL_READ_FPRF, 1, 0, 0, 0}},
|
||||
{70, Interpreter::mtfsb0x, {"mtfsb0x", OpType::SystemFP, FL_RC_BIT_F | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF, 3, 0, 0, 0}},
|
||||
{38, Interpreter::mtfsb1x, {"mtfsb1x", OpType::SystemFP, FL_RC_BIT_F | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 3, 0, 0, 0}},
|
||||
{134, Interpreter::mtfsfix, {"mtfsfix", OpType::SystemFP, FL_RC_BIT_F | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 3, 0, 0, 0}},
|
||||
{711, Interpreter::mtfsfx, {"mtfsfx", OpType::SystemFP, FL_RC_BIT_F | FL_IN_FLOAT_B | FL_USE_FPU | FL_READ_FPRF | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 3, 0, 0, 0}},
|
||||
{64, Interpreter::mcrfs}, // mcrfs
|
||||
{583, Interpreter::mffsx}, // mffsx
|
||||
{70, Interpreter::mtfsb0x}, // mtfsb0x
|
||||
{38, Interpreter::mtfsb1x}, // mtfsb1x
|
||||
{134, Interpreter::mtfsfix}, // mtfsfix
|
||||
{711, Interpreter::mtfsfx}, // mtfsfx
|
||||
}};
|
||||
|
||||
static std::array<GekkoOPTemplate, 10> table63_2 =
|
||||
{{
|
||||
{18, Interpreter::fdivx, {"fdivx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 31, 0, 0, 0}},
|
||||
{20, Interpreter::fsubx, {"fsubx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{21, Interpreter::faddx, {"faddx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_AB | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{23, Interpreter::fselx, {"fselx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_IN_FLOAT_BC_BITEXACT | FL_RC_BIT_F | FL_USE_FPU, 1, 0, 0, 0}},
|
||||
{25, Interpreter::fmulx, {"fmulx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_AC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{26, Interpreter::frsqrtex, {"frsqrtex", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_B | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION | FL_FLOAT_DIV, 1, 0, 0, 0}},
|
||||
{28, Interpreter::fmsubx, {"fmsubx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{29, Interpreter::fmaddx, {"fmaddx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{30, Interpreter::fnmsubx, {"fnmsubx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
{31, Interpreter::fnmaddx, {"fnmaddx", OpType::DoubleFP, FL_INOUT_FLOAT_D | FL_IN_FLOAT_ABC | FL_RC_BIT_F | FL_USE_FPU | FL_SET_FPRF | FL_FLOAT_EXCEPTION, 1, 0, 0, 0}},
|
||||
constexpr std::array<InterpreterOpTemplate, 10> s_table63_2{{
|
||||
{18, Interpreter::fdivx}, // fdivx
|
||||
{20, Interpreter::fsubx}, // fsubx
|
||||
{21, Interpreter::faddx}, // faddx
|
||||
{23, Interpreter::fselx}, // fselx
|
||||
{25, Interpreter::fmulx}, // fmulx
|
||||
{26, Interpreter::frsqrtex}, // frsqrtex
|
||||
{28, Interpreter::fmsubx}, // fmsubx
|
||||
{29, Interpreter::fmaddx}, // fmaddx
|
||||
{30, Interpreter::fnmsubx}, // fnmsubx
|
||||
{31, Interpreter::fnmaddx}, // fnmaddx
|
||||
}};
|
||||
// clang-format on
|
||||
|
||||
constexpr size_t TotalInstructionFunctionCount()
|
||||
constexpr std::array<Interpreter::Instruction, 64> s_interpreter_op_table = []() consteval
|
||||
{
|
||||
return primarytable.size() + table4_2.size() + table4_3.size() + table4.size() + table31.size() +
|
||||
table19.size() + table59.size() + table63.size() + table63_2.size();
|
||||
std::array<Interpreter::Instruction, 64> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
for (auto& tpl : s_primary_table)
|
||||
{
|
||||
ASSERT(table[tpl.opcode] == Interpreter::unknown_instruction);
|
||||
table[tpl.opcode] = tpl.fn;
|
||||
};
|
||||
return table;
|
||||
}
|
||||
();
|
||||
constexpr std::array<Interpreter::Instruction, 1024> s_interpreter_op_table4 = []() consteval
|
||||
{
|
||||
std::array<Interpreter::Instruction, 1024> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
const u32 fill = i << 5;
|
||||
for (const auto& tpl : s_table4_2)
|
||||
{
|
||||
const u32 op = fill + tpl.opcode;
|
||||
ASSERT(table[op] == Interpreter::unknown_instruction);
|
||||
table[op] = tpl.fn;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
const u32 fill = i << 6;
|
||||
for (const auto& tpl : s_table4_3)
|
||||
{
|
||||
const u32 op = fill + tpl.opcode;
|
||||
ASSERT(table[op] == Interpreter::unknown_instruction);
|
||||
table[op] = tpl.fn;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& tpl : s_table4)
|
||||
{
|
||||
const u32 op = tpl.opcode;
|
||||
ASSERT(table[op] == Interpreter::unknown_instruction);
|
||||
table[op] = tpl.fn;
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
();
|
||||
constexpr std::array<Interpreter::Instruction, 1024> s_interpreter_op_table19 = []() consteval
|
||||
{
|
||||
std::array<Interpreter::Instruction, 1024> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
for (auto& tpl : s_table19)
|
||||
{
|
||||
ASSERT(table[tpl.opcode] == Interpreter::unknown_instruction);
|
||||
table[tpl.opcode] = tpl.fn;
|
||||
};
|
||||
return table;
|
||||
}
|
||||
();
|
||||
constexpr std::array<Interpreter::Instruction, 1024> s_interpreter_op_table31 = []() consteval
|
||||
{
|
||||
std::array<Interpreter::Instruction, 1024> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
for (auto& tpl : s_table31)
|
||||
{
|
||||
ASSERT(table[tpl.opcode] == Interpreter::unknown_instruction);
|
||||
table[tpl.opcode] = tpl.fn;
|
||||
};
|
||||
return table;
|
||||
}
|
||||
();
|
||||
constexpr std::array<Interpreter::Instruction, 32> s_interpreter_op_table59 = []() consteval
|
||||
{
|
||||
std::array<Interpreter::Instruction, 32> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
for (auto& tpl : s_table59)
|
||||
{
|
||||
ASSERT(table[tpl.opcode] == Interpreter::unknown_instruction);
|
||||
table[tpl.opcode] = tpl.fn;
|
||||
};
|
||||
return table;
|
||||
}
|
||||
();
|
||||
constexpr std::array<Interpreter::Instruction, 1024> s_interpreter_op_table63 = []() consteval
|
||||
{
|
||||
std::array<Interpreter::Instruction, 1024> table{};
|
||||
Common::Fill(table, Interpreter::unknown_instruction);
|
||||
for (auto& tpl : s_table63)
|
||||
{
|
||||
ASSERT(table[tpl.opcode] == Interpreter::unknown_instruction);
|
||||
table[tpl.opcode] = tpl.fn;
|
||||
};
|
||||
|
||||
for (u32 i = 0; i < 32; i++)
|
||||
{
|
||||
const u32 fill = i << 5;
|
||||
for (const auto& tpl : s_table63_2)
|
||||
{
|
||||
const u32 op = fill + tpl.opcode;
|
||||
ASSERT(table[op] == Interpreter::unknown_instruction);
|
||||
table[op] = tpl.fn;
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
();
|
||||
|
||||
Interpreter::Instruction Interpreter::GetInterpreterOp(UGeckoInstruction inst)
|
||||
{
|
||||
// Check for the appropriate subtable ahead of time.
|
||||
// (This is used by the cached interpreter and JIT, and called once per instruction, so spending a
|
||||
// bit of extra time to optimise is worthwhile)
|
||||
Interpreter::Instruction result = s_interpreter_op_table[inst.OPCD];
|
||||
if (result == Interpreter::RunTable4)
|
||||
return s_interpreter_op_table4[inst.SUBOP10];
|
||||
else if (result == Interpreter::RunTable19)
|
||||
return s_interpreter_op_table19[inst.SUBOP10];
|
||||
else if (result == Interpreter::RunTable31)
|
||||
return s_interpreter_op_table31[inst.SUBOP10];
|
||||
else if (result == Interpreter::RunTable59)
|
||||
return s_interpreter_op_table59[inst.SUBOP5];
|
||||
else if (result == Interpreter::RunTable63)
|
||||
return s_interpreter_op_table63[inst.SUBOP10];
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
||||
static_assert(TotalInstructionFunctionCount() < m_allInstructions.size(),
|
||||
"m_allInstructions is too small");
|
||||
|
||||
void Interpreter::InitializeInstructionTables()
|
||||
void Interpreter::RunInterpreterOp(UGeckoInstruction inst)
|
||||
{
|
||||
// once initialized, tables are read-only
|
||||
static bool initialized = false;
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
// clear
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
m_op_table[i] = Interpreter::unknown_instruction;
|
||||
m_infoTable[i] = &unknownopinfo;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
m_op_table59[i] = Interpreter::unknown_instruction;
|
||||
m_infoTable59[i] = &unknownopinfo;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
m_op_table4[i] = Interpreter::unknown_instruction;
|
||||
m_op_table19[i] = Interpreter::unknown_instruction;
|
||||
m_op_table31[i] = Interpreter::unknown_instruction;
|
||||
m_op_table63[i] = Interpreter::unknown_instruction;
|
||||
m_infoTable4[i] = &unknownopinfo;
|
||||
m_infoTable19[i] = &unknownopinfo;
|
||||
m_infoTable31[i] = &unknownopinfo;
|
||||
m_infoTable63[i] = &unknownopinfo;
|
||||
}
|
||||
|
||||
for (auto& tpl : primarytable)
|
||||
{
|
||||
m_op_table[tpl.opcode] = tpl.Inst;
|
||||
m_infoTable[tpl.opcode] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
int fill = i << 5;
|
||||
for (auto& tpl : table4_2)
|
||||
{
|
||||
int op = fill + tpl.opcode;
|
||||
m_op_table4[op] = tpl.Inst;
|
||||
m_infoTable4[op] = &tpl.opinfo;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int fill = i << 6;
|
||||
for (auto& tpl : table4_3)
|
||||
{
|
||||
int op = fill + tpl.opcode;
|
||||
m_op_table4[op] = tpl.Inst;
|
||||
m_infoTable4[op] = &tpl.opinfo;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& tpl : table4)
|
||||
{
|
||||
int op = tpl.opcode;
|
||||
m_op_table4[op] = tpl.Inst;
|
||||
m_infoTable4[op] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (auto& tpl : table31)
|
||||
{
|
||||
int op = tpl.opcode;
|
||||
m_op_table31[op] = tpl.Inst;
|
||||
m_infoTable31[op] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (auto& tpl : table19)
|
||||
{
|
||||
int op = tpl.opcode;
|
||||
m_op_table19[op] = tpl.Inst;
|
||||
m_infoTable19[op] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (auto& tpl : table59)
|
||||
{
|
||||
int op = tpl.opcode;
|
||||
m_op_table59[op] = tpl.Inst;
|
||||
m_infoTable59[op] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (auto& tpl : table63)
|
||||
{
|
||||
int op = tpl.opcode;
|
||||
m_op_table63[op] = tpl.Inst;
|
||||
m_infoTable63[op] = &tpl.opinfo;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
int fill = i << 5;
|
||||
for (auto& tpl : table63_2)
|
||||
{
|
||||
int op = fill + tpl.opcode;
|
||||
m_op_table63[op] = tpl.Inst;
|
||||
m_infoTable63[op] = &tpl.opinfo;
|
||||
}
|
||||
}
|
||||
|
||||
m_numInstructions = 0;
|
||||
for (auto& tpl : primarytable)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table4_2)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table4_3)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table4)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table31)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table19)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table59)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table63)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
for (auto& tpl : table63_2)
|
||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||
|
||||
initialized = true;
|
||||
// Will handle subtables using RunTable4 etc.
|
||||
s_interpreter_op_table[inst.OPCD](inst);
|
||||
}
|
||||
|
||||
void Interpreter::RunTable4(UGeckoInstruction inst)
|
||||
{
|
||||
s_interpreter_op_table4[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable19(UGeckoInstruction inst)
|
||||
{
|
||||
s_interpreter_op_table19[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable31(UGeckoInstruction inst)
|
||||
{
|
||||
s_interpreter_op_table31[inst.SUBOP10](inst);
|
||||
}
|
||||
void Interpreter::RunTable59(UGeckoInstruction inst)
|
||||
{
|
||||
s_interpreter_op_table59[inst.SUBOP5](inst);
|
||||
}
|
||||
void Interpreter::RunTable63(UGeckoInstruction inst)
|
||||
{
|
||||
s_interpreter_op_table63[inst.SUBOP10](inst);
|
||||
}
|
||||
Reference in new issue
Block a user