summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disasm.cpp528
-rw-r--r--disasm.h9
-rw-r--r--main.cpp10
3 files changed, 273 insertions, 274 deletions
diff --git a/disasm.cpp b/disasm.cpp
index a3f7a36..7ada0ce 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -340,30 +340,30 @@ static inline size_t snprint_reg_mask(
return written;
}
-static void disasm_verbatim(
- DisasmNode &node, uint16_t instr, const DataBuffer &, const Settings &)
+static size_t disasm_verbatim(
+ DisasmNode &node, uint16_t instr, const DataBuffer &)
{
- node.size = kInstructionSizeStepBytes;
snprintf(node.mnemonic, kMnemonicBufferSize, ".short");
snprintf(node.arguments, kArgsBufferSize, "0x%04x", instr);
+ return node.size = kInstructionSizeStepBytes;
}
-static void disasm_jsr_jmp(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s, JType jsrjmp)
+static size_t disasm_jsr_jmp(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code, JType jsrjmp)
{
const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, instr, 'w');
switch (a.mode) {
case AddrMode::kInvalid:
case AddrMode::kDn: // 4e80..4e87 / 4ec0..4ec7
case AddrMode::kAn: // 4e88..4e8f / 4ec8..4ecf
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr: // 4e90..4e97 / 4ed0..4ed7
// NOTE: dynamic jump, branch_addr may possibly be obtained during the
// trace
break;
case AddrMode::kAnAddrIncr: // 4e98..4e9f / 4ed8..4edf
case AddrMode::kAnAddrDecr: // 4ea0..4ea7 / 4ee0..4ee7
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kD16AnAddr: // 4ea8..4eaf / 4ee8..4eef
// NOTE: dynamic jump, branch_addr may possibly be obtained during the
// trace
@@ -401,18 +401,18 @@ static void disasm_jsr_jmp(
// trace
break;
case AddrMode::kImmediate: // 4ebc / 4efc
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
node.is_call = (jsrjmp == JType::kJsr);
- node.size = kInstructionSizeStepBytes + a.Size();
const char *mnemonic = (jsrjmp == JType::kJsr) ? "jsr" : "jmp";
snprintf(node.mnemonic, kMnemonicBufferSize, "%s", mnemonic);
const int ret = a.SNPrint(node.arguments, kArgsBufferSize);
assert(ret > 0);
(void) ret;
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
-static void disasm_ext(
+static size_t disasm_ext(
DisasmNode &node,
const char suffix,
const AddrModeArg arg)
@@ -420,11 +420,11 @@ static void disasm_ext(
assert(arg.mode == AddrMode::kDn);
snprintf(node.mnemonic, kMnemonicBufferSize, "ext%c", suffix);
arg.SNPrint(node.arguments, kArgsBufferSize);
- node.size = kInstructionSizeStepBytes + arg.Size();
+ return node.size = kInstructionSizeStepBytes + arg.Size();
}
-static void disasm_ext_movem(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_ext_movem(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto dir = static_cast<MoveDirection>((instr >> 10) & 1);
const unsigned m = (instr >> 3) & 7;
@@ -436,12 +436,12 @@ static void disasm_ext_movem(
}
if (node.offset + kInstructionSizeStepBytes >= code.occupied_size) {
// Not enough space for regmask, but maybe it is just EXT?
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const unsigned regmask = GetU16BE(code.buffer + node.offset + kInstructionSizeStepBytes);
if (regmask == 0) {
// This is just not representable: at least one register must be specified
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const auto a = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes * 2, code, m, xn, suffix);
@@ -449,17 +449,17 @@ static void disasm_ext_movem(
case AddrMode::kInvalid:
case AddrMode::kDn: // 4880..4887 / 4c80..4c87 / 48c0..48c7 / 4cc0..4cc7
case AddrMode::kAn: // 4888..488f / 4c88..4c8f / 48c8..48cf / 4cc8..4ccf
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr: // 4890..4897 / 4c90..4c97 / 48d0..48d7 / 4cd0..4cd7
break;
case AddrMode::kAnAddrIncr: // 4898..489f / 4c89..4c9f / 48d8..48df / 4cd8..4cdf
if (dir == MoveDirection::kRegisterToMemory) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kAnAddrDecr: // 48a0..48a7 / 4ca0..4ca7 / 48e0..48e7 / 4ce0..4ce7
if (dir == MoveDirection::kMemoryToRegister) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kD16AnAddr: // 48a8..48af / 4c8a..4caf / 48e8..48ef / 4ce8..4cef
@@ -470,13 +470,12 @@ static void disasm_ext_movem(
case AddrMode::kD16PCAddr: // 48ba / 4cba / 48fa / 4cfa
case AddrMode::kD8PCXiAddr: // 48bb / 4cbb / 48fb / 4cfb
if (dir == MoveDirection::kRegisterToMemory) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate: // 4ebc / 4efc
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
- node.size = kInstructionSizeStepBytes * 2 + a.Size();
snprintf(node.mnemonic, kMnemonicBufferSize, "movem%c", suffix);
char regmask_str[48]{};
char addrmodearg_str[32]{};
@@ -487,10 +486,11 @@ static void disasm_ext_movem(
} else {
snprintf(node.arguments, kArgsBufferSize, "%s,%s", regmask_str, addrmodearg_str);
}
+ return node.size = kInstructionSizeStepBytes * 2 + a.Size();
}
-static void disasm_lea(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_lea(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto addr = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, instr, 'l');
@@ -498,12 +498,12 @@ static void disasm_lea(
case AddrMode::kInvalid:
case AddrMode::kDn:
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
break;
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kD16AnAddr:
case AddrMode::kD8AnXiAddr:
case AddrMode::kWord:
@@ -512,7 +512,7 @@ static void disasm_lea(
case AddrMode::kD8PCXiAddr:
break;
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const unsigned an = ((instr >> 9) & 7);
const auto reg = AddrModeArg::An(an);
@@ -522,21 +522,21 @@ static void disasm_lea(
reg.SNPrint(reg_str, sizeof(reg_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "leal");
snprintf(node.arguments, kArgsBufferSize, "%s,%s", addr_str, reg_str);
- node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
+ return node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
-static void disasm_chk(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_chk(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto src = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, instr, 'w');
switch (src.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -548,7 +548,7 @@ static void disasm_chk(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const unsigned dn = ((instr >> 9) & 7);
const auto dst = AddrModeArg::Dn(dn);
@@ -558,7 +558,7 @@ static void disasm_chk(
dst.SNPrint(dst_str, sizeof(dst_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "chkw");
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
static inline const char *bcc_mnemonic_by_condition(Cond condition)
@@ -585,25 +585,25 @@ static inline const char *bcc_mnemonic_by_condition(Cond condition)
return "?";
}
-static void disasm_bra_bsr_bcc(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_bra_bsr_bcc(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
Cond condition = static_cast<Cond>((instr >> 8) & 0xf);
const char *mnemonic = bcc_mnemonic_by_condition(condition);
// False condition Indicates BSR
int dispmt = static_cast<int8_t>(instr & 0xff);
if (dispmt % kInstructionSizeStepBytes) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const char suffix = dispmt ? 's' : 'w';
if (dispmt == 0) {
// Check the boundaries
if (node.offset + kInstructionSizeStepBytes >= code.occupied_size) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
dispmt = GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes);
if (dispmt % kInstructionSizeStepBytes) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
node.size = kInstructionSizeStepBytes * 2;
} else {
@@ -618,7 +618,7 @@ static void disasm_bra_bsr_bcc(
const char * const sign = dispmt >= 0 ? "+" : "";
// FIXME support s.rel_marks option for this instruction
snprintf(node.arguments, kArgsBufferSize, ".%s%d", sign, dispmt);
- return;
+ return node.size;
}
static inline const char *mnemonic_for_bitops(unsigned opcode)
@@ -633,8 +633,8 @@ static inline const char *mnemonic_for_bitops(unsigned opcode)
return "?";
}
-static inline void disasm_movep(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+static inline size_t disasm_movep(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code)
{
const unsigned dn = ((instr >> 9) & 7);
const unsigned an = instr & 7;
@@ -644,7 +644,7 @@ static inline void disasm_movep(
node.offset + kInstructionSizeStepBytes, code, 5, an, suffix);
if (addr.mode == AddrMode::kInvalid) {
// Boundary check failed, most likely
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
assert(addr.mode == AddrMode::kD16AnAddr);
const auto reg = AddrModeArg::Dn(dn);
@@ -658,19 +658,18 @@ static inline void disasm_movep(
} else {
snprintf(node.arguments, kArgsBufferSize, "%s,%s", addr_str, reg_str);
}
- node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
+ return node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
-static void disasm_src_arg_bitops_movep(
+static size_t disasm_src_arg_bitops_movep(
DisasmNode &node,
const uint16_t instr,
const DataBuffer &code,
- const Settings &s,
const bool has_dn_src = true)
{
const unsigned m = (instr >> 3) & 7;
if ((m == 1) && has_dn_src) {
- return disasm_movep(node, instr, code, s);
+ return disasm_movep(node, instr, code);
}
const unsigned dn = ((instr >> 9) & 7);
const unsigned xn = instr & 7;
@@ -683,7 +682,7 @@ static void disasm_src_arg_bitops_movep(
dn,
'b');
if (src.mode == AddrMode::kInvalid) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (has_dn_src) {
assert(src.mode == AddrMode::kDn);
@@ -696,11 +695,11 @@ static void disasm_src_arg_bitops_movep(
const unsigned opcode = (instr >> 6) & 3;
switch (dst.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -713,11 +712,11 @@ static void disasm_src_arg_bitops_movep(
case AddrMode::kD8PCXiAddr:
if (opcode != 0) {
// PC relative destination address argument available for BTST only
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
char src_str[32]{};
char dst_str[32]{};
@@ -727,21 +726,21 @@ static void disasm_src_arg_bitops_movep(
const char *mnemonic = mnemonic_for_bitops(opcode);
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_bitops(DisasmNode &n, const uint16_t i, const DataBuffer &c, const Settings &s)
+static size_t disasm_bitops(DisasmNode &n, const uint16_t i, const DataBuffer &c)
{
- return disasm_src_arg_bitops_movep(n, i, c, s, false);
+ return disasm_src_arg_bitops_movep(n, i, c, false);
}
-static inline void disasm_logical_immediate_to(
+static inline size_t disasm_logical_immediate_to(
DisasmNode &node, const char* mnemonic, const char suffix, const int16_t imm)
{
const char *reg = suffix == 'b' ? "ccr" : "sr";
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
snprintf(node.arguments, kArgsBufferSize, "#%d,%%%s", imm, reg);
- node.size = kInstructionSizeStepBytes * 2;
+ return node.size = kInstructionSizeStepBytes * 2;
}
static inline const char *mnemonic_logical_immediate(const unsigned opcode)
@@ -760,45 +759,45 @@ static inline const char *mnemonic_logical_immediate(const unsigned opcode)
return "?";
}
-static void disasm_bitops_movep(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_bitops_movep(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const bool has_source_reg = (instr >> 8) & 1;
if (has_source_reg) {
- return disasm_src_arg_bitops_movep(node, instr, code, s);
+ return disasm_src_arg_bitops_movep(node, instr, code);
}
const unsigned opcode = (instr >> 9) & 7;
if (opcode == 7) {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (opcode == 4) {
- return disasm_bitops(node, instr, code, s);
+ return disasm_bitops(node, instr, code);
}
const int m = (instr >> 3) & 7;
const int xn = instr & 7;
const auto opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
// Anticipating #imm which means "to CCR"/"to SR", depending on OpSize
if (m == 7 && xn == 4) {
if (opcode == 2 || opcode == 3 || opcode == 6) {
// CMPI, SUBI and ANDI neither have immediate destination arguments
// nor "to CCR"/"to SR" variations
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (opsize == OpSize::kLong) {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
}
const char suffix = suffix_from_opsize(opsize);
const auto src = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, 7, 4, suffix);
if (src.mode == AddrMode::kInvalid) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
assert(src.mode == AddrMode::kImmediate);
const char *mnemonic = mnemonic_logical_immediate(opcode);
@@ -809,11 +808,11 @@ static void disasm_bitops_movep(
node.offset + kInstructionSizeStepBytes + src.Size(), code, m, xn, suffix);
switch (dst.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -826,32 +825,32 @@ static void disasm_bitops_movep(
case AddrMode::kD8PCXiAddr:
if (opcode != 6) {
// PC relative destination address argument available for CMPI only
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
char dst_str[32]{};
dst.SNPrint(dst_str, sizeof(dst_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
snprintf(node.arguments, kArgsBufferSize, "#%d,%s", src.value, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_move_movea(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_move_movea(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const int size_spec = (instr >> 12) & 3;
const char suffix = size_spec == 1 ? 'b' : (size_spec == 3 ? 'w' : 'l');
const auto src = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
if (src.mode == AddrMode::kInvalid) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (suffix == 'b' && src.mode == AddrMode::kAn) {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const int m = (instr >> 6) & 7;
const int xn = (instr >> 9) & 7;
@@ -859,13 +858,13 @@ static void disasm_move_movea(
node.offset + kInstructionSizeStepBytes + src.Size(), code, m, xn, suffix);
switch (dst.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
if (suffix == 'b') {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
@@ -878,7 +877,7 @@ static void disasm_move_movea(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
char src_str[32]{};
char dst_str[32]{};
@@ -887,22 +886,22 @@ static void disasm_move_movea(
const char *mnemonic = dst.mode == AddrMode::kAn ? "movea" : "move";
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_move_from_sr(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_move_from_sr(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const char suffix = 'w';
const auto dst = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (dst.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -914,28 +913,28 @@ static void disasm_move_from_sr(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
char dst_str[32]{};
dst.SNPrint(dst_str, sizeof(dst_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "move%c", suffix);
snprintf(node.arguments, kArgsBufferSize, "%%sr,%s", dst_str);
- node.size = kInstructionSizeStepBytes + dst.Size();
+ return node.size = kInstructionSizeStepBytes + dst.Size();
}
-static void disasm_move_to(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s, const char* reg)
+static size_t disasm_move_to(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code, const char* reg)
{
const char suffix = 'w';
const auto src = AddrModeArg::Fetch(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (src.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -952,7 +951,7 @@ static void disasm_move_to(
src.SNPrint(src_str, sizeof(src_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "move%c", suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%%%s", src_str, reg);
- node.size = kInstructionSizeStepBytes + src.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size();
}
static inline const char *mnemonic_for_negx_clr_neg_not(const unsigned opcode)
@@ -967,24 +966,24 @@ static inline const char *mnemonic_for_negx_clr_neg_not(const unsigned opcode)
return "?";
}
-static void disasm_move_negx_clr_neg_not(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_move_negx_clr_neg_not(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto opsize = static_cast<OpSize>((instr >> 6) & 3);
const unsigned opcode = (instr >> 9) & 3;
if (opsize == OpSize::kInvalid) {
switch (opcode) {
case 0:
- return disasm_move_from_sr(node, instr, code, s);
+ return disasm_move_from_sr(node, instr, code);
case 1:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case 2:
- return disasm_move_to(node, instr, code, s, "ccr");
+ return disasm_move_to(node, instr, code, "ccr");
case 3:
- return disasm_move_to(node, instr, code, s, "sr");
+ return disasm_move_to(node, instr, code, "sr");
}
assert(false);
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const char *mnemonic = mnemonic_for_negx_clr_neg_not(opcode);
const char suffix = suffix_from_opsize(opsize);
@@ -992,11 +991,11 @@ static void disasm_move_negx_clr_neg_not(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (a.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1008,31 +1007,31 @@ static void disasm_move_negx_clr_neg_not(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
a.SNPrint(node.arguments, kArgsBufferSize);
- node.size = kInstructionSizeStepBytes + a.Size();
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
-static inline void disasm_trivial(
- DisasmNode &node, uint16_t, const DataBuffer &, const Settings &, const char* mnemonic)
+static inline size_t disasm_trivial(
+ DisasmNode &node, uint16_t, const DataBuffer &, const char* mnemonic)
{
- node.size = kInstructionSizeStepBytes;
snprintf(node.mnemonic, kMnemonicBufferSize, mnemonic);
+ return node.size = kInstructionSizeStepBytes;
}
-static inline void disasm_tas(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static inline size_t disasm_tas(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, instr, 'w');
switch (a.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1044,34 +1043,34 @@ static inline void disasm_tas(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
snprintf(node.mnemonic, kMnemonicBufferSize, "tas");
a.SNPrint(node.arguments, kArgsBufferSize);
- node.size = kInstructionSizeStepBytes + a.Size();
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
-static void disasm_tst_tas_illegal(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_tst_tas_illegal(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const auto opsize = static_cast<OpSize>((instr >> 6) & 3);
const int m = (instr >> 3) & 7;
const int xn = instr & 7;
if (opsize == OpSize::kInvalid) {
if (m == 7 && xn == 4){
- return disasm_trivial(node, instr, code, s, "illegal");
+ return disasm_trivial(node, instr, code, "illegal");
}
- return disasm_tas(node, instr, code, s);
+ return disasm_tas(node, instr, code);
}
const char suffix = suffix_from_opsize(opsize);
const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, m, xn, suffix);
switch (a.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1083,32 +1082,31 @@ static void disasm_tst_tas_illegal(
case AddrMode::kD8PCXiAddr:
break;
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
snprintf(node.mnemonic, kMnemonicBufferSize, "tst%c", suffix);
a.SNPrint(node.arguments, kArgsBufferSize);
- node.size = kInstructionSizeStepBytes + a.Size();
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
-static void disasm_trap(
- DisasmNode &node, uint16_t instr, const DataBuffer &, const Settings &)
+static size_t disasm_trap(
+ DisasmNode &node, uint16_t instr, const DataBuffer &)
{
const unsigned vector = instr & 0xf;
snprintf(node.mnemonic, kMnemonicBufferSize, "trap");
snprintf(node.arguments, kArgsBufferSize, "#%u", vector);
- node.size = kInstructionSizeStepBytes;
+ return node.size = kInstructionSizeStepBytes;
}
-static void disasm_link_unlink(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_link_unlink(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const bool unlk = (instr >> 3) & 1;
const unsigned xn = instr & 7;
if (unlk) {
snprintf(node.mnemonic, kMnemonicBufferSize, "unlk");
snprintf(node.arguments, kArgsBufferSize, "%%a%u", xn);
- node.size = kInstructionSizeStepBytes;
- return;
+ return node.size = kInstructionSizeStepBytes;
}
// Fetch immediate word
const auto src = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, 7, 4, 'w');
@@ -1125,7 +1123,7 @@ static void disasm_link_unlink(
case AddrMode::kLong:
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kImmediate:
break;
}
@@ -1133,25 +1131,25 @@ static void disasm_link_unlink(
src.SNPrint(src_str, sizeof(src_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "linkw");
snprintf(node.arguments, kArgsBufferSize, "%%a%u,%s", xn, src_str);
- node.size = kInstructionSizeStepBytes + src.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size();
}
-static void disasm_move_usp(
- DisasmNode &node, uint16_t instr, const DataBuffer &, const Settings &)
+static size_t disasm_move_usp(
+ DisasmNode &node, uint16_t instr, const DataBuffer &)
{
const unsigned xn = instr & 7;
const auto dir = static_cast<MoveDirection>((instr >> 3) & 1);
- node.size = kInstructionSizeStepBytes;
snprintf(node.mnemonic, kMnemonicBufferSize, "movel");
if (dir == MoveDirection::kRegisterToMemory) {
snprintf(node.arguments, kArgsBufferSize, "%%a%u,%%usp", xn);
} else {
snprintf(node.arguments, kArgsBufferSize, "%%usp,%%a%u", xn);
}
+ return node.size = kInstructionSizeStepBytes;
}
-static void disasm_nbcd_swap_pea(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_nbcd_swap_pea(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const bool is_nbcd = !((instr >> 6) & 1);
const auto arg = AddrModeArg::Fetch(
@@ -1159,20 +1157,20 @@ static void disasm_nbcd_swap_pea(
bool is_swap{};
switch (arg.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
if (!is_nbcd) {
is_swap = true;
}
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
break;
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
if (!is_nbcd) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kD16AnAddr:
@@ -1183,83 +1181,82 @@ static void disasm_nbcd_swap_pea(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
if (is_nbcd) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const char *mnemonic = is_nbcd ? "nbcdb" : is_swap ? "swapw" : "peal";
snprintf(node.mnemonic, kMnemonicBufferSize, "%s", mnemonic);
arg.SNPrint(node.arguments, kArgsBufferSize);
- node.size = kInstructionSizeStepBytes + arg.Size();
+ return node.size = kInstructionSizeStepBytes + arg.Size();
}
-static void disasm_chunk_4(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_chunk_4(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
if ((instr & 0xf900) == 0x4000) {
- return disasm_move_negx_clr_neg_not(node, instr, code, s);
+ return disasm_move_negx_clr_neg_not(node, instr, code);
} else if ((instr & 0xff80) == 0x4800) {
// NOTE EXT is handled with MOVEM
- return disasm_nbcd_swap_pea(node, instr, code, s);
+ return disasm_nbcd_swap_pea(node, instr, code);
} else if ((instr & 0xff00) == 0x4a00) {
- return disasm_tst_tas_illegal(node, instr, code, s);
+ return disasm_tst_tas_illegal(node, instr, code);
} else if ((instr & 0xfff0) == 0x4e40) {
- return disasm_trap(node, instr, code, s);
+ return disasm_trap(node, instr, code);
} else if ((instr & 0xfff0) == 0x4e50) {
- return disasm_link_unlink(node, instr, code, s);
+ return disasm_link_unlink(node, instr, code);
} else if ((instr & 0xfff0) == 0x4e60) {
- return disasm_move_usp(node, instr, code, s);
+ return disasm_move_usp(node, instr, code);
} else if (instr == 0x4e70) {
- return disasm_trivial(node, instr, code, s, "reset");
+ return disasm_trivial(node, instr, code, "reset");
} else if (instr == 0x4e71) {
- return disasm_trivial(node, instr, code, s, "nop");
+ return disasm_trivial(node, instr, code, "nop");
} else if (instr == 0x4e72) {
if (node.offset + kInstructionSizeStepBytes < code.occupied_size) {
- node.size = kInstructionSizeStepBytes * 2;
snprintf(node.mnemonic, kMnemonicBufferSize, "stop");
const uint16_t sr_imm = GetU16BE(code.buffer + node.offset + kInstructionSizeStepBytes);
snprintf(node.arguments, kArgsBufferSize, "#0x%x:w", sr_imm);
- return;
+ return node.size = kInstructionSizeStepBytes * 2;
}
} else if (instr == 0x4e73) {
- return disasm_trivial(node, instr, code, s, "rte");
+ return disasm_trivial(node, instr, code, "rte");
} else if (instr == 0x4e75) {
- return disasm_trivial(node, instr, code, s, "rts");
+ return disasm_trivial(node, instr, code, "rts");
} else if (instr == 0x4e76) {
- return disasm_trivial(node, instr, code, s, "trapv");
+ return disasm_trivial(node, instr, code, "trapv");
} else if (instr == 0x4e77) {
- return disasm_trivial(node, instr, code, s, "rtr");
+ return disasm_trivial(node, instr, code, "rtr");
} else if ((instr & 0xffc0) == 0x4e80) {
- return disasm_jsr_jmp(node, instr, code, s, JType::kJsr);
+ return disasm_jsr_jmp(node, instr, code, JType::kJsr);
} else if ((instr & 0xffc0) == 0x4ec0) {
- return disasm_jsr_jmp(node, instr, code, s, JType::kJmp);
+ return disasm_jsr_jmp(node, instr, code, JType::kJmp);
} else if ((instr & 0xfb80) == 0x4880) {
- return disasm_ext_movem(node, instr, code, s);
+ return disasm_ext_movem(node, instr, code);
} else if ((instr & 0xf1c0) == 0x41c0) {
- return disasm_lea(node, instr, code, s);
+ return disasm_lea(node, instr, code);
} else if ((instr & 0xf1c0) == 0x4180) {
- return disasm_chk(node, instr, code, s);
+ return disasm_chk(node, instr, code);
}
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
-static void disasm_addq_subq(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s, OpSize opsize)
+static size_t disasm_addq_subq(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code, OpSize opsize)
{
const char suffix = suffix_from_opsize(opsize);
const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (a.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn: // 5x00..5x07 / 5x40..5x47 / 5x80..5x87
break;
case AddrMode::kAn: // 5x08..5x0f / 5x48..5x4f / 5x88..5x8f
if (opsize == OpSize::kByte) {
// 5x08..5x0f
// addqb and subqb with An do not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kAnAddr: // 5x10..5x17 / 5x50..5x57 / 5x90..5x97
@@ -1274,9 +1271,8 @@ static void disasm_addq_subq(
case AddrMode::kD8PCXiAddr: // 5x3b / 5x7b / 5xbb
case AddrMode::kImmediate: // 5x3c / 5x7c / 5xbc
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
- node.size = kInstructionSizeStepBytes + a.Size();
const char *mnemonic = (instr >> 8) & 1 ? "subq" : "addq";
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c", mnemonic, suffix);
const unsigned imm = ((uint8_t((instr >> 9) & 7) - 1) & 7) + 1;
@@ -1284,6 +1280,7 @@ static void disasm_addq_subq(
assert(ret > 0);
assert(static_cast<unsigned>(ret) == strlen("#8,"));
a.SNPrint(node.arguments + ret, kArgsBufferSize - ret);
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
static inline const char *dbcc_mnemonic_by_condition(Cond condition)
@@ -1310,16 +1307,15 @@ static inline const char *dbcc_mnemonic_by_condition(Cond condition)
return "?";
}
-static void disasm_dbcc(DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_dbcc(DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
if (node.offset + kInstructionSizeStepBytes >= code.occupied_size) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const int16_t dispmt_raw = GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes);
if (dispmt_raw % kInstructionSizeStepBytes) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
- node.size = kInstructionSizeStepBytes * 2;
Cond condition = static_cast<Cond>((instr >> 8) & 0xf);
const char *mnemonic = dbcc_mnemonic_by_condition(condition);
const int dn = (instr & 7);
@@ -1332,7 +1328,7 @@ static void disasm_dbcc(DisasmNode &node, uint16_t instr, const DataBuffer &code
const char * const sign = dispmt >= 0 ? "+" : "";
// FIXME support s.rel_marks option for this instruction
snprintf(node.arguments, kArgsBufferSize, "%%d%d,.%s%d", dn, sign, dispmt);
- return;
+ return node.size = kInstructionSizeStepBytes * 2;
}
static inline const char *scc_mnemonic_by_condition(Cond condition)
@@ -1359,17 +1355,17 @@ static inline const char *scc_mnemonic_by_condition(Cond condition)
return "?";
}
-static void disasm_scc_dbcc(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_scc_dbcc(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code)
{
const auto a = AddrModeArg::Fetch(node.offset + kInstructionSizeStepBytes, code, instr, 'w');
switch (a.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn: // 5xc0..5xc7, Dn
break;
case AddrMode::kAn: // 5xc8..5xcf, An
- return disasm_dbcc(node, instr, code, s);
+ return disasm_dbcc(node, instr, code);
case AddrMode::kAnAddr: // 5xd0..5xd7
case AddrMode::kAnAddrIncr: // 5xd8..5xdf
case AddrMode::kAnAddrDecr: // 5xe0..5xe7
@@ -1382,29 +1378,29 @@ static void disasm_scc_dbcc(
case AddrMode::kD8PCXiAddr: // 5xfb
case AddrMode::kImmediate: // 5xfc
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
- node.size = kInstructionSizeStepBytes + a.Size();
Cond condition = static_cast<Cond>((instr >> 8) & 0xf);
const char *mnemonic = scc_mnemonic_by_condition(condition);
snprintf(node.mnemonic, kMnemonicBufferSize, mnemonic);
a.SNPrint(node.arguments, kArgsBufferSize);
+ return node.size = kInstructionSizeStepBytes + a.Size();
}
-static void disasm_addq_subq_scc_dbcc(DisasmNode &n, uint16_t instr, const DataBuffer &c, const Settings &s)
+static size_t disasm_addq_subq_scc_dbcc(DisasmNode &n, uint16_t instr, const DataBuffer &c)
{
const auto opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_scc_dbcc(n, instr, c, s);
+ return disasm_scc_dbcc(n, instr, c);
}
- return disasm_addq_subq(n, instr, c, s, opsize);
+ return disasm_addq_subq(n, instr, c, opsize);
}
-static void disasm_moveq(DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_moveq(DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
if (instr & 0x100) {
// Does not exist
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const int xn = (instr >> 9) & 7;
const auto dst = AddrModeArg::Dn(xn);
@@ -1413,15 +1409,14 @@ static void disasm_moveq(DisasmNode &node, uint16_t instr, const DataBuffer &cod
snprintf(node.mnemonic, kMnemonicBufferSize, "moveq");
const int8_t data = instr & 0xff;
snprintf(node.arguments, kArgsBufferSize, "#%d,%s", data, dst_str);
- node.size = kInstructionSizeStepBytes + dst.Size();
+ return node.size = kInstructionSizeStepBytes + dst.Size();
}
-static void disasm_divu_divs_mulu_muls(
+static size_t disasm_divu_divs_mulu_muls(
DisasmNode &node,
uint16_t instr,
const DataBuffer &code,
- const Settings &s,
const char *mnemonic)
{
const char suffix = 'w';
@@ -1429,11 +1424,11 @@ static void disasm_divu_divs_mulu_muls(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (src.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1457,11 +1452,10 @@ static void disasm_divu_divs_mulu_muls(
const char sign_suffix = is_signed ? 's' : 'u';
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%c%c", mnemonic, sign_suffix, suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + dst.Size() + src.Size();
-
+ return node.size = kInstructionSizeStepBytes + dst.Size() + src.Size();
}
-static void disasm_addx_subx_abcd_sbcd(
+static size_t disasm_addx_subx_abcd_sbcd(
DisasmNode &node,
const uint16_t instr,
const char *mnemonic,
@@ -1490,14 +1484,13 @@ static void disasm_addx_subx_abcd_sbcd(
snprintf(node.mnemonic, kMnemonicBufferSize, "%s%s%c", mnemonic, msuffix, suffix);
}
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_or_and(
+static size_t disasm_or_and(
DisasmNode &node,
uint16_t instr,
const DataBuffer &code,
- const Settings &s,
const OpSize opsize,
const char* mnemonic)
{
@@ -1507,15 +1500,15 @@ static void disasm_or_and(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (addr.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
if (dir_to_addr) {
// Switching dir when bot operands are data registers is not allowed
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1528,13 +1521,13 @@ static void disasm_or_and(
case AddrMode::kD8PCXiAddr:
if (dir_to_addr) {
// PC relative cannot be destination
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate:
if (dir_to_addr) {
// immediate cannot be destination
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (1) {
// XXX GNU AS always emits ORI (04xx xxxx [xxxx]) or ANDI (02xx
@@ -1543,7 +1536,7 @@ static void disasm_or_and(
// -fpedantic to generate instruction in this case, but for now it
// is gonna be just plain bytes to keep original and reassembled
// binaries *identical* as it must be by default.
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
}
@@ -1559,24 +1552,24 @@ static void disasm_or_and(
} else {
snprintf(node.arguments, kArgsBufferSize, "%s,%s", addr_str, reg_str);
}
- node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
+ return node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
-static void disasm_divu_divs_sbcd_or(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_divu_divs_sbcd_or(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
if ((instr & 0x1f0) == 0x100) {
return disasm_addx_subx_abcd_sbcd(node, instr, "sbcd", "");
}
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_divu_divs_mulu_muls(node, instr, code, s, "div");
+ return disasm_divu_divs_mulu_muls(node, instr, code, "div");
}
- return disasm_or_and(node, instr, code, s, opsize, "or");
+ return disasm_or_and(node, instr, code, opsize, "or");
}
-static inline void disasm_adda_suba_cmpa(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s, const char *mnemonic)
+static inline size_t disasm_adda_suba_cmpa(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code, const char *mnemonic)
{
const OpSize opsize = static_cast<OpSize>(((instr >> 8) & 1) + 1);
const char suffix = suffix_from_opsize(opsize);
@@ -1585,7 +1578,7 @@ static inline void disasm_adda_suba_cmpa(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (src.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
case AddrMode::kAn:
case AddrMode::kAnAddr:
@@ -1608,14 +1601,13 @@ static inline void disasm_adda_suba_cmpa(
dst.SNPrint(dst_str, sizeof(dst_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "%sa%c", mnemonic, suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_add_sub_cmp(
+static size_t disasm_add_sub_cmp(
DisasmNode &node,
const uint16_t instr,
const DataBuffer &code,
- const Settings &s,
const char *mnemonic,
const OpSize opsize,
const bool dir_to_addr)
@@ -1625,13 +1617,13 @@ static void disasm_add_sub_cmp(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (addr.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
if (dir_to_addr || suffix == 'b') {
// An cannot be destination and An cannot be used as byte
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
/* Fall through */
case AddrMode::kAnAddr:
@@ -1646,13 +1638,13 @@ static void disasm_add_sub_cmp(
case AddrMode::kD8PCXiAddr:
if (dir_to_addr) {
// PC relative cannot be destination
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
case AddrMode::kImmediate:
if (dir_to_addr) {
// immediate cannot be destination
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
if (1) {
// XXX GNU AS always emits ADDI (06xx xxxx [xxxx]) instruction when
@@ -1661,7 +1653,7 @@ static void disasm_add_sub_cmp(
// option like -fpedantic to generate instruction in this case, but
// for now it is gonna be just plain bytes to keep original and
// reassembled binaries *identical* as it must be by default.
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
break;
}
@@ -1677,11 +1669,11 @@ static void disasm_add_sub_cmp(
} else {
snprintf(node.arguments, kArgsBufferSize, "%s,%s", addr_str, reg_str);
}
- node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
+ return node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
-static void disasm_cmpm(
- DisasmNode &node, const uint16_t instr, const DataBuffer &, const Settings &)
+static size_t disasm_cmpm(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &)
{
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
// Must be already handled by parent call
@@ -1700,11 +1692,11 @@ static void disasm_cmpm(
const char suffix = suffix_from_opsize(opsize);
snprintf(node.mnemonic, kMnemonicBufferSize, "cmpm%c", suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_eor(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_eor(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code)
{
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
const char suffix = suffix_from_opsize(opsize);
@@ -1712,11 +1704,11 @@ static void disasm_eor(
node.offset + kInstructionSizeStepBytes, code, instr, suffix);
switch (addr.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1729,7 +1721,7 @@ static void disasm_eor(
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
// PC relative and immediate cannot be destination
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const unsigned dn = (instr >> 9) & 7;
const auto reg = AddrModeArg::Dn(dn);
@@ -1739,28 +1731,28 @@ static void disasm_eor(
reg.SNPrint(reg_str, sizeof(reg_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "eor%c", suffix);
snprintf(node.arguments, kArgsBufferSize, "%s,%s", reg_str, addr_str);
- node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
+ return node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
-static void disasm_eor_cmpm_cmp_cmpa(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_eor_cmpm_cmp_cmpa(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code)
{
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_adda_suba_cmpa(node, instr, code, s, "cmp");
+ return disasm_adda_suba_cmpa(node, instr, code, "cmp");
}
const bool dir_to_addr = ((instr >> 8) & 1);
if (!dir_to_addr) {
- return disasm_add_sub_cmp(node, instr, code, s, "cmp", opsize, dir_to_addr);
+ return disasm_add_sub_cmp(node, instr, code, "cmp", opsize, dir_to_addr);
}
const int m = (instr >> 3) & 7;
if (m == 1) {
- return disasm_cmpm(node, instr, code, s);
+ return disasm_cmpm(node, instr, code);
}
- return disasm_eor(node, instr, code, s);
+ return disasm_eor(node, instr, code);
}
-static inline void disasm_exg(DisasmNode &node, uint16_t instr)
+static inline size_t disasm_exg(DisasmNode &node, uint16_t instr)
{
assert((instr & 0x130) == 0x100);
const int m1 = (instr >> 3) & 1;
@@ -1779,11 +1771,11 @@ static inline void disasm_exg(DisasmNode &node, uint16_t instr)
dst.SNPrint(dst_str, sizeof(dst_str));
snprintf(node.mnemonic, kMnemonicBufferSize, "exg");
snprintf(node.arguments, kArgsBufferSize, "%s,%s", src_str, dst_str);
- node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
+ return node.size = kInstructionSizeStepBytes + src.Size() + dst.Size();
}
-static void disasm_chunk_c(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_chunk_c(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
if ((instr & 0x1f0) == 0x100) {
// XXX GNU AS does not know ABCD.B, it only knows ABCD, but happily
@@ -1794,28 +1786,28 @@ static void disasm_chunk_c(
}
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_divu_divs_mulu_muls(node, instr, code, s, "mul");
+ return disasm_divu_divs_mulu_muls(node, instr, code, "mul");
}
const unsigned m_split = instr & 0x1f8;
if (m_split == 0x188 || m_split == 0x148 || m_split == 0x140) {
return disasm_exg(node, instr);
}
- return disasm_or_and(node, instr, code, s, opsize, "and");
+ return disasm_or_and(node, instr, code, opsize, "and");
}
-static void disasm_add_sub_x_a(
- DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s, const char *mnemonic)
+static size_t disasm_add_sub_x_a(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code, const char *mnemonic)
{
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_adda_suba_cmpa(node, instr, code, s, mnemonic);
+ return disasm_adda_suba_cmpa(node, instr, code, mnemonic);
}
const bool dir_to_addr = (instr >> 8) & 1;
const unsigned m = (instr >> 3) & 7;
if (dir_to_addr && (m == 0 || m == 1)) {
return disasm_addx_subx_abcd_sbcd(node, instr, mnemonic, "x");
}
- return disasm_add_sub_cmp(node, instr, code, s, mnemonic, opsize, dir_to_addr);
+ return disasm_add_sub_cmp(node, instr, code, mnemonic, opsize, dir_to_addr);
}
static inline const char *ShiftKindToMnemonic(const ShiftKind k)
@@ -1835,8 +1827,8 @@ static inline bool IsValidShiftKind(const ShiftKind k)
return static_cast<int>(k) < 4;
}
-static void disasm_shift_rotate(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static size_t disasm_shift_rotate(
+ DisasmNode &node, uint16_t instr, const DataBuffer &code)
{
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
const unsigned xn = instr & 7;
@@ -1845,7 +1837,7 @@ static void disasm_shift_rotate(
? static_cast<ShiftKind>(rotation)
: static_cast<ShiftKind>((instr >> 3) & 3);
if (!IsValidShiftKind(kind)) {
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
const unsigned m = (instr >> 5) & 1;
const char suffix = suffix_from_opsize(opsize);
@@ -1855,14 +1847,14 @@ static void disasm_shift_rotate(
if (opsize == OpSize::kInvalid) {
switch (dst.mode) {
case AddrMode::kInvalid:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kDn:
// Intersects with situation when args are "#1,%dx". GNU AS would
// not understand shift instruction with single argument of "%dx".
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
break;
case AddrMode::kAn:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1874,7 +1866,7 @@ static void disasm_shift_rotate(
case AddrMode::kD16PCAddr:
case AddrMode::kD8PCXiAddr:
case AddrMode::kImmediate:
- return disasm_verbatim(node, instr, code, s);
+ return disasm_verbatim(node, instr, code);
}
}
const unsigned imm = ((rotation - 1) & 7) + 1;
@@ -1892,60 +1884,60 @@ static void disasm_shift_rotate(
} else {
snprintf(node.arguments, kArgsBufferSize, "#%u,%s", imm, dst_str);
}
- node.size = kInstructionSizeStepBytes + dst.Size();
+ return node.size = kInstructionSizeStepBytes + dst.Size();
}
-static void m68k_disasm(DisasmNode &n, uint16_t i, const DataBuffer &c, const Settings &s)
+static size_t m68k_disasm(DisasmNode &n, uint16_t i, const DataBuffer &c)
{
switch ((i & 0xf000) >> 12) {
case 0x0:
- return disasm_bitops_movep(n, i, c, s);
+ return disasm_bitops_movep(n, i, c);
case 0x1:
case 0x2:
case 0x3:
- return disasm_move_movea(n, i, c, s);
+ return disasm_move_movea(n, i, c);
case 0x4:
- return disasm_chunk_4(n, i, c, s);
+ return disasm_chunk_4(n, i, c);
case 0x5:
- return disasm_addq_subq_scc_dbcc(n, i, c, s);
+ return disasm_addq_subq_scc_dbcc(n, i, c);
case 0x6:
- return disasm_bra_bsr_bcc(n, i, c, s);
+ return disasm_bra_bsr_bcc(n, i, c);
case 0x7:
- return disasm_moveq(n, i, c, s);
+ return disasm_moveq(n, i, c);
case 0x8:
- return disasm_divu_divs_sbcd_or(n, i, c, s);
+ return disasm_divu_divs_sbcd_or(n, i, c);
case 0x9:
- return disasm_add_sub_x_a(n, i, c, s, "sub");
+ return disasm_add_sub_x_a(n, i, c, "sub");
case 0xa:
// Does not exist
- return disasm_verbatim(n, i, c, s);
+ return disasm_verbatim(n, i, c);
case 0xb:
- return disasm_eor_cmpm_cmp_cmpa(n, i, c, s);
+ return disasm_eor_cmpm_cmp_cmpa(n, i, c);
case 0xc:
- return disasm_chunk_c(n, i, c, s);
+ return disasm_chunk_c(n, i, c);
case 0xd:
- return disasm_add_sub_x_a(n, i, c, s, "add");
+ return disasm_add_sub_x_a(n, i, c, "add");
case 0xe:
- return disasm_shift_rotate(n, i, c, s);
+ return disasm_shift_rotate(n, i, c);
case 0xf:
// Does not exist
- return disasm_verbatim(n, i, c, s);
+ return disasm_verbatim(n, i, c);
}
assert(false);
- return disasm_verbatim(n, i, c, s);
+ return disasm_verbatim(n, i, c);
}
-void DisasmNode::Disasm(const DataBuffer &code, const Settings &s)
+size_t DisasmNode::Disasm(const DataBuffer &code)
{
- // We assume that no MMU and ROM is always starts with 0
+ // We assume that machine have no MMU and ROM data always starts with 0
assert(this->offset < code.occupied_size);
// It is possible to have multiple DisasmNode::Disasm() calls, and there is
// no point to disassemble it again if it already has mnemonic determined
if (this->mnemonic[0] != '\0') {
- return;
+ return this->size;
}
const uint16_t instr = GetU16BE(code.buffer + this->offset);
- m68k_disasm(*this, instr, code, s);
+ return m68k_disasm(*this, instr, code);
}
diff --git a/disasm.h b/disasm.h
index e6ca13c..5a40462 100644
--- a/disasm.h
+++ b/disasm.h
@@ -5,6 +5,7 @@
#include <cstddef>
#include <cstdint>
+#include <cstdio>
enum class OpCode: uint8_t {
kNone = 0,
@@ -217,7 +218,13 @@ struct DisasmNode {
SizeSpec size_spec{SizeSpec::kNone};
Condition condition{Condition::kT}; ///< For Scc, Bcc and Dbcc
Arg args[2]{}; ///< Should replace `arguments` field
- void Disasm(const DataBuffer &code, const Settings&);
+
+ /*! Disassembles instruction with arguments
+ * returns size of whole instruction with arguments in bytes
+ */
+ size_t Disasm(const DataBuffer &code);
+ int FPrintf(FILE*, const Settings&);
+ int SNPrintf(char *buf, size_t bufsz, const Settings&);
void AddReferencedBy(uint32_t offset, ReferenceType);
~DisasmNode();
private:
diff --git a/main.cpp b/main.cpp
index 54c12d5..b3e3e4d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -67,7 +67,7 @@ DisasmNode *DisasmMap::insertTracedNode(uint32_t offset, TracedNodeType type)
return node;
}
-void DisasmMap::DisasmTraced(const DataBuffer &code, const Settings & s)
+void DisasmMap::DisasmTraced(const DataBuffer &code, const Settings &)
{
assert(_type == DisasmMapType::kTraced);
for (size_t i = 0; i < kDisasmMapSizeElements; i++) {
@@ -75,23 +75,23 @@ void DisasmMap::DisasmTraced(const DataBuffer &code, const Settings & s)
if (!node) {
continue;
}
- node->Disasm(code, s);
+ node->Disasm(code);
if (node->has_branch_addr && node->branch_addr < code.occupied_size) {
auto *ref_node = insertTracedNode(
node->branch_addr, TracedNodeType::kInstruction);
- ref_node->Disasm(code, s);
+ ref_node->Disasm(code);
ref_node->AddReferencedBy(
node->offset, node->is_call ? ReferenceType::kCall : ReferenceType::kBranch);
}
}
}
-void DisasmMap::DisasmAll(const DataBuffer &code, const Settings & s)
+void DisasmMap::DisasmAll(const DataBuffer &code, const Settings &)
{
assert(_type == DisasmMapType::kRaw);
for (size_t i = 0; i < Min(kDisasmMapSizeElements, code.occupied_size);) {
auto node = insertTracedNode(i, TracedNodeType::kInstruction);
- node->Disasm(code, s);
+ node->Disasm(code);
i += node->size;
}
}