summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-02 00:07:04 +0300
committerOxore <oxore@protonmail.com>2023-05-02 00:07:04 +0300
commit0df8468808e922f694de264cae59762ff484b67e (patch)
tree771b439587ddca3031218147d4f7eb5c28cee286
parentf1083d93821cf9e3d9041f451ed8e14474db02f7 (diff)
Impl LEA
-rw-r--r--disasm.cpp36
-rw-r--r--test.bash8
2 files changed, 42 insertions, 2 deletions
diff --git a/disasm.cpp b/disasm.cpp
index 3142a21..d761c12 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -446,7 +446,39 @@ static void disasm_movem(
static void disasm_lea(
DisasmNode &node, uint16_t instr, const DataBuffer &code, const Settings &s)
{
+ const auto addr = AddrModeArg::Fetch(
+ node.offset + kInstructionSizeStepBytes, code, instr, 'l');
+ switch (addr.mode) {
+ case AddrMode::kInvalid:
+ case AddrMode::kDn:
+ case AddrMode::kAn:
return disasm_verbatim(node, instr, code, s);
+ case AddrMode::kAnAddr:
+ break;
+ case AddrMode::kAnAddrIncr:
+ case AddrMode::kAnAddrDecr:
+ return disasm_verbatim(node, instr, code, s);
+ case AddrMode::kD16AnAddr:
+ case AddrMode::kD8AnXiAddr:
+ case AddrMode::kWord:
+ case AddrMode::kLong:
+ case AddrMode::kD16PCAddr:
+ case AddrMode::kD8PCXiAddr:
+ break;
+ case AddrMode::kImmediate:
+ return disasm_verbatim(node, instr, code, s);
+ }
+ const unsigned an = ((instr >> 9) & 7);
+ const auto reg = AddrModeArg::Fetch(
+ node.offset + kInstructionSizeStepBytes, code, 1, an, 'l');
+ assert(reg.mode == AddrMode::kAn);
+ 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, "leal");
+ snprintf(node.arguments, kArgsBufferSize, "%s,%s", addr_str, reg_str);
+ node.size = kInstructionSizeStepBytes + addr.Size() + reg.Size();
}
static void disasm_chk(
@@ -1110,9 +1142,9 @@ static void chunk_mf000_v4000(
return disasm_jsr_jmp(node, instr, code, s, JType::kJmp);
} else if ((instr & 0xfb80) == 0x4880) {
return disasm_movem(node, instr, code, s);
- } else if ((instr & 0xf1c) == 0x41c0) {
+ } else if ((instr & 0xf1c0) == 0x41c0) {
return disasm_lea(node, instr, code, s);
- } else if ((instr & 0xf1c) == 0x4180) {
+ } else if ((instr & 0xf1c0) == 0x4180) {
return disasm_chk(node, instr, code, s);
}
return disasm_verbatim(node, instr, code, s);
diff --git a/test.bash b/test.bash
index 9bde77c..d615b32 100644
--- a/test.bash
+++ b/test.bash
@@ -93,6 +93,14 @@ run_test_iterative() {
done
}
+# 4xxx lea
+#
+run_test_simple "lea (An)" "\x41\xd0"
+run_test_simple "lea (d16,An)" "\x47\xe9\x80\x00"
+run_test_simple "lea (d8,An,Xi)" "\x47\xf2\xa8\x7f"
+run_test_simple "lea (d16,PC)" "\x47\xfa\x7f\xff"
+run_test_simple "lea (d8,PC,Xi)" "\x47\xfb\xa8\x80"
+
# 0xxx movep
#
run_test_simple "movepw Dn to (An)" "\x01\x0b\x00\xa0"