SPARC disassembler: tst, neg and more mov synthetics [Vas Crabb]

This commit is contained in:
Vas Crabb 2016-07-07 02:07:51 +10:00
parent bb15b6725e
commit f1720aaf32
2 changed files with 113 additions and 50 deletions

View File

@ -155,22 +155,22 @@ const sparc_disassembler::branch_desc sparc_disassembler::CBCCC_DESC = {
}; };
const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V7_INT_OP_DESC[] = { const sparc_disassembler::int_op_desc_map::value_type sparc_disassembler::V7_INT_OP_DESC[] = {
{ 0x00, { false, "add" } }, { 0x10, { false, "addcc" } }, { 0x00, { false, "add", nullptr } }, { 0x10, { false, "addcc", nullptr } },
{ 0x01, { true, "and" } }, { 0x11, { true, "andcc" } }, { 0x01, { true, "and", nullptr } }, { 0x11, { true, "andcc", "btst" } },
{ 0x02, { true, "or" } }, { 0x12, { true, "orcc" } }, { 0x02, { true, "or", nullptr } }, { 0x12, { true, "orcc", nullptr } },
{ 0x03, { true, "xor" } }, { 0x13, { true, "xorcc" } }, { 0x03, { true, "xor", nullptr } }, { 0x13, { true, "xorcc", nullptr } },
{ 0x04, { false, "sub" } }, { 0x14, { false, "subcc" } }, { 0x04, { false, "sub", nullptr } }, { 0x14, { false, "subcc", "cmp" } },
{ 0x05, { true, "andn" } }, { 0x15, { true, "andncc" } }, { 0x05, { true, "andn", nullptr } }, { 0x15, { true, "andncc", nullptr } },
{ 0x06, { true, "orn" } }, { 0x16, { true, "orncc" } }, { 0x06, { true, "orn", nullptr } }, { 0x16, { true, "orncc", nullptr } },
{ 0x07, { true, "xnor" } }, { 0x17, { true, "xnorcc" } }, { 0x07, { true, "xnor", nullptr } }, { 0x17, { true, "xnorcc", nullptr } },
{ 0x08, { false, "addx" } }, { 0x18, { false, "addxcc" } }, { 0x08, { false, "addx", nullptr } }, { 0x18, { false, "addxcc", nullptr } },
{ 0x0c, { false, "subx" } }, { 0x1c, { false, "subxcc" } }, { 0x0c, { false, "subx", nullptr } }, { 0x1c, { false, "subxcc", nullptr } },
{ 0x20, { false, "taddcc" } }, { 0x20, { false, "taddcc", nullptr } },
{ 0x21, { false, "tsubcc" } }, { 0x21, { false, "tsubcc", nullptr } },
{ 0x22, { false, "taddcctv" } }, { 0x22, { false, "taddcctv", nullptr } },
{ 0x23, { false, "tsubcctv" } }, { 0x23, { false, "tsubcctv", nullptr } },
{ 0x24, { false, "mulscc" } }, { 0x24, { false, "mulscc", nullptr } },
{ 0x3c, { false, "save" } }, { 0x3c, { false, "save" } },
{ 0x3d, { false, "restore" } } { 0x3d, { false, "restore" } }
@ -788,11 +788,23 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
} }
break; break;
case 0x04: case 0x04:
if (USEIMM && (RS1 == RD)) if (USEIMM)
{ {
if (SIMM13 == 1) print(buf, "%-*s%s", m_op_field_width, "dec", REG_NAMES[RD]); if (RS1 == RD)
else print(buf, "%-*s%d,%s", m_op_field_width, "dec", SIMM13, REG_NAMES[RD]); {
return 4 | DASMFLAG_SUPPORTED; if (SIMM13 == 1) print(buf, "%-*s%s", m_op_field_width, "dec", REG_NAMES[RD]);
else print(buf, "%-*s%d,%s", m_op_field_width, "dec", SIMM13, REG_NAMES[RD]);
return 4 | DASMFLAG_SUPPORTED;
}
}
else
{
if (RS1 == 0)
{
if (RS2 == RD) print(buf, "%-*s%s", m_op_field_width, "neg", REG_NAMES[RD]);
else print(buf, "%-*s%s,%s", m_op_field_width, "neg", REG_NAMES[RS2], REG_NAMES[RD]);
return 4 | DASMFLAG_SUPPORTED;
}
} }
break; break;
case 0x05: case 0x05:
@ -819,22 +831,15 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
break; break;
case 0x11: case 0x12:
if (RD == 0) if (!USEIMM && (RS1 == 0) && (RD == 0))
{ {
if (USEIMM) print(buf, "%-*s0x%08x,%s", m_op_field_width, "btst", SIMM13, REG_NAMES[RS1]); print(buf, "%-*s%s", m_op_field_width, "tst", REG_NAMES[RS2]);
else print(buf, "%-*s%s,%s", m_op_field_width, "btst", REG_NAMES[RS2], REG_NAMES[RS1]);
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
break; break;
case 0x14: case 0x14:
if (RD == 0) if (USEIMM && (RS1 == RD) && (RD != 0))
{
if (USEIMM) print(buf, "%-*s%s,%d", m_op_field_width, "cmp", REG_NAMES[RS1], SIMM13);
else print(buf, "%-*s%s,%s", m_op_field_width, "cmp", REG_NAMES[RS1], REG_NAMES[RS2]);
return 4 | DASMFLAG_SUPPORTED;
}
else if (USEIMM && (RS1 == RD))
{ {
if (SIMM13 == 1) print(buf, "%-*s%s", m_op_field_width, "deccc", REG_NAMES[RD]); if (SIMM13 == 1) print(buf, "%-*s%s", m_op_field_width, "deccc", REG_NAMES[RD]);
else print(buf, "%-*s%d,%s", m_op_field_width, "deccc", SIMM13, REG_NAMES[RD]); else print(buf, "%-*s%d,%s", m_op_field_width, "deccc", SIMM13, REG_NAMES[RD]);
@ -915,9 +920,16 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
} }
else else
{ {
if (!USEIMM) print(buf, "%-*s%s,%s,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); if (RS1 == 0)
else if (RS1 == 0) print(buf, "%-*s0x%08x,%%psr", m_op_field_width, "wr", SIMM13); {
else print(buf, "%-*s%s,0x%08x,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); if (USEIMM) print(buf, "%-*s0x%08x,%%psr", m_op_field_width, "mov", SIMM13);
else print(buf, "%-*s%s,%%psr", m_op_field_width, "mov", REG_NAMES[RS2]);
}
else
{
if (USEIMM) print(buf, "%-*s%s,0x%08x,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13);
else print(buf, "%-*s%s,%s,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]);
}
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
break; break;
@ -935,18 +947,32 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
} }
else else
{ {
if (!USEIMM) print(buf, "%-*s%s,%s,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); if (RS1 == 0)
else if (RS1 == 0) print(buf, "%-*s0x%08x,%%wim", m_op_field_width, "wr", SIMM13); {
else print(buf, "%-*s%s,0x%08x,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); if (USEIMM) print(buf, "%-*s0x%08x,%%wim", m_op_field_width, "mov", SIMM13);
else print(buf, "%-*s%s,%%wim", m_op_field_width, "mov", REG_NAMES[RS2]);
}
else
{
if (USEIMM) print(buf, "%-*s%s,0x%08x,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13);
else print(buf, "%-*s%s,%s,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]);
}
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
break; break;
case 0x33: case 0x33:
if (m_version <= 8) if (m_version <= 8)
{ {
if (!USEIMM) print(buf, "%-*s%s,%s,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); if (RS1 == 0)
else if (RS1 == 0) print(buf, "%-*s0x%08x,%%tbr", m_op_field_width, "wr", SIMM13); {
else print(buf, "%-*s%s,0x%08x,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); if (USEIMM) print(buf, "%-*s0x%08x,%%tbr", m_op_field_width, "mov", SIMM13);
else print(buf, "%-*s%s,%%tbr", m_op_field_width, "mov", REG_NAMES[RS2]);
}
else
{
if (USEIMM) print(buf, "%-*s%s,0x%08x,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13);
else print(buf, "%-*s%s,%s,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]);
}
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
break; break;
@ -1002,12 +1028,24 @@ offs_t sparc_disassembler::dasm(char *buf, offs_t pc, UINT32 op) const
const auto it(m_int_op_desc.find(OP3)); const auto it(m_int_op_desc.find(OP3));
if (it != m_int_op_desc.end()) if (it != m_int_op_desc.end())
{ {
if (!USEIMM) if (it->second.g0_synth && (RD == 0))
print(buf, "%-*s%s,%s,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]); {
else if (it->second.hex_imm) if (!USEIMM)
print(buf, "%-*s%s,0x%08x,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]); print(buf, "%-*s%s,%s", m_op_field_width, it->second.g0_synth, REG_NAMES[RS1], REG_NAMES[RS2]);
else if (it->second.hex_imm)
print(buf, "%-*s%s,0x%08x", m_op_field_width, it->second.g0_synth, REG_NAMES[RS1], SIMM13);
else
print(buf, "%-*s%s,%d", m_op_field_width, it->second.g0_synth, REG_NAMES[RS1], SIMM13);
}
else else
print(buf, "%-*s%s,%d,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]); {
if (!USEIMM)
print(buf, "%-*s%s,%s,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]);
else if (it->second.hex_imm)
print(buf, "%-*s%s,0x%08x,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]);
else
print(buf, "%-*s%s,%d,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]);
}
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
} }
@ -1145,8 +1183,16 @@ offs_t sparc_disassembler::dasm_write_state_reg(char *buf, offs_t pc, UINT32 op)
{ {
if (RD == 0) if (RD == 0)
{ {
if (USEIMM) print(buf, "%-*s%s,%d,%%y", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); if (RS1 == 0)
else print(buf, "%-*s%s,%s,%%y", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); {
if (USEIMM) print(buf, "%-*s%d,%%y", m_op_field_width, "mov", SIMM13);
else print(buf, "%-*s%s,%%y", m_op_field_width, "mov", REG_NAMES[RS2]);
}
else
{
if (USEIMM) print(buf, "%-*s%s,%08x,%%y", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13);
else print(buf, "%-*s%s,%s,%%y", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]);
}
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }
else if (m_version >= 8) else if (m_version >= 8)
@ -1163,14 +1209,30 @@ offs_t sparc_disassembler::dasm_write_state_reg(char *buf, offs_t pc, UINT32 op)
{ {
if ((it != m_state_reg_desc.end()) && it->second.write_name) if ((it != m_state_reg_desc.end()) && it->second.write_name)
{ {
if (USEIMM) print(buf, "%-*s%s,%d,%s", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13, it->second.write_name); if (RS1 == 0)
else print(buf, "%-*s%s,%s,%s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], it->second.write_name); {
if (USEIMM) print(buf, "%-*s%d,%s", m_op_field_width, "mov", SIMM13, it->second.write_name);
else print(buf, "%-*s%s,%s", m_op_field_width, "mov", REG_NAMES[RS2], it->second.write_name);
}
else
{
if (USEIMM) print(buf, "%-*s%s,%08x,%s", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13, it->second.write_name);
else print(buf, "%-*s%s,%s,%s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], it->second.write_name);
}
} }
else 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); if (RS1 == 0)
else print(buf, "%-*s%s,%s,%%asr%d ! %s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], RD, comment); {
if (USEIMM) print(buf, "%-*s%d,%%asr%d ! %s", m_op_field_width, "mov", SIMM13, RD, comment);
else print(buf, "%-*s%s,%%asr%d ! %s", m_op_field_width, "mov", REG_NAMES[RS2], RD, comment);
}
else
{
if (USEIMM) print(buf, "%-*s%s,%08x,%%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);
}
} }
return 4 | DASMFLAG_SUPPORTED; return 4 | DASMFLAG_SUPPORTED;
} }

View File

@ -123,6 +123,7 @@ private:
{ {
bool hex_imm; bool hex_imm;
const char *mnemonic; const char *mnemonic;
const char *g0_synth;
}; };
typedef std::map<UINT8, int_op_desc> int_op_desc_map; typedef std::map<UINT8, int_op_desc> int_op_desc_map;