From c5b2c3eed16b586b0e488ede2a69bf85fd91397e Mon Sep 17 00:00:00 2001 From: Oxore Date: Mon, 8 May 2023 21:52:41 +0300 Subject: Impl MULU, MULS, DIVU and DIVS --- disasm.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++------------- test.bash | 28 ++++++++++++++++++++++++++++ 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((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((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" -- cgit v1.2.3