summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disasm.cpp57
-rw-r--r--test.bash28
2 files changed, 72 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) {
diff --git a/test.bash b/test.bash
index 50ee0e3..ed99a31 100644
--- a/test.bash
+++ b/test.bash
@@ -93,6 +93,34 @@ run_test_iterative() {
done
}
+# cxxx divu divs
+#
+run_test_simple "divuw Dn, Dn" "\x82\xc6"
+run_test_simple "divsw (An), Dn" "\x83\xd6"
+run_test_simple "divuw (An)+, Dn" "\x82\xde"
+run_test_simple "divsw -(An), Dn" "\x83\xe6"
+run_test_simple "divuw (d16,An), Dn" "\x82\xee\xa0\x00"
+run_test_simple "divsw (d8,An,Dn:l), Dn" "\x83\xf6\x68\xf0"
+run_test_simple "divuw (xxx).W, Dn" "\x82\xf8\x30\x00"
+run_test_simple "divsw (xxx).L, Dn" "\x83\xf9\x80\x00\x00\x00"
+run_test_simple "divuw (d16,PC), Dn" "\x82\xfa\xff\xff"
+run_test_simple "divsw (d8,PC,An:w), Dn" "\x83\xfb\x90\xff"
+run_test_simple "divuw #imm, Dn" "\x82\xfc\x30\x00"
+
+# cxxx mulu muls
+#
+run_test_simple "muluw Dn, Dn" "\xc2\xc6"
+run_test_simple "mulsw (An), Dn" "\xc3\xd6"
+run_test_simple "muluw (An)+, Dn" "\xc2\xde"
+run_test_simple "mulsw -(An), Dn" "\xc3\xe6"
+run_test_simple "muluw (d16,An), Dn" "\xc2\xee\xa0\x00"
+run_test_simple "mulsw (d8,An,Dn:l), Dn" "\xc3\xf6\x68\xf0"
+run_test_simple "muluw (xxx).W, Dn" "\xc2\xf8\x30\x00"
+run_test_simple "mulsw (xxx).L, Dn" "\xc3\xf9\x80\x00\x00\x00"
+run_test_simple "muluw (d16,PC), Dn" "\xc2\xfa\xff\xff"
+run_test_simple "mulsw (d8,PC,An:w), Dn" "\xc3\xfb\x90\xff"
+run_test_simple "muluw #imm, Dn" "\xc2\xfc\x30\x00"
+
# cxxx exg
#
run_test_simple "exg Dn, Dn" "\xcd\x41"