summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2017-01-19 14:48:59 -0500
committerLioncash <mathew1800@gmail.com>2017-01-19 17:46:07 -0500
commitc73f4bd2266c92b1e1b2eee2ebe10627bc7b5e32 (patch)
tree0bee7431237b202e419cc5571d5dae2fb2be193a /Source
parent2b5b21f2a4238cfe076ebf8618d90f04d2b67962 (diff)
DSPTables: Hide main opcode tables
Hides the opcode tables that the interpreter and JIT interface with to execute instructions. This does not, however, hide the read-only tables that the assembler and disassembler use.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/DSP/DSPMemoryMap.cpp2
-rw-r--r--Source/Core/Core/DSP/DSPTables.cpp44
-rw-r--r--Source/Core/Core/DSP/DSPTables.h8
-rw-r--r--Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp5
-rw-r--r--Source/Core/Core/DSP/Jit/DSPEmitter.cpp58
-rw-r--r--Source/Core/Core/DSP/Jit/DSPJitBranch.cpp25
6 files changed, 69 insertions, 73 deletions
diff --git a/Source/Core/Core/DSP/DSPMemoryMap.cpp b/Source/Core/Core/DSP/DSPMemoryMap.cpp
index c19d6947f2..19cced93ff 100644
--- a/Source/Core/Core/DSP/DSPMemoryMap.cpp
+++ b/Source/Core/Core/DSP/DSPMemoryMap.cpp
@@ -82,6 +82,6 @@ u16 dsp_peek_code()
void dsp_skip_inst()
{
- g_dsp.pc += opTable[dsp_peek_code()]->size;
+ g_dsp.pc += GetOpTemplate(dsp_peek_code())->size;
}
} // namespace DSP
diff --git a/Source/Core/Core/DSP/DSPTables.cpp b/Source/Core/Core/DSP/DSPTables.cpp
index e14a944903..f0bfee47cb 100644
--- a/Source/Core/Core/DSP/DSPTables.cpp
+++ b/Source/Core/Core/DSP/DSPTables.cpp
@@ -479,8 +479,6 @@ const std::array<pdlabel_t, 36> regnames =
}};
// clang-format on
-std::array<const DSPOPCTemplate*, OPTABLE_SIZE> opTable;
-std::array<const DSPOPCTemplate*, EXT_OPTABLE_SIZE> extOpTable;
std::array<u16, WRITEBACK_LOG_SIZE> writeBackLog;
std::array<int, WRITEBACK_LOG_SIZE> writeBackLogIdx;
@@ -508,9 +506,27 @@ const char* pdregnamelong(int val)
return regnames[val].description;
}
-const DSPOPCTemplate* GetOpTemplate(const UDSPInstruction& inst)
+namespace
{
- return opTable[inst];
+constexpr size_t OPTABLE_SIZE = 0xffff + 1;
+constexpr size_t EXT_OPTABLE_SIZE = 0xff + 1;
+std::array<const DSPOPCTemplate*, OPTABLE_SIZE> s_op_table;
+std::array<const DSPOPCTemplate*, EXT_OPTABLE_SIZE> s_ext_op_table;
+} // Anonymous namespace
+
+const DSPOPCTemplate* GetOpTemplate(UDSPInstruction inst)
+{
+ return s_op_table[inst];
+}
+
+const DSPOPCTemplate* GetExtOpTemplate(UDSPInstruction inst)
+{
+ const bool has_seven_bit_extension = (inst >> 12) == 0x3;
+
+ if (has_seven_bit_extension)
+ return s_ext_op_table[inst & 0x7F];
+
+ return s_ext_op_table[inst & 0xFF];
}
// This function could use the above GetOpTemplate, but then we'd lose the
@@ -518,27 +534,27 @@ const DSPOPCTemplate* GetOpTemplate(const UDSPInstruction& inst)
void InitInstructionTable()
{
// ext op table
- for (size_t i = 0; i < extOpTable.size(); i++)
+ for (size_t i = 0; i < s_ext_op_table.size(); i++)
{
- extOpTable[i] = &cw;
+ s_ext_op_table[i] = &cw;
for (const DSPOPCTemplate& ext : opcodes_ext)
{
u16 mask = ext.opcode_mask;
if ((mask & i) == ext.opcode)
{
- if (extOpTable[i] == &cw)
+ if (s_ext_op_table[i] == &cw)
{
- extOpTable[i] = &ext;
+ s_ext_op_table[i] = &ext;
}
else
{
// if the entry already in the table
// is a strict subset, allow it
- if ((extOpTable[i]->opcode_mask | ext.opcode_mask) != extOpTable[i]->opcode_mask)
+ if ((s_ext_op_table[i]->opcode_mask | ext.opcode_mask) != s_ext_op_table[i]->opcode_mask)
{
ERROR_LOG(DSPLLE, "opcode ext table place %zu already in use by %s when inserting %s",
- i, extOpTable[i]->name, ext.name);
+ i, s_ext_op_table[i]->name, ext.name);
}
}
}
@@ -546,17 +562,17 @@ void InitInstructionTable()
}
// op table
- opTable.fill(&cw);
+ s_op_table.fill(&cw);
- for (size_t i = 0; i < opTable.size(); i++)
+ for (size_t i = 0; i < s_op_table.size(); i++)
{
for (const DSPOPCTemplate& opcode : opcodes)
{
u16 mask = opcode.opcode_mask;
if ((mask & i) == opcode.opcode)
{
- if (opTable[i] == &cw)
- opTable[i] = &opcode;
+ if (s_op_table[i] == &cw)
+ s_op_table[i] = &opcode;
else
ERROR_LOG(DSPLLE, "opcode table place %zu already in use for %s", i, opcode.name);
}
diff --git a/Source/Core/Core/DSP/DSPTables.h b/Source/Core/Core/DSP/DSPTables.h
index d93c7f0b40..194c7cb0bb 100644
--- a/Source/Core/Core/DSP/DSPTables.h
+++ b/Source/Core/Core/DSP/DSPTables.h
@@ -94,12 +94,7 @@ extern const std::array<DSPOPCTemplate, 214> opcodes;
extern const std::array<DSPOPCTemplate, 25> opcodes_ext;
extern const DSPOPCTemplate cw;
-constexpr size_t OPTABLE_SIZE = 0xffff + 1;
-constexpr size_t EXT_OPTABLE_SIZE = 0xff + 1;
constexpr size_t WRITEBACK_LOG_SIZE = 5;
-
-extern std::array<const DSPOPCTemplate*, OPTABLE_SIZE> opTable;
-extern std::array<const DSPOPCTemplate*, EXT_OPTABLE_SIZE> extOpTable;
extern std::array<u16, WRITEBACK_LOG_SIZE> writeBackLog;
extern std::array<int, WRITEBACK_LOG_SIZE> writeBackLogIdx;
@@ -123,5 +118,6 @@ void applyWriteBackLog();
void zeroWriteBackLog();
void zeroWriteBackLogPreserveAcc(u8 acc);
-const DSPOPCTemplate* GetOpTemplate(const UDSPInstruction& inst);
+const DSPOPCTemplate* GetOpTemplate(UDSPInstruction inst);
+const DSPOPCTemplate* GetExtOpTemplate(UDSPInstruction inst);
} // namespace DSP
diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
index a7a4a2e12d..d874f878bb 100644
--- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
+++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp
@@ -25,10 +25,7 @@ void ExecuteInstruction(const UDSPInstruction inst)
if (opcode_template->extended)
{
- if ((inst >> 12) == 0x3)
- extOpTable[inst & 0x7F]->intFunc(inst);
- else
- extOpTable[inst & 0xFF]->intFunc(inst);
+ GetExtOpTemplate(inst)->intFunc(inst);
}
opcode_template->intFunc(inst);
diff --git a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp
index f89c604485..0b11b922a4 100644
--- a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp
+++ b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp
@@ -105,7 +105,9 @@ bool DSPEmitter::FlagsNeeded() const
void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
{
- if (opTable[inst]->reads_pc)
+ const DSPOPCTemplate* const op_template = GetOpTemplate(inst);
+
+ if (op_template->reads_pc)
{
// Increment PC - we shouldn't need to do this for every instruction. only for branches and end
// of block.
@@ -116,68 +118,50 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst)
// Fall back to interpreter
gpr.PushRegs();
- _assert_msg_(DSPLLE, opTable[inst]->intFunc, "No function for %04x", inst);
- ABI_CallFunctionC16(opTable[inst]->intFunc, inst);
+ _assert_msg_(DSPLLE, op_template->intFunc, "No function for %04x", inst);
+ ABI_CallFunctionC16(op_template->intFunc, inst);
gpr.PopRegs();
}
void DSPEmitter::EmitInstruction(UDSPInstruction inst)
{
- const DSPOPCTemplate* tinst = GetOpTemplate(inst);
+ const DSPOPCTemplate* const op_template = GetOpTemplate(inst);
bool ext_is_jit = false;
// Call extended
- if (tinst->extended)
+ if (op_template->extended)
{
- if ((inst >> 12) == 0x3)
+ const DSPOPCTemplate* const ext_op_template = GetExtOpTemplate(inst);
+
+ if (!ext_op_template->jitFunc)
{
- if (!extOpTable[inst & 0x7F]->jitFunc)
- {
- // Fall back to interpreter
- gpr.PushRegs();
- ABI_CallFunctionC16(extOpTable[inst & 0x7F]->intFunc, inst);
- gpr.PopRegs();
- INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
- ext_is_jit = false;
- }
- else
- {
- (this->*extOpTable[inst & 0x7F]->jitFunc)(inst);
- ext_is_jit = true;
- }
+ // Fall back to interpreter
+ gpr.PushRegs();
+ ABI_CallFunctionC16(ext_op_template->intFunc, inst);
+ gpr.PopRegs();
+ INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
+ ext_is_jit = false;
}
else
{
- if (!extOpTable[inst & 0xFF]->jitFunc)
- {
- // Fall back to interpreter
- gpr.PushRegs();
- ABI_CallFunctionC16(extOpTable[inst & 0xFF]->intFunc, inst);
- gpr.PopRegs();
- INFO_LOG(DSPLLE, "Instruction not JITed(ext part): %04x", inst);
- ext_is_jit = false;
- }
- else
- {
- (this->*extOpTable[inst & 0xFF]->jitFunc)(inst);
- ext_is_jit = true;
- }
+ (this->*ext_op_template->jitFunc)(inst);
+ ext_is_jit = true;
}
}
// Main instruction
- if (!opTable[inst]->jitFunc)
+ if (!op_template->jitFunc)
{
FallBackToInterpreter(inst);
INFO_LOG(DSPLLE, "Instruction not JITed(main part): %04x", inst);
}
else
{
- (this->*opTable[inst]->jitFunc)(inst);
+ (this->*op_template->jitFunc)(inst);
}
// Backlog
- if (tinst->extended)
+ if (op_template->extended)
{
if (!ext_is_jit)
{
diff --git a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp
index 356bf9731e..e60cbaed64 100644
--- a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp
+++ b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp
@@ -232,7 +232,10 @@ static void r_ifcc(const UDSPInstruction opc, DSPEmitter& emitter)
// NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit
void DSPEmitter::ifcc(const UDSPInstruction opc)
{
- MOV(16, M(&g_dsp.pc), Imm16((compilePC + 1) + opTable[dsp_imem_read(compilePC + 1)]->size));
+ const u16 address = compilePC + 1;
+ const DSPOPCTemplate* const op_template = GetOpTemplate(dsp_imem_read(address));
+
+ MOV(16, M(&g_dsp.pc), Imm16(address + op_template->size));
ReJitConditional<r_ifcc>(opc, *this);
WriteBranchExit(*this);
}
@@ -347,8 +350,8 @@ void DSPEmitter::loop(const UDSPInstruction opc)
FixupBranch exit = J(true);
SetJumpTarget(cnt);
- // dsp_skip_inst();
- MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
+ // dsp_skip_inst();
+ MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
gpr.FlushRegs(c, false);
SetJumpTarget(exit);
@@ -380,8 +383,8 @@ void DSPEmitter::loopi(const UDSPInstruction opc)
}
else
{
- // dsp_skip_inst();
- MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
+ // dsp_skip_inst();
+ MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
}
}
@@ -416,9 +419,9 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
FixupBranch exit = J(true);
SetJumpTarget(cnt);
- // g_dsp.pc = loop_pc;
- // dsp_skip_inst();
- MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
+ // g_dsp.pc = loop_pc;
+ // dsp_skip_inst();
+ MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
gpr.FlushRegs(c, false);
SetJumpTarget(exit);
@@ -452,9 +455,9 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
}
else
{
- // g_dsp.pc = loop_pc;
- // dsp_skip_inst();
- MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
+ // g_dsp.pc = loop_pc;
+ // dsp_skip_inst();
+ MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
WriteBranchExit(*this);
}
}