DSPTables: Use std::array instead of C arrays

This commit is contained in:
Lioncash 2017-01-19 13:49:17 -05:00
parent 629fcb437a
commit 14f0e66809
6 changed files with 75 additions and 81 deletions

View File

@ -5,6 +5,7 @@
#include "Core/DSP/DSPAssembler.h"
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
@ -442,7 +443,7 @@ u32 DSPAssembler::GetParams(char* parstr, param_t* par)
}
const opc_t* DSPAssembler::FindOpcode(const char* opcode, u32 par_count, const opc_t* const opcod,
int opcod_size)
size_t opcod_size)
{
if (opcode[0] == 'C' && opcode[1] == 'W')
return &cw;
@ -450,7 +451,7 @@ const opc_t* DSPAssembler::FindOpcode(const char* opcode, u32 par_count, const o
AliasMap::const_iterator alias_iter = aliases.find(opcode);
if (alias_iter != aliases.end())
opcode = alias_iter->second.c_str();
for (int i = 0; i < opcod_size; i++)
for (size_t i = 0; i < opcod_size; i++)
{
const opc_t* opc = &opcod[i];
if (strcmp(opc->name, opcode) == 0)
@ -478,11 +479,11 @@ static u16 get_mask_shifted_down(u16 mask)
return mask;
}
bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool ext)
bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, size_t count, bool ext)
{
for (int i = 0; i < count; i++)
for (size_t i = 0; i < count; i++)
{
const int current_param = i + 1; // just for display.
const size_t current_param = i + 1; // just for display.
if (opc->params[i].type != par[i].type || (par[i].type & P_REG))
{
if (par[i].type == P_VAL &&
@ -510,7 +511,7 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
if (ext)
fprintf(stderr, "(ext) ");
fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
fprintf(stderr, "%s (param %zu)", cur_line.c_str(), current_param);
ShowError(ERR_INVALID_REGISTER);
}
break;
@ -520,7 +521,7 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
if (ext)
fprintf(stderr, "(ext) ");
fprintf(stderr, "%s (param %i)", cur_line.c_str(), current_param);
fprintf(stderr, "%s (param %zu)", cur_line.c_str(), current_param);
ShowError(ERR_INVALID_REGISTER);
}
break;
@ -534,14 +535,14 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
{
fprintf(stderr, "%i : %s ", code_line, cur_line.c_str());
fprintf(stderr, "WARNING: $ACM%d register used instead of $ACC%d register Line: %d "
"Param: %d Ext: %d\n",
"Param: %zu Ext: %d\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param, ext);
}
else if (par[i].val >= 0x1c && par[i].val <= 0x1d)
{
fprintf(
stderr,
"WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %d\n",
"WARNING: $ACL%d register used instead of $ACC%d register Line: %d Param: %zu\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
}
else
@ -560,14 +561,14 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
{
fprintf(
stderr,
"WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %d\n",
"WARNING: $ACL%d register used instead of $ACM%d register Line: %d Param: %zu\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
}
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
{
fprintf(
stderr,
"WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %d\n",
"WARNING: $ACC%d register used instead of $ACM%d register Line: %d Param: %zu\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
}
else
@ -588,7 +589,7 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
fprintf(stderr, "%s ", cur_line.c_str());
fprintf(
stderr,
"WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %d\n",
"WARNING: $ACM%d register used instead of $ACL%d register Line: %d Param: %zu\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
}
else if (par[i].val >= 0x20 && par[i].val <= 0x21)
@ -596,7 +597,7 @@ bool DSPAssembler::VerifyParams(const opc_t* opc, param_t* par, int count, bool
fprintf(stderr, "%s ", cur_line.c_str());
fprintf(
stderr,
"WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %d\n",
"WARNING: $ACC%d register used instead of $ACL%d register Line: %d Param: %zu\n",
(par[i].val & 1), (par[i].val & 1), code_line, current_param);
}
else
@ -987,7 +988,7 @@ bool DSPAssembler::AssembleFile(const char* fname, int pass)
continue;
}
const opc_t* opc = FindOpcode(opcode, params_count, opcodes, opcodes_size);
const opc_t* opc = FindOpcode(opcode, params_count, opcodes.data(), opcodes.size());
if (!opc)
opc = &cw;
@ -1001,7 +1002,7 @@ bool DSPAssembler::AssembleFile(const char* fname, int pass)
{
if (opcode_ext)
{
opc_ext = FindOpcode(opcode_ext, params_count_ext, opcodes_ext, opcodes_ext_size);
opc_ext = FindOpcode(opcode_ext, params_count_ext, opcodes_ext.data(), opcodes_ext.size());
VerifyParams(opc_ext, params_ext, params_count_ext, true);
}
else if (params_count_ext)

View File

@ -5,6 +5,7 @@
#pragma once
#include <cstddef>
#include <map>
#include <string>
@ -90,8 +91,8 @@ private:
char* FindBrackets(char* src, char* dst);
const opc_t* FindOpcode(const char* opcode, u32 par_count, const opc_t* const opcod,
int opcod_size);
bool VerifyParams(const opc_t* opc, param_t* par, int count, bool ext = false);
size_t opcod_size);
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);
char* gdg_buffer;

View File

@ -186,13 +186,13 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
const DSPOPCTemplate* opc_ext = nullptr;
// find opcode
for (int j = 0; j < opcodes_size; j++)
for (const auto& opcode : opcodes)
{
u16 mask = opcodes[j].opcode_mask;
u16 mask = opcode.opcode_mask;
if ((op1 & mask) == opcodes[j].opcode)
if ((op1 & mask) == opcode.opcode)
{
opc = &opcodes[j];
opc = &opcode;
break;
}
}
@ -220,21 +220,21 @@ bool DSPDisassembler::DisassembleOpcode(const u16* binbuf, int base_addr, int pa
{
// opcode has an extension
// find opcode
for (int j = 0; j < opcodes_ext_size; j++)
for (const auto& opcode_ext : opcodes_ext)
{
if (only7bitext)
{
if (((op1 & 0x7f) & opcodes_ext[j].opcode_mask) == opcodes_ext[j].opcode)
if (((op1 & 0x7f) & opcode_ext.opcode_mask) == opcode_ext.opcode)
{
opc_ext = &opcodes_ext[j];
opc_ext = &opcode_ext;
break;
}
}
else
{
if ((op1 & opcodes_ext[j].opcode_mask) == opcodes_ext[j].opcode)
if ((op1 & opcode_ext.opcode_mask) == opcode_ext.opcode)
{
opc_ext = &opcodes_ext[j];
opc_ext = &opcode_ext;
break;
}
}

View File

@ -6,6 +6,9 @@
#include "Core/DSP/DSPTables.h"
#include <array>
#include <cstddef>
#include "Common/CommonTypes.h"
#include "Core/DSP/Interpreter/DSPIntExtOps.h"
@ -17,8 +20,8 @@ namespace DSP
using JIT::x86::DSPEmitter;
// clang-format off
const DSPOPCTemplate opcodes[] =
{
const std::array<DSPOPCTemplate, 214> 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
{"NOP", 0x0000, 0xfffc, Interpreter::nop, &DSPEmitter::nop, 1, 0, {}, false, false, false, false, false}, // no operation
@ -286,15 +289,15 @@ const DSPOPCTemplate opcodes[] =
{"ADDPAXZ", 0xf800, 0xfc00, Interpreter::addpaxz, &DSPEmitter::addpaxz,1, 2, {{P_ACC, 1, 0, 9, 0x0200}, {P_AX, 1, 0, 8, 0x0100}}, true, false, false, false, true}, // $acD.hm = $prod.hm + $ax.h; $acD.l = 0
{"CLRL", 0xfc00, 0xfe00, Interpreter::clrl, &DSPEmitter::clrl, 1, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, true, false, false, false, true}, // $acR.l = 0
{"MOVPZ", 0xfe00, 0xfe00, Interpreter::movpz, &DSPEmitter::movpz, 1, 1, {{P_ACC, 1, 0, 8, 0x0100}}, true, false, false, false, true}, // $acD.hm = $prod.hm; $acD.l = 0
};
}};
const DSPOPCTemplate cw =
{"CW", 0x0000, 0x0000, Interpreter::nop, nullptr, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}}, false, false, false, false, false};
// extended opcodes
const DSPOPCTemplate opcodes_ext[] =
{
const std::array<DSPOPCTemplate, 25> 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
{"DR", 0x0004, 0x00fc, Interpreter::Ext::dr, &DSPEmitter::dr, 1, 1, {{P_REG, 1, 0, 0, 0x0003}}, false, false, false, false, false}, // $arR--
@ -326,13 +329,10 @@ const DSPOPCTemplate opcodes_ext[] =
{"LDN", 0x00c4, 0x00cc, Interpreter::Ext::ldn, &DSPEmitter::ldn, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false}, // $ax0.D = MEM[$arS]; $ax1.R = MEM[$ar3++]; $arS += $ixS
{"LDM", 0x00c8, 0x00cc, Interpreter::Ext::ldm, &DSPEmitter::ldm, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false}, // $ax0.D = MEM[$arS++]; $ax1.R = MEM[$ar3]; $ar3 += $ix3
{"LDNM", 0x00cc, 0x00cc, Interpreter::Ext::ldnm, &DSPEmitter::ldnm, 1, 3, {{P_REGM18, 1, 0, 4, 0x0020}, {P_REGM19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false, false}, // $ax0.D = MEM[$arS]; $ax1.R = MEM[$ar3]; $arS += $ixS; $ar3 += $ix3
};
}};
const int opcodes_size = sizeof(opcodes) / sizeof(DSPOPCTemplate);
const int opcodes_ext_size = sizeof(opcodes_ext) / sizeof(DSPOPCTemplate);
const pdlabel_t pdlabels[] =
{
const std::array<pdlabel_t, 96> pdlabels =
{{
{0xffa0, "COEF_A1_0", "COEF_A1_0",},
{0xffa1, "COEF_A2_0", "COEF_A2_0",},
{0xffa2, "COEF_A1_1", "COEF_A1_1",},
@ -434,12 +434,10 @@ const pdlabel_t pdlabels[] =
{0xfffd, "DMBL", "DSP Mailbox L",},
{0xfffe, "CMBH", "CPU Mailbox H",},
{0xffff, "CMBL", "CPU Mailbox L",},
};
}};
const u32 pdlabels_size = sizeof(pdlabels) / sizeof(pdlabel_t);
const pdlabel_t regnames[] =
{
const std::array<pdlabel_t, 36> regnames =
{{
{0x00, "AR0", "Addr Reg 00",},
{0x01, "AR1", "Addr Reg 01",},
{0x02, "AR2", "Addr Reg 02",},
@ -478,13 +476,13 @@ const pdlabel_t regnames[] =
{0x21, "ACC1", "Accu Full 1",},
{0x22, "AX0", "Extra Accu 0",},
{0x23, "AX1", "Extra Accu 1",},
};
}};
// clang-format on
const DSPOPCTemplate* opTable[OPTABLE_SIZE];
const DSPOPCTemplate* extOpTable[EXT_OPTABLE_SIZE];
u16 writeBackLog[WRITEBACKLOGSIZE];
int writeBackLogIdx[WRITEBACKLOGSIZE];
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;
const char* pdname(u16 val)
{
@ -520,7 +518,7 @@ const DSPOPCTemplate* GetOpTemplate(const UDSPInstruction& inst)
void InitInstructionTable()
{
// ext op table
for (int i = 0; i < EXT_OPTABLE_SIZE; i++)
for (size_t i = 0; i < extOpTable.size(); i++)
{
extOpTable[i] = &cw;
@ -539,8 +537,8 @@ void InitInstructionTable()
// is a strict subset, allow it
if ((extOpTable[i]->opcode_mask | ext.opcode_mask) != extOpTable[i]->opcode_mask)
{
ERROR_LOG(DSPLLE, "opcode ext table place %d already in use by %s when inserting %s", i,
extOpTable[i]->name, ext.name);
ERROR_LOG(DSPLLE, "opcode ext table place %zu already in use by %s when inserting %s",
i, extOpTable[i]->name, ext.name);
}
}
}
@ -548,12 +546,9 @@ void InitInstructionTable()
}
// op table
for (const DSPOPCTemplate*& opcode : opTable)
{
opcode = &cw;
}
opTable.fill(&cw);
for (int i = 0; i < OPTABLE_SIZE; i++)
for (size_t i = 0; i < opTable.size(); i++)
{
for (const DSPOPCTemplate& opcode : opcodes)
{
@ -563,14 +558,11 @@ void InitInstructionTable()
if (opTable[i] == &cw)
opTable[i] = &opcode;
else
ERROR_LOG(DSPLLE, "opcode table place %d already in use for %s", i, opcode.name);
ERROR_LOG(DSPLLE, "opcode table place %zu already in use for %s", i, opcode.name);
}
}
}
for (int& elem : writeBackLogIdx)
{
elem = -1;
}
writeBackLogIdx.fill(-1);
}
} // namespace DSP

