summaryrefslogtreecommitdiff
path: root/disasm.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-08 21:52:41 +0300
committerOxore <oxore@protonmail.com>2023-05-08 21:52:41 +0300
commitc5b2c3eed16b586b0e488ede2a69bf85fd91397e (patch)
tree096df4d0f76b96c0b195f7317ad05ad783ce557e /disasm.cpp
parent3c0b372d623a52a2e0623f48c4adfb74fb727748 (diff)
Impl MULU, MULS, DIVU and DIVS
Diffstat (limited to 'disasm.cpp')
-rw-r--r--disasm.cpp57
1 files changed, 44 insertions, 13 deletions
diff --git a/disasm.cpp b/disasm.cpp
index 401c869..46a9847 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -1417,11 +1417,49 @@ static void disasm_moveq(DisasmNode &node, uint16_t instr, const DataBuffer &cod
}
-static void disasm_divu_divs(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
+static void disasm_divu_divs_mulu_muls(
+ DisasmNode &node,
+ uint16_t instr,
+ const DataBuffer &code,
+ const Settings &s,
+ const char *mnemonic)
{
- // TODO Implement
- return disasm_verbatim(node, instr, code, s);
+ 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);
+ case AddrMode::kDn:
+ break;
+ case AddrMode::kAn:
+ return disasm_verbatim(node, instr, code, s);
+ /* Fall through */
+ case AddrMode::kAnAddr:
+ case AddrMode::kAnAddrIncr:
+ case AddrMode::kAnAddrDecr:
+ case AddrMode::kD16AnAddr:
+ case AddrMode::kD8AnXiAddr:
+ case AddrMode::kWord:
+ case AddrMode::kLong:
+ break;
+ case AddrMode::kD16PCAddr:
+ case AddrMode::kD8PCXiAddr:
+ case AddrMode::kImmediate:
+ break;
+ }
+ const unsigned dn = (instr >> 9) & 7;
+ const auto dst = AddrModeArg::Dn(dn);
+ char dst_str[32]{};
+ char src_str[32]{};
+ dst.SNPrint(dst_str, sizeof(dst_str));
+ src.SNPrint(src_str, sizeof(src_str));
+ const bool is_signed = (instr >> 8) & 1;
+ 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();
+
}
static void disasm_addx_subx_abcd_sbcd(
@@ -1534,7 +1572,7 @@ static void disasm_divu_divs_sbcd_or(
}
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_divu_divs(node, instr, code, s);
+ return disasm_divu_divs_mulu_muls(node, instr, code, s, "div");
}
return disasm_or_and(node, instr, code, s, opsize, "or");
}
@@ -1545,13 +1583,6 @@ static void disasm_chunk_b(DisasmNode &n, uint16_t i, const DataBuffer &c, const
return disasm_verbatim(n, i, c, s);
}
-static void disasm_mulu_muls(
- DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
-{
- // TODO Implement
- return disasm_verbatim(node, instr, code, s);
-}
-
static inline void disasm_exg(DisasmNode &node, uint16_t instr)
{
assert((instr & 0x130) == 0x100);
@@ -1586,7 +1617,7 @@ static void disasm_chunk_c(
}
const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
if (opsize == OpSize::kInvalid) {
- return disasm_mulu_muls(node, instr, code, s);
+ return disasm_divu_divs_mulu_muls(node, instr, code, s, "mul");
}
const unsigned m_split = instr & 0x1f8;
if (m_split == 0x188 || m_split == 0x148 || m_split == 0x140) {