mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
DSPTables: Hide remaining exposed opcode tables
All opcode tables are now internal.
This commit is contained in:
parent
ec9b49436c
commit
6cb6707a4e
@ -425,33 +425,33 @@ u32 DSPAssembler::GetParams(char* parstr, param_t* par)
|
||||
return count;
|
||||
}
|
||||
|
||||
const opc_t* DSPAssembler::FindOpcode(const char* name, u32 par_count, const opc_t* const opcodes,
|
||||
size_t opcodes_size)
|
||||
const opc_t* DSPAssembler::FindOpcode(std::string name, size_t par_count, OpcodeType type)
|
||||
{
|
||||
if (name[0] == 'C' && name[1] == 'W')
|
||||
return &cw;
|
||||
|
||||
const auto alias_iter = aliases.find(name);
|
||||
if (alias_iter != aliases.end())
|
||||
name = alias_iter->second.c_str();
|
||||
for (size_t i = 0; i < opcodes_size; i++)
|
||||
name = alias_iter->second;
|
||||
|
||||
const DSPOPCTemplate* const info =
|
||||
type == OpcodeType::Primary ? FindOpInfoByName(name) : FindExtOpInfoByName(name);
|
||||
if (!info)
|
||||
{
|
||||
const opc_t* opcode = &opcodes[i];
|
||||
if (strcmp(opcode->name, name) == 0)
|
||||
{
|
||||
if (par_count < opcode->param_count)
|
||||
{
|
||||
ShowError(ERR_NOT_ENOUGH_PARAMETERS);
|
||||
}
|
||||
else if (par_count > opcode->param_count)
|
||||
{
|
||||
ShowError(ERR_TOO_MANY_PARAMETERS);
|
||||
}
|
||||
return opcode;
|
||||
}
|
||||
ShowError(ERR_UNKNOWN_OPCODE);
|
||||
return nullptr;
|
||||
}
|
||||
ShowError(ERR_UNKNOWN_OPCODE);
|
||||
return nullptr;
|
||||
|
||||
if (par_count < info->param_count)
|
||||
{
|
||||
ShowError(ERR_NOT_ENOUGH_PARAMETERS);
|
||||
}
|
||||
else if (par_count > info->param_count)
|
||||
{
|
||||
ShowError(ERR_TOO_MANY_PARAMETERS);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// weird...
|
||||
@ -969,7 +969,7 @@ bool DSPAssembler::AssembleFile(const std::string& file_path, int pass)
|
||||
continue;
|
||||
}
|
||||
|
||||
const opc_t* opc = FindOpcode(opcode, params_count, opcodes.data(), opcodes.size());
|
||||
const opc_t* opc = FindOpcode(opcode, params_count, OpcodeType::Primary);
|
||||
if (!opc)
|
||||
opc = &cw;
|
||||
|
||||
@ -983,7 +983,7 @@ bool DSPAssembler::AssembleFile(const std::string& file_path, int pass)
|
||||
{
|
||||
if (opcode_ext)
|
||||
{
|
||||
opc_ext = FindOpcode(opcode_ext, params_count_ext, opcodes_ext.data(), opcodes_ext.size());
|
||||
opc_ext = FindOpcode(opcode_ext, params_count_ext, OpcodeType::Extension);
|
||||
VerifyParams(opc_ext, params_ext, params_count_ext, true);
|
||||
}
|
||||
else if (params_count_ext)
|
||||
|
@ -78,6 +78,12 @@ private:
|
||||
SEGMENT_MAX
|
||||
};
|
||||
|
||||
enum class OpcodeType
|
||||
{
|
||||
Primary,
|
||||
Extension
|
||||
};
|
||||
|
||||
// Utility functions
|
||||
s32 ParseValue(const char* str);
|
||||
u32 ParseExpression(const char* ptr);
|
||||
@ -91,8 +97,7 @@ private:
|
||||
// void ShowWarning(err_t err_code, const char *extra_info = nullptr);
|
||||
|
||||
char* FindBrackets(char* src, char* dst);
|
||||
const opc_t* FindOpcode(const char* name, u32 par_count, const opc_t* opcodes,
|
||||
size_t opcodes_size);
|
||||
const opc_t* FindOpcode(std::string name, size_t par_count, OpcodeType type);
|
||||
bool VerifyParams(const opc_t* opc, param_t* par, size_t count, bool ext = false);
|
||||
void BuildCode(const opc_t* opc, param_t* par, u32 par_count, u16* outbuf);
|
||||
|
||||
|
@ -180,22 +180,10 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 op1 = binbuf[*pc & 0x0fff];
|
||||
const u16 op1 = binbuf[*pc & 0x0fff];
|
||||
|
||||
const DSPOPCTemplate* opc = nullptr;
|
||||
const DSPOPCTemplate* opc_ext = nullptr;
|
||||
|
||||
// find opcode
|
||||
for (const auto& opcode : opcodes)
|
||||
{
|
||||
u16 mask = opcode.opcode_mask;
|
||||
|
||||
if ((op1 & mask) == opcode.opcode)
|
||||
{
|
||||
opc = &opcode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Find main opcode
|
||||
const DSPOPCTemplate* opc = FindOpInfoByOpcode(op1);
|
||||
const DSPOPCTemplate fake_op = {"CW", 0x0000, 0x0000, DSP::Interpreter::nop,
|
||||
nullptr, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},
|
||||
false, false, false, false,
|
||||
@ -203,42 +191,25 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
if (!opc)
|
||||
opc = &fake_op;
|
||||
|
||||
bool extended = false;
|
||||
bool only7bitext = false;
|
||||
bool is_extended = false;
|
||||
bool is_only_7_bit_ext = false;
|
||||
|
||||
if (((opc->opcode >> 12) == 0x3) && (op1 & 0x007f))
|
||||
{
|
||||
extended = true;
|
||||
only7bitext = true;
|
||||
is_extended = true;
|
||||
is_only_7_bit_ext = true;
|
||||
}
|
||||
else if (((opc->opcode >> 12) > 0x3) && (op1 & 0x00ff))
|
||||
{
|
||||
extended = true;
|
||||
is_extended = true;
|
||||
}
|
||||
|
||||
if (extended)
|
||||
const DSPOPCTemplate* opc_ext = nullptr;
|
||||
if (is_extended)
|
||||
{
|
||||
// opcode has an extension
|
||||
// find opcode
|
||||
for (const auto& opcode_ext : opcodes_ext)
|
||||
{
|
||||
if (only7bitext)
|
||||
{
|
||||
if (((op1 & 0x7f) & opcode_ext.opcode_mask) == opcode_ext.opcode)
|
||||
{
|
||||
opc_ext = &opcode_ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((op1 & opcode_ext.opcode_mask) == opcode_ext.opcode)
|
||||
{
|
||||
opc_ext = &opcode_ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const u16 extended_opcode = is_only_7_bit_ext ? op1 & 0x7F : op1;
|
||||
opc_ext = FindExtOpInfoByOpcode(extended_opcode);
|
||||
}
|
||||
|
||||
// printing
|
||||
@ -246,7 +217,7 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
if (settings_.show_pc)
|
||||
buf += StringFromFormat("%04x ", *pc);
|
||||
|
||||
u32 op2;
|
||||
u16 op2;
|
||||
|
||||
// Size 2 - the op has a large immediate.
|
||||
if (opc->size == 2)
|
||||
@ -267,7 +238,7 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
opname = MakeLowerCase(opname);
|
||||
|
||||
std::string ext_buf;
|
||||
if (extended)
|
||||
if (is_extended)
|
||||
ext_buf = StringFromFormat("%s%c%s", opname.c_str(), settings_.ext_separator, opc_ext->name);
|
||||
else
|
||||
ext_buf = opname;
|
||||
@ -283,7 +254,7 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
buf += DisassembleParameters(*opc, op1, op2);
|
||||
|
||||
// Handle opcode extension.
|
||||
if (extended)
|
||||
if (is_extended)
|
||||
{
|
||||
if (opc->param_count > 0)
|
||||
buf += " ";
|
||||
@ -301,7 +272,7 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
|
||||
buf += "\t\t; *** UNKNOWN OPCODE ***";
|
||||
}
|
||||
|
||||
if (extended)
|
||||
if (is_extended)
|
||||
*pc += opc_ext->size;
|
||||
else
|
||||
*pc += opc->size;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "Core/DSP/DSPTables.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
@ -20,7 +21,7 @@ namespace DSP
|
||||
using JIT::x86::DSPEmitter;
|
||||
|
||||
// clang-format off
|
||||
const std::array<DSPOPCTemplate, 214> opcodes =
|
||||
const std::array<DSPOPCTemplate, 214> s_opcodes =
|
||||
{{
|
||||
// # of parameters----+ {type, size, loc, lshift, mask} branch reads PC // instruction approximation
|
||||
// name opcode mask interpreter function JIT function size-V V param 1 param 2 param 3 extendable uncond. updates SR
|
||||
@ -296,7 +297,7 @@ const DSPOPCTemplate cw =
|
||||
|
||||
// extended opcodes
|
||||
|
||||
const std::array<DSPOPCTemplate, 25> opcodes_ext =
|
||||
const std::array<DSPOPCTemplate, 25> s_opcodes_ext =
|
||||
{{
|
||||
{"XXX", 0x0000, 0x00fc, Interpreter::Ext::nop, &DSPEmitter::nop, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}}, false, false, false, false, false}, // no operation
|
||||
|
||||
@ -512,8 +513,59 @@ 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;
|
||||
|
||||
template <size_t N>
|
||||
auto FindByOpcode(UDSPInstruction opcode, const std::array<DSPOPCTemplate, N>& data)
|
||||
{
|
||||
return std::find_if(data.cbegin(), data.cend(), [opcode](const auto& info) {
|
||||
return (opcode & info.opcode_mask) == info.opcode;
|
||||
});
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
auto FindByName(const std::string& name, const std::array<DSPOPCTemplate, N>& data)
|
||||
{
|
||||
return std::find_if(data.cbegin(), data.cend(),
|
||||
[&name](const auto& info) { return name == info.name; });
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
const DSPOPCTemplate* FindOpInfoByOpcode(UDSPInstruction opcode)
|
||||
{
|
||||
const auto iter = FindByOpcode(opcode, s_opcodes);
|
||||
if (iter == s_opcodes.cend())
|
||||
return nullptr;
|
||||
|
||||
return &*iter;
|
||||
}
|
||||
|
||||
const DSPOPCTemplate* FindOpInfoByName(const std::string& name)
|
||||
{
|
||||
const auto iter = FindByName(name, s_opcodes);
|
||||
if (iter == s_opcodes.cend())
|
||||
return nullptr;
|
||||
|
||||
return &*iter;
|
||||
}
|
||||
|
||||
const DSPOPCTemplate* FindExtOpInfoByOpcode(UDSPInstruction opcode)
|
||||
{
|
||||
const auto iter = FindByOpcode(opcode, s_opcodes_ext);
|
||||
if (iter == s_opcodes_ext.cend())
|
||||
return nullptr;
|
||||
|
||||
return &*iter;
|
||||
}
|
||||
|
||||
const DSPOPCTemplate* FindExtOpInfoByName(const std::string& name)
|
||||
{
|
||||
const auto iter = FindByName(name, s_opcodes_ext);
|
||||
if (iter == s_opcodes_ext.cend())
|
||||
return nullptr;
|
||||
|
||||
return &*iter;
|
||||
}
|
||||
|
||||
const DSPOPCTemplate* GetOpTemplate(UDSPInstruction inst)
|
||||
{
|
||||
return s_op_table[inst];
|
||||
@ -538,25 +590,21 @@ void InitInstructionTable()
|
||||
{
|
||||
s_ext_op_table[i] = &cw;
|
||||
|
||||
for (const DSPOPCTemplate& ext : opcodes_ext)
|
||||
const auto iter = FindByOpcode(static_cast<UDSPInstruction>(i), s_opcodes_ext);
|
||||
if (iter == s_opcodes_ext.cend())
|
||||
continue;
|
||||
|
||||
if (s_ext_op_table[i] == &cw)
|
||||
{
|
||||
u16 mask = ext.opcode_mask;
|
||||
if ((mask & i) == ext.opcode)
|
||||
s_ext_op_table[i] = &*iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the entry already in the table is a strict subset, allow it
|
||||
if ((s_ext_op_table[i]->opcode_mask | iter->opcode_mask) != s_ext_op_table[i]->opcode_mask)
|
||||
{
|
||||
if (s_ext_op_table[i] == &cw)
|
||||
{
|
||||
s_ext_op_table[i] = &ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the entry already in the table
|
||||
// is a strict subset, allow it
|
||||
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, s_ext_op_table[i]->name, ext.name);
|
||||
}
|
||||
}
|
||||
ERROR_LOG(DSPLLE, "opcode ext table place %zu already in use by %s when inserting %s", i,
|
||||
s_ext_op_table[i]->name, iter->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -566,17 +614,14 @@ void InitInstructionTable()
|
||||
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
const auto iter = FindByOpcode(static_cast<UDSPInstruction>(i), s_opcodes);
|
||||
if (iter == s_opcodes.cend())
|
||||
continue;
|
||||
|
||||
if (s_op_table[i] == &cw)
|
||||
s_op_table[i] = &*iter;
|
||||
else
|
||||
ERROR_LOG(DSPLLE, "opcode table place %zu already in use for %s", i, iter->name);
|
||||
}
|
||||
|
||||
writeBackLogIdx.fill(-1);
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "Core/DSP/DSPCommon.h"
|
||||
#include "Core/DSP/Jit/DSPEmitter.h"
|
||||
@ -90,8 +91,6 @@ struct DSPOPCTemplate
|
||||
typedef DSPOPCTemplate opc_t;
|
||||
|
||||
// Opcodes
|
||||
extern const std::array<DSPOPCTemplate, 214> opcodes;
|
||||
extern const std::array<DSPOPCTemplate, 25> opcodes_ext;
|
||||
extern const DSPOPCTemplate cw;
|
||||
|
||||
constexpr size_t WRITEBACK_LOG_SIZE = 5;
|
||||
@ -118,6 +117,14 @@ void applyWriteBackLog();
|
||||
void zeroWriteBackLog();
|
||||
void zeroWriteBackLogPreserveAcc(u8 acc);
|
||||
|
||||
// Used by the assembler and disassembler for info retrieval.
|
||||
const DSPOPCTemplate* FindOpInfoByOpcode(UDSPInstruction opcode);
|
||||
const DSPOPCTemplate* FindOpInfoByName(const std::string& name);
|
||||
|
||||
const DSPOPCTemplate* FindExtOpInfoByOpcode(UDSPInstruction opcode);
|
||||
const DSPOPCTemplate* FindExtOpInfoByName(const std::string& name);
|
||||
|
||||
// Used by the interpreter and JIT for instruction emulation
|
||||
const DSPOPCTemplate* GetOpTemplate(UDSPInstruction inst);
|
||||
const DSPOPCTemplate* GetExtOpTemplate(UDSPInstruction inst);
|
||||
} // namespace DSP
|
||||
|
Loading…
Reference in New Issue
Block a user