ns32000: Disassembly format improvements

- Change number prefixes to better agree with NS assembly code examples
- Cut immediate operands down to size
- Format displacements as signed numbers and abbreviate small ones
- Force decimal format for bit positions and shift counts
This commit is contained in:
AJR 2020-03-17 21:05:51 -04:00
parent fa500f400d
commit b2a46fc6cf
2 changed files with 58 additions and 22 deletions

View File

@ -444,7 +444,7 @@ inline std::string ns32000_disassembler::get_options(uint8_t opts)
inline int32_t ns32000_disassembler::get_disp(offs_t &pc, const data_buffer &opcodes) inline int32_t ns32000_disassembler::get_disp(offs_t &pc, const data_buffer &opcodes)
{ {
/* displacement can be upto 3 bytes */ /* displacement can be upto 3 bytes */
uint32_t disp = bitswap<32>(opcodes.r32(pc), 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24); uint32_t disp = swapendian_int32(opcodes.r32(pc));
switch ((disp >> 29) & 0x07) switch ((disp >> 29) & 0x07)
{ {
@ -481,6 +481,16 @@ inline int32_t ns32000_disassembler::get_disp(offs_t &pc, const data_buffer &opc
return disp; return disp;
} }
inline std::string ns32000_disassembler::format_disp(int32_t disp)
{
if (disp >= -9 && disp <= 9)
return string_format("%d", disp);
else if (disp < 0)
return string_format("-0x%X", -disp);
else
return string_format("0x%X", disp);
}
inline std::string ns32000_disassembler::get_reg_list(offs_t &pc, const data_buffer &opcodes, bool reverse) inline std::string ns32000_disassembler::get_reg_list(offs_t &pc, const data_buffer &opcodes, bool reverse)
{ {
std::string reg_list; std::string reg_list;
@ -515,13 +525,13 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
/* Register Relative */ /* Register Relative */
disp1 = get_disp(pc, opcodes); disp1 = get_disp(pc, opcodes);
util::stream_format(stream, "%+d(%s)", disp1, R[gen_addr & 0x07]); util::stream_format(stream, "%s(%s)", format_disp(disp1), R[gen_addr & 0x07]);
break; break;
case 0x10: case 0x11: case 0x12: case 0x10: case 0x11: case 0x12:
/* Memory Relative */ /* Memory Relative */
disp1 = get_disp(pc, opcodes); disp1 = get_disp(pc, opcodes);
disp2 = get_disp(pc, opcodes); disp2 = get_disp(pc, opcodes);
util::stream_format(stream, "#X%02X(#X%02X(%s))", disp2, disp1, M[gen_addr & 0x03]); util::stream_format(stream, "%s(%s(%s))", format_disp(disp2), format_disp(disp1), M[gen_addr & 0x03]);
break; break;
case 0x13: case 0x13:
/* Reserved */ /* Reserved */
@ -529,10 +539,22 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l
break; break;
case 0x14: case 0x14:
/* Immediate */ /* Immediate */
if (op_class == operand_class::SOURCE) if (op_class == operand_class::SOURCE || op_class == operand_class::BITPOS)
{ {
disp1 = bitswap<32>(opcodes.r32(pc), 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24); if (op_len == 0)
util::stream_format(stream, "#X%02X", (op_len == 0 ? (disp1 >> 24) : (op_len == 1 ? (disp1 >> 16) : disp1))); disp1 = int8_t(opcodes.r8(pc));
else if (op_len == 1)
disp1 = int16_t(swapendian_int16(opcodes.r16(pc)));
else
disp1 = swapendian_int32(opcodes.r32(pc));
if (op_class == operand_class::BITPOS)
util::stream_format(stream, "$%d", disp1);
else if (op_len == 0)
util::stream_format(stream, "$0x%02X", uint8_t(disp1));
else if (op_len == 1)
util::stream_format(stream, "$0x%04X", uint16_t(disp1));
else
util::stream_format(stream, "$0x%08X", disp1);
pc += op_len + 1; pc += op_len + 1;
} }
else else
@ -541,7 +563,7 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l
case 0x15: case 0x15:
/* Absolute */ /* Absolute */
disp1 = get_disp(pc, opcodes); disp1 = get_disp(pc, opcodes);
util::stream_format(stream, "@#X%02X", disp1); util::stream_format(stream, "@0x%06X", disp1 & 0xffffff);
break; break;
case 0x16: case 0x16:
/* External */ /* External */
@ -556,12 +578,12 @@ void ns32000_disassembler::stream_gen(std::ostream &stream, u8 gen_addr, u8 op_l
case 0x18: case 0x19: case 0x1a: case 0x18: case 0x19: case 0x1a:
/* Memory Space */ /* Memory Space */
disp1 = get_disp(pc, opcodes); disp1 = get_disp(pc, opcodes);
util::stream_format(stream, "#X%02X(%s)", disp1, M[gen_addr & 0x03]); util::stream_format(stream, "%s(%s)", format_disp(disp1), M[gen_addr & 0x03]);
break; break;
case 0x1b: case 0x1b:
/* Memory Space */ /* Memory Space */
disp1 = get_disp(pc, opcodes); disp1 = get_disp(pc, opcodes);
util::stream_format(stream, "#X%06X", m_base_pc + disp1); util::stream_format(stream, "0x%06X", m_base_pc + disp1);
break; break;
case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
/* Scaled Index */ /* Scaled Index */
@ -593,7 +615,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
{ {
case 0: /* Format 0 */ case 0: /* Format 0 */
pc += 1; pc += 1;
util::stream_format(stream, "%-8s #X%06X", std::string("B").append(cond[Format0cond(opcode)]), m_base_pc + get_disp(pc, opcodes)); util::stream_format(stream, "%-8s 0x%06X", std::string("B").append(cond[Format0cond(opcode)]), m_base_pc + get_disp(pc, opcodes));
break; break;
case 0x01: /* Format 1 */ case 0x01: /* Format 1 */
@ -601,19 +623,20 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch (Format1op(opcode)) switch (Format1op(opcode))
{ {
case 0x00: case 0x00:
util::stream_format(stream, "%-8s #X%06X", Format1[Format1op(opcode)], m_base_pc + get_disp(pc, opcodes)); util::stream_format(stream, "%-8s 0x%06X", Format1[Format1op(opcode)], m_base_pc + get_disp(pc, opcodes));
flags |= STEP_OVER;
break; break;
case 0x01: case 0x01: case 0x03: case 0x04:
util::stream_format(stream, "%-8s #X%02X", Format1[Format1op(opcode)], get_disp(pc, opcodes) & 0xffffff); util::stream_format(stream, "%-8s %s", Format1[Format1op(opcode)], format_disp(get_disp(pc, opcodes)));
flags |= STEP_OUT;
break; break;
case 0x02: case 0x02:
util::stream_format(stream, "%-8s EXT(%d)", Format1[Format1op(opcode)], get_disp(pc, opcodes)); util::stream_format(stream, "%-8s EXT(%d)", Format1[Format1op(opcode)], get_disp(pc, opcodes));
break; flags |= STEP_OVER;
case 0x03: case 0x04:
util::stream_format(stream, "%-8s #X%02X", Format1[Format1op(opcode)], get_disp(pc, opcodes) & 0xffffff);
break; break;
case 0x05: case 0x05:
util::stream_format(stream, "%-8s", Format1[Format1op(opcode)]); util::stream_format(stream, "%-8s", Format1[Format1op(opcode)]);
flags |= STEP_OUT;
break; break;
case 0x06: case 0x06:
util::stream_format(stream, "%-8s %s", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, false)); util::stream_format(stream, "%-8s %s", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, false));
@ -622,7 +645,8 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
util::stream_format(stream, "%-8s %s", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, true)); util::stream_format(stream, "%-8s %s", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, true));
break; break;
case 0x08: case 0x08:
util::stream_format(stream, "%-8s %s, %d", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, false), get_disp(pc, opcodes)); util::stream_format(stream, "%-8s %s, ", Format1[Format1op(opcode)], get_reg_list(pc, opcodes, false));
util::stream_format(stream, "%s", format_disp(get_disp(pc, opcodes)));
break; break;
case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
util::stream_format(stream, "%-8s", Format1[Format1op(opcode)]); util::stream_format(stream, "%-8s", Format1[Format1op(opcode)]);
@ -636,7 +660,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
switch (Format2op(opcode)) switch (Format2op(opcode))
{ {
case 0x00: case 0x01: case 0x05: case 0x00: case 0x01: case 0x05:
util::stream_format(stream, "%-8s %+d, ", mnemonic, short2int(Format2short(opcode))); util::stream_format(stream, "%-8s $%d, ", mnemonic, short2int(Format2short(opcode)));
if (Format2op(opcode) == 0x01) if (Format2op(opcode) == 0x01)
stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::SOURCE, pc, opcodes); stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::SOURCE, pc, opcodes);
else else
@ -654,9 +678,9 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::DESTINATION, pc, opcodes); stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::DESTINATION, pc, opcodes);
break; break;
case 0x04: case 0x04:
util::stream_format(stream, "%-8s %+d, ", mnemonic, short2int(Format2short(opcode))); util::stream_format(stream, "%-8s %d, ", mnemonic, short2int(Format2short(opcode)));
stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::DESTINATION, pc, opcodes); stream_gen(stream, Format2gen(opcode), Format2i(opcode), operand_class::DESTINATION, pc, opcodes);
util::stream_format(stream, ", #X%06X", m_base_pc + get_disp(pc, opcodes)); util::stream_format(stream, ", 0x%06X", m_base_pc + get_disp(pc, opcodes));
break; break;
} }
break; break;
@ -669,6 +693,8 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
case 0x00: case 0x02: case 0x04: case 0x06: case 0x0a: case 0x0c: case 0x0e: case 0x00: case 0x02: case 0x04: case 0x06: case 0x0a: case 0x0c: case 0x0e:
util::stream_format(stream, "%-8s ", mnemonic); util::stream_format(stream, "%-8s ", mnemonic);
stream_gen(stream, Format3gen(opcode), Format3i(opcode), operand_class::SOURCE, pc, opcodes); stream_gen(stream, Format3gen(opcode), Format3i(opcode), operand_class::SOURCE, pc, opcodes);
if (Format3op(opcode) == 0x00 || Format3op(opcode) == 0x0c)
flags |= STEP_OVER;
break; break;
default: /* Trap */ default: /* Trap */
util::stream_format(stream, "%-8s ", mnemonic); util::stream_format(stream, "%-8s ", mnemonic);
@ -682,6 +708,8 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
util::stream_format(stream, "%-8s ", mnemonic); util::stream_format(stream, "%-8s ", mnemonic);
if (Format4op(opcode) == 0x09) if (Format4op(opcode) == 0x09)
stream_gen(stream, Format4gen1(opcode), Format4i(opcode), operand_class::ADDRESS, pc, opcodes); stream_gen(stream, Format4gen1(opcode), Format4i(opcode), operand_class::ADDRESS, pc, opcodes);
else if (Format4op(opcode) == 0x0d)
stream_gen(stream, Format4gen1(opcode), Format4i(opcode), operand_class::BITPOS, pc, opcodes);
else else
stream_gen(stream, Format4gen1(opcode), Format4i(opcode), operand_class::SOURCE, pc, opcodes); stream_gen(stream, Format4gen1(opcode), Format4i(opcode), operand_class::SOURCE, pc, opcodes);
util::stream_format(stream, ", "); util::stream_format(stream, ", ");
@ -718,11 +746,17 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, const
{ {
case 0x00: case 0x01: case 0x05: case 0x00: case 0x01: case 0x05:
util::stream_format(stream, "%-8s ", mnemonic); util::stream_format(stream, "%-8s ", mnemonic);
stream_gen(stream, Format6gen1(opcode), B, operand_class::SOURCE, pc, opcodes); stream_gen(stream, Format6gen1(opcode), B, operand_class::BITPOS, pc, opcodes);
util::stream_format(stream, ", "); util::stream_format(stream, ", ");
stream_gen(stream, Format6gen2(opcode), Format6i(opcode), operand_class::DESTINATION, pc, opcodes); stream_gen(stream, Format6gen2(opcode), Format6i(opcode), operand_class::DESTINATION, pc, opcodes);
break; break;
case 0x02: case 0x03: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: case 0x02: case 0x03: case 0x06: case 0x07: case 0x0e:
util::stream_format(stream, "%-8s ", mnemonic);
stream_gen(stream, Format6gen1(opcode), Format6i(opcode), operand_class::BITPOS, pc, opcodes);
util::stream_format(stream, ", ");
stream_gen(stream, Format6gen2(opcode), Format6i(opcode), operand_class::DESTINATION, pc, opcodes);
break;
case 0x08: case 0x09: case 0x0b: case 0x0c: case 0x0d: case 0x0f:
util::stream_format(stream, "%-8s ", mnemonic); util::stream_format(stream, "%-8s ", mnemonic);
stream_gen(stream, Format6gen1(opcode), Format6i(opcode), operand_class::SOURCE, pc, opcodes); stream_gen(stream, Format6gen1(opcode), Format6i(opcode), operand_class::SOURCE, pc, opcodes);
util::stream_format(stream, ", "); util::stream_format(stream, ", ");

View File

@ -67,6 +67,7 @@ private:
enum class operand_class enum class operand_class
{ {
SOURCE, SOURCE,
BITPOS,
DESTINATION, DESTINATION,
ADDRESS, ADDRESS,
SCALED_INDEX SCALED_INDEX
@ -113,6 +114,7 @@ private:
uint8_t opcode_format(uint8_t byte); uint8_t opcode_format(uint8_t byte);
int8_t short2int(uint8_t val); int8_t short2int(uint8_t val);
static inline int32_t get_disp(offs_t &pc, const data_buffer &opcodes); static inline int32_t get_disp(offs_t &pc, const data_buffer &opcodes);
static inline std::string format_disp(int32_t disp);
static inline std::string get_option_list(uint8_t cfg); static inline std::string get_option_list(uint8_t cfg);
static inline std::string get_options(uint8_t opts); static inline std::string get_options(uint8_t opts);
static inline std::string get_reg_list(offs_t &pc, const data_buffer &opcodes, bool reverse); static inline std::string get_reg_list(offs_t &pc, const data_buffer &opcodes, bool reverse);