View File

@ -6,6 +6,9 @@
#pragma once
#include <array>
#include <cstddef>
#include "Core/DSP/DSPCommon.h"
#include "Core/DSP/Jit/DSPEmitter.h"
@ -53,9 +56,6 @@ enum partype_t
// P_AX_D = P_REG | 0x2280,
};
#define OPTABLE_SIZE 0xffff + 1
#define EXT_OPTABLE_SIZE 0xff + 1
struct param2_t
{
partype_t type;
@ -90,18 +90,18 @@ struct DSPOPCTemplate
typedef DSPOPCTemplate opc_t;
// Opcodes
extern const DSPOPCTemplate opcodes[];
extern const int opcodes_size;
extern const DSPOPCTemplate opcodes_ext[];
extern const int opcodes_ext_size;
extern const std::array<DSPOPCTemplate, 214> opcodes;
extern const std::array<DSPOPCTemplate, 25> opcodes_ext;
extern const DSPOPCTemplate cw;
#define WRITEBACKLOGSIZE 5
constexpr size_t OPTABLE_SIZE = 0xffff + 1;
constexpr size_t EXT_OPTABLE_SIZE = 0xff + 1;
constexpr size_t WRITEBACK_LOG_SIZE = 5;
extern const DSPOPCTemplate* opTable[OPTABLE_SIZE];
extern const DSPOPCTemplate* extOpTable[EXT_OPTABLE_SIZE];
extern u16 writeBackLog[WRITEBACKLOGSIZE];
extern int writeBackLogIdx[WRITEBACKLOGSIZE];
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;
// Predefined labels
struct pdlabel_t
@ -111,9 +111,8 @@ struct pdlabel_t
const char* description;
};
extern const pdlabel_t regnames[];
extern const pdlabel_t pdlabels[];
extern const u32 pdlabels_size;
extern const std::array<pdlabel_t, 36> regnames;
extern const std::array<pdlabel_t, 96> pdlabels;
const char* pdname(u16 val);
const char* pdregname(int val);

View File

@ -13,15 +13,16 @@ LabelMap::LabelMap()
void LabelMap::RegisterDefaults()
{
for (int i = 0; i < 0x24; i++)
for (const auto& reg_name_label : regnames)
{
if (regnames[i].name)
RegisterLabel(regnames[i].name, regnames[i].addr);
if (reg_name_label.name != nullptr)
RegisterLabel(reg_name_label.name, reg_name_label.addr);
}
for (int i = 0; i < (int)pdlabels_size; i++)
for (const auto& predefined_label : pdlabels)
{
if (pdlabels[i].name)
RegisterLabel(pdlabels[i].name, pdlabels[i].addr);
if (predefined_label.name != nullptr)
RegisterLabel(predefined_label.name, predefined_label.addr);
}
}