summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disasm.cpp55
-rw-r--r--test.bash9
2 files changed, 60 insertions, 4 deletions
diff --git a/disasm.cpp b/disasm.cpp
index a432d5b..b50cb5f 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -1434,7 +1434,6 @@ static void disasm_divu_divs_mulu_muls(
break;
case AddrMode::kAn:
return disasm_verbatim(node, instr, code, s);
- /* Fall through */
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1517,7 +1516,6 @@ static void disasm_or_and(
break;
case AddrMode::kAn:
return disasm_verbatim(node, instr, code, s);
- /* Fall through */
case AddrMode::kAnAddr:
case AddrMode::kAnAddrIncr:
case AddrMode::kAnAddrDecr:
@@ -1682,6 +1680,52 @@ static void disasm_add_sub_cmp(
node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
+static void disasm_cmpm(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+{
+ // TODO Implement
+ return disasm_verbatim(node, instr, code, s);
+}
+
+static void disasm_eor(
+ DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
+{
+ const OpSize opsize = static_cast<OpSize>((instr >> 6) & 3);
+ const char suffix = suffix_from_opsize(opsize);
+ const auto addr = AddrModeArg::Fetch(
+ node.offset + kInstructionSizeStepBytes, code, instr, suffix);
+ switch (addr.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);
+ 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:
+ // PC relative and immediate cannot be destination
+ return disasm_verbatim(node, instr, code, s);
+ }
+ const unsigned dn = (instr >> 9) & 7;
+ const auto reg = AddrModeArg::Dn(dn);
+ char addr_str[32]{};
+ char reg_str[32]{};
+ addr.SNPrint(addr_str, sizeof(addr_str));
+ 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();
+}
+
static void disasm_eor_cmpm_cmp_cmpa(
DisasmNode &node, const uint16_t instr, const DataBuffer &code, const Settings &s)
{
@@ -1693,8 +1737,11 @@ static void disasm_eor_cmpm_cmp_cmpa(
if (!dir_to_addr) {
return disasm_add_sub_cmp(node, instr, code, s, "cmp", opsize, dir_to_addr);
}
- // TODO Implement
- return disasm_verbatim(node, instr, code, s);
+ const int m = (instr >> 3) & 7;
+ if (m == 1) {
+ return disasm_cmpm(node, instr, code, s);
+ }
+ return disasm_eor(node, instr, code, s);
}
static inline void disasm_exg(DisasmNode &node, uint16_t instr)
diff --git a/test.bash b/test.bash
index 62d6391..863e3c0 100644
--- a/test.bash
+++ b/test.bash
@@ -93,6 +93,15 @@ run_test_iterative() {
done
}
+# bxxx eor
+#
+run_test_simple "eorb Dn, Dn" "\xb5\x01"
+run_test_expect_short "eorb Dn, An" "\xb5\x09"
+run_test_simple "eorb Dn, (An)" "\xb5\x11"
+run_test_simple "eorb Dn, (An)+" "\xb5\x19"
+run_test_simple "eorw Dn, -(An)" "\xb5\x61"
+run_test_simple "eorl Dn, (xxx).L" "\xb5\xb9\xff\xff\x00\x00"
+
# bxxx cmp
#
run_test_simple "cmpb Dn, Dn" "\xb4\x01"