From 2f373f72582610f40b7219a7b7d64b7c7534f160 Mon Sep 17 00:00:00 2001 From: Oxore Date: Mon, 8 May 2023 20:26:20 +0300 Subject: Impl ABCD --- disasm.cpp | 33 ++++++++++++++++++++++++++------- test.bash | 7 ++++++- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/disasm.cpp b/disasm.cpp index f75b43f..adbd926 100644 --- a/disasm.cpp +++ b/disasm.cpp @@ -1424,8 +1424,12 @@ static void disasm_divu_divs( return disasm_verbatim(node, instr, code, s); } -static void disasm_addx_subx_sbcd( - DisasmNode &node, const uint16_t instr, const char *mnemonic, const char *msuffix) +static void disasm_addx_subx_abcd_sbcd( + DisasmNode &node, + const uint16_t instr, + const char *mnemonic, + const char *msuffix, + const bool skip_suffix = false) { const OpSize opsize = static_cast((instr >> 6) & 3); // Must be already handled by parent call @@ -1440,7 +1444,14 @@ static void disasm_addx_subx_sbcd( src.SNPrint(src_str, sizeof(src_str)); dst.SNPrint(dst_str, sizeof(dst_str)); const char suffix = suffix_from_opsize(opsize); - snprintf(node.mnemonic, kMnemonicBufferSize, "%s%s%c", mnemonic, msuffix, suffix); + if (skip_suffix) { + // XXX GNU AS does not know ABCD.B, it only knows ABCD, but happily + // consumes SBCD.B and others. That's why `skip_suffix` flag is needed, + // specifically for ABCD mnemonic. It is probably a bug in GNU AS. + snprintf(node.mnemonic, kMnemonicBufferSize, "%s%s", mnemonic, msuffix); + } else { + 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(); } @@ -1449,7 +1460,7 @@ static void disasm_divu_divs_sbcd_or( DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s) { if ((instr & 0x1f0) == 0x100) { - return disasm_addx_subx_sbcd(node, instr, "sbcd", ""); + return disasm_addx_subx_abcd_sbcd(node, instr, "sbcd", ""); } const OpSize opsize = static_cast((instr >> 6) & 3); if (opsize == OpSize::kInvalid) { @@ -1522,10 +1533,18 @@ static void disasm_chunk_b(DisasmNode &n, uint16_t i, const DataBuffer &c, const return disasm_verbatim(n, i, c, s); } -static void disasm_chunk_c(DisasmNode &n, uint16_t i, const DataBuffer &c, const Settings &s) +static void disasm_chunk_c( + DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s) { + if ((instr & 0x1f0) == 0x100) { + // XXX GNU AS does not know ABCD.B, it only knows ABCD, but happily + // consumes SBCD.B and others. That's why `skip_suffix` flag is needed, + // specifically for ABCD mnemonic. It is probably a bug in GNU AS. + const bool skip_size_suffix = true; + return disasm_addx_subx_abcd_sbcd(node, instr, "abcd", "", skip_size_suffix); + } // TODO Implement - return disasm_verbatim(n, i, c, s); + return disasm_verbatim(node, instr, code, s); } static inline void disasm_adda_suba( @@ -1574,7 +1593,7 @@ static void disasm_add_sub_x_a( 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_sbcd(node, instr, mnemonic, "x"); + return disasm_addx_subx_abcd_sbcd(node, instr, mnemonic, "x"); } const char suffix = suffix_from_opsize(opsize); const auto addr = AddrModeArg::Fetch( diff --git a/test.bash b/test.bash index 0a70201..a6f25d7 100644 --- a/test.bash +++ b/test.bash @@ -93,10 +93,15 @@ run_test_iterative() { done } +# cxxx abcd +# +run_test_simple "abcd Dn, Dn" "\xc1\x01" +run_test_simple "abcd -(An), -(An)" "\xc1\x09" + # 8xxx sbcd # run_test_simple "sbcdb Dn, Dn" "\x81\x01" -run_test_simple "sbcdb -(An), -(An)" "\x81\x01" +run_test_simple "sbcdb -(An), -(An)" "\x81\x09" # 8xxx or # -- cgit v1.2.3