mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-01 03:32:58 +00:00
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.
This commit is contained in:
parent
2b5b21f2a4
commit
c73f4bd226
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
if (!extOpTable[inst & 0x7F]->jitFunc)
|
||||
const DSPOPCTemplate* const ext_op_template = GetExtOpTemplate(inst);
|
||||
|
||||
if (!ext_op_template->jitFunc)
|
||||
{
|
||||
// Fall back to interpreter
|
||||
gpr.PushRegs();
|
||||
ABI_CallFunctionC16(extOpTable[inst & 0x7F]->intFunc, inst);
|
||||
ABI_CallFunctionC16(ext_op_template->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);
|
||||
(this->*ext_op_template->jitFunc)(inst);
|
||||
ext_is_jit = true;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
@ -348,7 +351,7 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||
|
||||
SetJumpTarget(cnt);
|
||||
// dsp_skip_inst();
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||
WriteBranchExit(*this);
|
||||
gpr.FlushRegs(c, false);
|
||||
SetJumpTarget(exit);
|
||||
@ -381,7 +384,7 @@ 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));
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||
WriteBranchExit(*this);
|
||||
}
|
||||
}
|
||||
@ -418,7 +421,7 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||
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));
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||
WriteBranchExit(*this);
|
||||
gpr.FlushRegs(c, false);
|
||||
SetJumpTarget(exit);
|
||||
@ -454,7 +457,7 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
|
||||
{
|
||||
// g_dsp.pc = loop_pc;
|
||||
// dsp_skip_inst();
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + opTable[dsp_imem_read(loop_pc)]->size));
|
||||
MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size));
|
||||
WriteBranchExit(*this);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user