mirror of
https://github.com/holub/mame
synced 2025-06-04 20:06:28 +03:00
VIS I (UltraSPARC) and II (UltraSPARC III) for SPARC disassembler [Vas Crabb]
* Supports %gsr, all ops with exception of SIAM, and all ASI constants * Use -arch sparcv9vis1 or -arch sparcv9vis2 with unidasm
This commit is contained in:
parent
5884c383c2
commit
32a75e7ae4
@ -165,6 +165,7 @@ links {
|
||||
|
||||
includedirs {
|
||||
MAME_DIR .. "src/osd",
|
||||
MAME_DIR .. "src/devices",
|
||||
MAME_DIR .. "src/emu",
|
||||
MAME_DIR .. "src/lib/util",
|
||||
MAME_DIR .. "3rdparty",
|
||||
@ -779,7 +780,7 @@ if _OPTIONS["targetos"] == "macosx" then
|
||||
MAME_DIR .. "src/tools/aueffectutil.mm",
|
||||
}
|
||||
|
||||
configuration { }
|
||||
configuration { }
|
||||
|
||||
strip()
|
||||
end
|
||||
|
@ -8,13 +8,11 @@
|
||||
#include "sparcdasm.h"
|
||||
#include "sparcdefs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
namespace {
|
||||
const sparc_disassembler DASM_V7(7);
|
||||
const sparc_disassembler DASM_V8(8);
|
||||
const sparc_disassembler DASM_V9(9);
|
||||
|
||||
namespace {
|
||||
INT32 get_disp16(UINT32 op) { return DISP19; }
|
||||
INT32 get_disp19(UINT32 op) { return DISP19; }
|
||||
INT32 get_disp22(UINT32 op) { return DISP19; }
|
||||
@ -127,12 +125,12 @@ const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V9_INT
|
||||
};
|
||||
|
||||
const sparc_disassembler::state_reg_desc_map::value_type sparc_disassembler::V9_STATE_REG_DESC[] = {
|
||||
{ 1, { true, nullptr, nullptr } },
|
||||
{ 2, { false, "%ccr", "%ccr" } },
|
||||
{ 3, { false, "%asi", "%asi" } },
|
||||
{ 4, { false, "%tick", nullptr } },
|
||||
{ 5, { false, "%pc", nullptr } },
|
||||
{ 6, { false, "%fprs", "%fprs" } }
|
||||
{ 1, { true, nullptr, nullptr } },
|
||||
{ 2, { false, "%ccr", "%ccr" } },
|
||||
{ 3, { false, "%asi", "%asi" } },
|
||||
{ 4, { false, "%tick", nullptr } },
|
||||
{ 5, { false, "%pc", nullptr } },
|
||||
{ 6, { false, "%fprs", "%fprs" } }
|
||||
};
|
||||
|
||||
const char * const sparc_disassembler::MOVCC_CC_NAMES[8] = {
|
||||
@ -285,8 +283,7 @@ const sparc_disassembler::asi_desc_map::value_type sparc_disassembler::V9_ASI_DE
|
||||
{ 0x8b, { "#ASI_SNF_L", nullptr } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::prftch_desc_map::value_type sparc_disassembler::V9_PRFTCH_DESC[] =
|
||||
{
|
||||
const sparc_disassembler::prftch_desc_map::value_type sparc_disassembler::V9_PRFTCH_DESC[] = {
|
||||
{ 0x00, { "#n_reads" } },
|
||||
{ 0x01, { "#one_read" } },
|
||||
{ 0x02, { "#n_writes" } },
|
||||
@ -294,6 +291,142 @@ const sparc_disassembler::prftch_desc_map::value_type sparc_disassembler::V9_PRF
|
||||
{ 0x04, { "#page" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::vis_op_desc_map::value_type sparc_disassembler::VIS1_OP_DESC[] = {
|
||||
{ 0x000, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge8" } },
|
||||
{ 0x002, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge8l" } },
|
||||
{ 0x004, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge16" } },
|
||||
{ 0x006, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge16l" } },
|
||||
{ 0x008, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge32" } },
|
||||
{ 0x00a, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge32l" } },
|
||||
|
||||
{ 0x010, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "array8" } },
|
||||
{ 0x012, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "array16" } },
|
||||
{ 0x014, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "array32" } },
|
||||
{ 0x018, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, true, "alignaddr" } },
|
||||
{ 0x01a, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, true, "alignaddrl" } },
|
||||
|
||||
{ 0x020, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmple16" } },
|
||||
{ 0x022, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpne16" } },
|
||||
{ 0x024, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmple32" } },
|
||||
{ 0x026, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpne32" } },
|
||||
{ 0x028, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpgt16" } },
|
||||
{ 0x02a, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpeq16" } },
|
||||
{ 0x02c, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpgt32" } },
|
||||
{ 0x02e, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::I, false, "fcmpeq32" } },
|
||||
|
||||
{ 0x031, { vis_op_desc::Fs, vis_op_desc::Fd, vis_op_desc::Fd, false, "fmul8x16" } },
|
||||
{ 0x033, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fd, false, "fmul8x16au" } },
|
||||
{ 0x035, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fd, false, "fmul8x16al" } },
|
||||
{ 0x036, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fmul8sux16" } },
|
||||
{ 0x037, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fmul8ulx16" } },
|
||||
{ 0x038, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fd, false, "fmuld8sux16" } },
|
||||
{ 0x039, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fd, false, "fmuld8ulx16" } },
|
||||
{ 0x03a, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fpack32" } },
|
||||
{ 0x03b, { vis_op_desc::X, vis_op_desc::Fd, vis_op_desc::Fs, false, "fpack16" } },
|
||||
{ 0x03d, { vis_op_desc::X, vis_op_desc::Fd, vis_op_desc::Fs, false, "fpackfix" } },
|
||||
{ 0x03e, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "pdist" } },
|
||||
|
||||
{ 0x048, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "faligndata" } },
|
||||
{ 0x04b, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fd, false, "fpmerge" } },
|
||||
{ 0x04d, { vis_op_desc::X, vis_op_desc::Fs, vis_op_desc::Fd, false, "fexpand" } },
|
||||
|
||||
{ 0x050, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fpadd16" } },
|
||||
{ 0x051, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fpadd16s" } },
|
||||
{ 0x052, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fpadd32" } },
|
||||
{ 0x053, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fpadd32s" } },
|
||||
{ 0x054, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fpsub16" } },
|
||||
{ 0x055, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fpsub16s" } },
|
||||
{ 0x056, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fpsub32" } },
|
||||
{ 0x057, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fpsub32s" } },
|
||||
|
||||
{ 0x060, { vis_op_desc::X, vis_op_desc::X, vis_op_desc::Fd, false, "fzero" } },
|
||||
{ 0x061, { vis_op_desc::X, vis_op_desc::X, vis_op_desc::Fs, false, "fzeros" } },
|
||||
{ 0x062, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fnor" } },
|
||||
{ 0x063, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fnors" } },
|
||||
{ 0x064, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fandnot2" } },
|
||||
{ 0x065, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fandnot2s" } },
|
||||
{ 0x066, { vis_op_desc::X, vis_op_desc::Fd, vis_op_desc::Fd, false, "fnot2" } },
|
||||
{ 0x067, { vis_op_desc::X, vis_op_desc::Fs, vis_op_desc::Fs, false, "fnot2s" } },
|
||||
{ 0x068, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fandnot1" } },
|
||||
{ 0x069, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fandnot1s" } },
|
||||
{ 0x06a, { vis_op_desc::Fd, vis_op_desc::X, vis_op_desc::Fd, false, "fnot1" } },
|
||||
{ 0x06b, { vis_op_desc::Fs, vis_op_desc::X, vis_op_desc::Fs, false, "fnot1s" } },
|
||||
{ 0x06c, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fxor" } },
|
||||
{ 0x06d, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fxors" } },
|
||||
{ 0x06e, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fnand" } },
|
||||
{ 0x06f, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fnands" } },
|
||||
|
||||
{ 0x070, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fand" } },
|
||||
{ 0x071, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fands" } },
|
||||
{ 0x072, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fxnor" } },
|
||||
{ 0x073, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fxnors" } },
|
||||
{ 0x074, { vis_op_desc::Fd, vis_op_desc::X, vis_op_desc::Fd, false, "fsrc1" } },
|
||||
{ 0x075, { vis_op_desc::Fs, vis_op_desc::X, vis_op_desc::Fs, false, "fsrc1s" } },
|
||||
{ 0x076, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fornot2" } },
|
||||
{ 0x077, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fornot2s" } },
|
||||
{ 0x078, { vis_op_desc::X, vis_op_desc::Fd, vis_op_desc::Fd, false, "fsrc2" } },
|
||||
{ 0x079, { vis_op_desc::X, vis_op_desc::Fs, vis_op_desc::Fs, false, "fsrc2s" } },
|
||||
{ 0x07a, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "fornot1" } },
|
||||
{ 0x07b, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fornot1s" } },
|
||||
{ 0x07c, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "for" } },
|
||||
{ 0x07d, { vis_op_desc::Fs, vis_op_desc::Fs, vis_op_desc::Fs, false, "fors" } },
|
||||
{ 0x07e, { vis_op_desc::X, vis_op_desc::X, vis_op_desc::Fd, false, "fone" } },
|
||||
{ 0x07f, { vis_op_desc::X, vis_op_desc::X, vis_op_desc::Fs, false, "fones" } },
|
||||
|
||||
{ 0x080, { vis_op_desc::X, vis_op_desc::X, vis_op_desc::X, false, "shutdown" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::state_reg_desc_map::value_type sparc_disassembler::VIS1_STATE_REG_DESC[] = {
|
||||
{ 19, { false, "%gsr", "%gsr" } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::asi_desc_map::value_type sparc_disassembler::VIS1_ASI_DESC[] = {
|
||||
{ 0x2c, { "#ASI_NUCLEUS_QUAD_LDD_L", nullptr } },
|
||||
{ 0x70, { "#ASI_BLK_AIUP", nullptr } },
|
||||
{ 0x71, { "#ASI_BLK_AIUS", nullptr } },
|
||||
{ 0x78, { "#ASI_BLK_AIUPL", nullptr } },
|
||||
{ 0x79, { "#ASI_BLK_AIUSL", nullptr } },
|
||||
{ 0xc0, { "#ASI_PST8_P", nullptr } },
|
||||
{ 0xc1, { "#ASI_PST8_S", nullptr } },
|
||||
{ 0xc2, { "#ASI_PST16_P", nullptr } },
|
||||
{ 0xc3, { "#ASI_PST16_S", nullptr } },
|
||||
{ 0xc4, { "#ASI_PST32_P", nullptr } },
|
||||
{ 0xc5, { "#ASI_PST32_S", nullptr } },
|
||||
{ 0xc8, { "#ASI_PST8_PL", nullptr } },
|
||||
{ 0xc9, { "#ASI_PST8_SL", nullptr } },
|
||||
{ 0xca, { "#ASI_PST16_PL", nullptr } },
|
||||
{ 0xcb, { "#ASI_PST16_SL", nullptr } },
|
||||
{ 0xcc, { "#ASI_PST32_PL", nullptr } },
|
||||
{ 0xcd, { "#ASI_PST32_SL", nullptr } },
|
||||
{ 0xd0, { "#ASI_FL8_P", nullptr } },
|
||||
{ 0xd1, { "#ASI_FL8_S", nullptr } },
|
||||
{ 0xd2, { "#ASI_FL16_P", nullptr } },
|
||||
{ 0xd3, { "#ASI_FL16_S", nullptr } },
|
||||
{ 0xd8, { "#ASI_FL8_PL", nullptr } },
|
||||
{ 0xd9, { "#ASI_FL8_SL", nullptr } },
|
||||
{ 0xda, { "#ASI_FL16_PL", nullptr } },
|
||||
{ 0xdb, { "#ASI_FL16_SL", nullptr } },
|
||||
{ 0xe0, { "#ASI_BLOCK_COMMIT_P", nullptr } },
|
||||
{ 0xe1, { "#ASI_BLOCK_COMMIT_S", nullptr } },
|
||||
{ 0xf0, { "#ASI_BLOCK_P", nullptr } },
|
||||
{ 0xf1, { "#ASI_BLOCK_S", nullptr } },
|
||||
{ 0xf8, { "#ASI_BLOCK_PL", nullptr } },
|
||||
{ 0xf9, { "#ASI_BLOCK_SL", nullptr } }
|
||||
};
|
||||
|
||||
const sparc_disassembler::vis_op_desc_map::value_type sparc_disassembler::VIS2_OP_DESC[] = {
|
||||
{ 0x001, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge8n" } },
|
||||
{ 0x003, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge8ln" } },
|
||||
{ 0x005, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge16n" } },
|
||||
{ 0x007, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge16ln" } },
|
||||
{ 0x009, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge32n" } },
|
||||
{ 0x00b, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, false, "edge32ln" } },
|
||||
|
||||
{ 0x019, { vis_op_desc::I, vis_op_desc::I, vis_op_desc::I, true, "bmask" } },
|
||||
|
||||
{ 0x04c, { vis_op_desc::Fd, vis_op_desc::Fd, vis_op_desc::Fd, false, "bshuffle" } }
|
||||
};
|
||||
|
||||
|
||||
inline UINT32 sparc_disassembler::freg(UINT32 val, bool shift) const
|
||||
{
|
||||
@ -324,6 +457,12 @@ template <typename T> inline void sparc_disassembler::add_ldst_desc(const T &des
|
||||
m_ldst_desc.insert(it);
|
||||
}
|
||||
|
||||
template <typename T> inline void sparc_disassembler::add_vis_op_desc(const T &desc)
|
||||
{
|
||||
for (const auto &it : desc)
|
||||
m_vis_op_desc.insert(it);
|
||||
}
|
||||
|
||||
inline void sparc_disassembler::pad_op_field(char *buf, char *&output) const
|
||||
{
|
||||
while ((output - buf) < m_op_field_width) *output++ = ' ';
|
||||
@ -358,6 +497,7 @@ sparc_disassembler::sparc_disassembler(unsigned version)
|
||||
, m_ldst_desc(std::begin(V7_LDST_DESC), std::end(V7_LDST_DESC))
|
||||
, m_asi_desc()
|
||||
, m_prftch_desc()
|
||||
, m_vis_op_desc()
|
||||
{
|
||||
if (m_version >= 8)
|
||||
{
|
||||
@ -395,6 +535,22 @@ sparc_disassembler::sparc_disassembler(unsigned version)
|
||||
}
|
||||
|
||||
|
||||
void sparc_disassembler::enable_vis1()
|
||||
{
|
||||
m_op_field_width = std::max(m_op_field_width, 12);
|
||||
add_vis_op_desc(VIS1_OP_DESC);
|
||||
add_state_reg_desc(VIS1_STATE_REG_DESC);
|
||||
add_asi_desc(VIS1_ASI_DESC);
|
||||
}
|
||||
|
||||
|
||||
void sparc_disassembler::enable_vis2()
|
||||
{
|
||||
enable_vis1();
|
||||
add_vis_op_desc(VIS2_OP_DESC);
|
||||
}
|
||||
|
||||
|
||||
offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
|
||||
{
|
||||
switch (OP)
|
||||
@ -620,8 +776,7 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
|
||||
case 0x35:
|
||||
return dasm_fpop2(buf, pc, op);
|
||||
case 0x36:
|
||||
// TODO: hooks for IMPDEP1/CPop1
|
||||
break;
|
||||
return dasm_impdep1(buf, pc, op);
|
||||
case 0x37:
|
||||
// TODO: hooks for IMPDEP2/CPop2
|
||||
break;
|
||||
@ -832,7 +987,7 @@ offs_t sparc_disassembler::dasm_write_state_reg(char *buf, offs_t pc, UINT32 op)
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *const comment((RD < 16) ? "reserved" : "implementation-dependent");
|
||||
const char * const comment((RD < 16) ? "reserved" : "implementation-dependent");
|
||||
if (USEIMM) print(buf, "%-*s%s,%d,%%asr%d ! %s", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13, RD, comment);
|
||||
else print(buf, "%-*s%s,%s,%%asr%d ! %s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], RD, comment);
|
||||
}
|
||||
@ -936,6 +1091,36 @@ offs_t sparc_disassembler::dasm_fpop2(char *buf, offs_t pc, UINT32 op) const
|
||||
}
|
||||
|
||||
|
||||
offs_t sparc_disassembler::dasm_impdep1(char *buf, offs_t pc, UINT32 op) const
|
||||
{
|
||||
const auto it(m_vis_op_desc.find(OPF));
|
||||
if (it != m_vis_op_desc.end())
|
||||
{
|
||||
print(buf, "%-*s", m_op_field_width, it->second.mnemonic);
|
||||
bool args(false);
|
||||
if (it->second.collapse && !RS1)
|
||||
{
|
||||
dasm_vis_arg(buf, args, it->second.rs2, RS2);
|
||||
}
|
||||
else if (it->second.collapse && !RS2)
|
||||
{
|
||||
dasm_vis_arg(buf, args, it->second.rs1, RS1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dasm_vis_arg(buf, args, it->second.rs1, RS1);
|
||||
dasm_vis_arg(buf, args, it->second.rs2, RS2);
|
||||
}
|
||||
dasm_vis_arg(buf, args, it->second.rd, RD);
|
||||
return 4 | DASMFLAG_SUPPORTED;
|
||||
}
|
||||
|
||||
// TODO: driver hook for other kinds of coprocessor?
|
||||
|
||||
return dasm_invalid(buf, pc, op);
|
||||
}
|
||||
|
||||
|
||||
offs_t sparc_disassembler::dasm_jmpl(char *buf, offs_t pc, UINT32 op) const
|
||||
{
|
||||
if (USEIMM && (RD == 0) && ((RS1 == 15) || (RS1 == 31)) && (SIMM13 == 8))
|
||||
@ -1167,20 +1352,20 @@ void sparc_disassembler::dasm_asi_comment(char *&output, UINT32 op) const
|
||||
}
|
||||
|
||||
|
||||
CPU_DISASSEMBLE( sparcv7 )
|
||||
void sparc_disassembler::dasm_vis_arg(char *&output, bool &args, vis_op_desc::arg fmt, UINT32 reg) const
|
||||
{
|
||||
UINT32 op = *reinterpret_cast<const UINT32 *>(oprom);
|
||||
return DASM_V7.dasm(buffer, pc, BIG_ENDIANIZE_INT32(op));
|
||||
}
|
||||
|
||||
CPU_DISASSEMBLE( sparcv8 )
|
||||
{
|
||||
UINT32 op = *reinterpret_cast<const UINT32 *>(oprom);
|
||||
return DASM_V8.dasm(buffer, pc, BIG_ENDIANIZE_INT32(op));
|
||||
}
|
||||
|
||||
CPU_DISASSEMBLE( sparcv9 )
|
||||
{
|
||||
UINT32 op = *reinterpret_cast<const UINT32 *>(oprom);
|
||||
return DASM_V9.dasm(buffer, pc, BIG_ENDIANIZE_INT32(op));
|
||||
switch (fmt)
|
||||
{
|
||||
case vis_op_desc::X:
|
||||
break;
|
||||
case vis_op_desc::I:
|
||||
print(output, args ? ",%s" : "%s", REG_NAMES[reg]);
|
||||
args = true;
|
||||
break;
|
||||
case vis_op_desc::Fs:
|
||||
case vis_op_desc::Fd:
|
||||
print(output, args ? ",%%f%d" : "%%f%d", freg(reg, (fmt == vis_op_desc::Fd)));
|
||||
args = true;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ public:
|
||||
|
||||
sparc_disassembler(unsigned version);
|
||||
|
||||
void enable_vis1();
|
||||
void enable_vis2();
|
||||
|
||||
template <typename T> void add_state_reg_desc(const T &desc)
|
||||
{
|
||||
for (const auto &it : desc)
|
||||
@ -131,6 +134,17 @@ private:
|
||||
};
|
||||
typedef std::map<UINT8, ldst_desc> ldst_desc_map;
|
||||
|
||||
struct vis_op_desc
|
||||
{
|
||||
enum arg { X, I, Fs, Fd };
|
||||
arg rs1 = X;
|
||||
arg rs2 = X;
|
||||
arg rd = X;
|
||||
bool collapse = false;
|
||||
const char *mnemonic = nullptr;
|
||||
};
|
||||
typedef std::map<UINT16, vis_op_desc> vis_op_desc_map;
|
||||
|
||||
offs_t dasm_invalid(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_branch(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_shift(char *buf, offs_t pc, UINT32 op, const char *mnemonic, const char *mnemonicx, const char *mnemonicx0) const;
|
||||
@ -140,6 +154,7 @@ private:
|
||||
offs_t dasm_move_reg_cond(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_fpop1(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_fpop2(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_impdep1(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_jmpl(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_return(char *buf, offs_t pc, UINT32 op) const;
|
||||
offs_t dasm_tcc(char *buf, offs_t pc, UINT32 op) const;
|
||||
@ -148,6 +163,7 @@ private:
|
||||
void dasm_address(char *&output, UINT32 op) const;
|
||||
void dasm_asi(char *&output, UINT32 op) const;
|
||||
void dasm_asi_comment(char *&output, UINT32 op) const;
|
||||
void dasm_vis_arg(char *&output, bool &args, vis_op_desc::arg fmt, UINT32 reg) const;
|
||||
|
||||
UINT32 freg(UINT32 val, bool shift) const;
|
||||
|
||||
@ -155,6 +171,7 @@ private:
|
||||
template <typename T> void add_fpop1_desc(const T &desc);
|
||||
template <typename T> void add_fpop2_desc(const T &desc);
|
||||
template <typename T> void add_ldst_desc(const T &desc);
|
||||
template <typename T> void add_vis_op_desc(const T &desc);
|
||||
|
||||
void pad_op_field(char *buf, char *&output) const;
|
||||
ATTR_PRINTF(2, 3) static void print(char *&output, const char *fmt, ...);
|
||||
@ -183,6 +200,10 @@ private:
|
||||
static const ldst_desc_map::value_type V9_LDST_DESC[];
|
||||
static const asi_desc_map::value_type V9_ASI_DESC[];
|
||||
static const prftch_desc_map::value_type V9_PRFTCH_DESC[];
|
||||
static const vis_op_desc_map::value_type VIS1_OP_DESC[];
|
||||
static const state_reg_desc_map::value_type VIS1_STATE_REG_DESC[];
|
||||
static const asi_desc_map::value_type VIS1_ASI_DESC[];
|
||||
static const vis_op_desc_map::value_type VIS2_OP_DESC[];
|
||||
|
||||
unsigned m_version;
|
||||
int m_op_field_width;
|
||||
@ -194,6 +215,7 @@ private:
|
||||
ldst_desc_map m_ldst_desc;
|
||||
asi_desc_map m_asi_desc;
|
||||
prftch_desc_map m_prftch_desc;
|
||||
vis_op_desc_map m_vis_op_desc;
|
||||
};
|
||||
|
||||
CPU_DISASSEMBLE( sparcv7 );
|
||||
|
@ -9,6 +9,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/sparc/sparcdasm.h"
|
||||
#include <ctype.h>
|
||||
|
||||
enum display_type
|
||||
@ -163,9 +164,6 @@ CPU_DISASSEMBLE( sm500 );
|
||||
CPU_DISASSEMBLE( sm510 );
|
||||
CPU_DISASSEMBLE( sm511 );
|
||||
CPU_DISASSEMBLE( sm8500 );
|
||||
CPU_DISASSEMBLE( sparcv7 );
|
||||
CPU_DISASSEMBLE( sparcv8 );
|
||||
CPU_DISASSEMBLE( sparcv9 );
|
||||
CPU_DISASSEMBLE( spc700 );
|
||||
CPU_DISASSEMBLE( ssem );
|
||||
CPU_DISASSEMBLE( ssp1601 );
|
||||
@ -209,6 +207,25 @@ CPU_DISASSEMBLE( z8 );
|
||||
CPU_DISASSEMBLE( z80 );
|
||||
CPU_DISASSEMBLE( z8000 );
|
||||
|
||||
static sparc_disassembler sparcv7_dasm(7);
|
||||
static sparc_disassembler sparcv8_dasm(8);
|
||||
static sparc_disassembler sparcv9_dasm(9);
|
||||
static sparc_disassembler sparcv9vis1_dasm(9);
|
||||
static sparc_disassembler sparcv9vis2_dasm(9);
|
||||
struct sparc_helper_c
|
||||
{
|
||||
sparc_helper_c()
|
||||
{
|
||||
sparcv9vis1_dasm.enable_vis1();
|
||||
sparcv9vis2_dasm.enable_vis2();
|
||||
}
|
||||
} sparc_helper;
|
||||
CPU_DISASSEMBLE( sparcv7 ) { return sparcv7_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(*reinterpret_cast<const UINT32 *>(oprom))); }
|
||||
CPU_DISASSEMBLE( sparcv8 ) { return sparcv8_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(*reinterpret_cast<const UINT32 *>(oprom))); }
|
||||
CPU_DISASSEMBLE( sparcv9 ) { return sparcv9_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(*reinterpret_cast<const UINT32 *>(oprom))); }
|
||||
CPU_DISASSEMBLE( sparcv9vis1 ) { return sparcv9vis1_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(*reinterpret_cast<const UINT32 *>(oprom))); }
|
||||
CPU_DISASSEMBLE( sparcv9vis2 ) { return sparcv9vis2_dasm.dasm(buffer, pc, BIG_ENDIANIZE_INT32(*reinterpret_cast<const UINT32 *>(oprom))); }
|
||||
|
||||
|
||||
static const dasm_table_entry dasm_table[] =
|
||||
{
|
||||
@ -325,6 +342,8 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "sparcv7", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv7) },
|
||||
{ "sparcv8", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv8) },
|
||||
{ "sparcv9", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9) },
|
||||
{ "sparcv9vis1",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis1) },
|
||||
{ "sparcv9vis2",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2) },
|
||||
{ "spc700", _8bit, 0, CPU_DISASSEMBLE_NAME(spc700) },
|
||||
{ "ssem", _32le, 0, CPU_DISASSEMBLE_NAME(ssem) },
|
||||
{ "ssp1601", _16be, -1, CPU_DISASSEMBLE_NAME(ssp1601) },
|
||||
@ -491,15 +510,15 @@ usage:
|
||||
printf(" [-skip <n>] [-count <n>]\n");
|
||||
printf("\n");
|
||||
printf("Supported architectures:");
|
||||
numrows = (ARRAY_LENGTH(dasm_table) + 6) / 7;
|
||||
for (curarch = 0; curarch < numrows * 7; curarch++)
|
||||
numrows = (ARRAY_LENGTH(dasm_table) + 5) / 6;
|
||||
for (curarch = 0; curarch < numrows * 6; curarch++)
|
||||
{
|
||||
int row = curarch / 7;
|
||||
int col = curarch % 7;
|
||||
int row = curarch / 6;
|
||||
int col = curarch % 6;
|
||||
int index = col * numrows + row;
|
||||
if (col == 0)
|
||||
printf("\n ");
|
||||
printf("%-11s", (index < ARRAY_LENGTH(dasm_table)) ? dasm_table[index].name : "");
|
||||
printf("%-12s", (index < ARRAY_LENGTH(dasm_table)) ? dasm_table[index].name : "");
|
||||
}
|
||||
printf("\n");
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user