diff options
author | Oxore <oxore@protonmail.com> | 2023-05-21 22:15:11 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-05-21 22:38:55 +0300 |
commit | d4aa0bf9d642df7da85d25246ffb99ddca814f8f (patch) | |
tree | 384c6897eca675a9b2675791538a222787aee073 /disasm.cpp | |
parent | befd06430f141cbe95ea2393603046020cb14019 (diff) |
Impl imm refs for MOVEA
Diffstat (limited to 'disasm.cpp')
-rw-r--r-- | disasm.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -667,6 +667,17 @@ static size_t disasm_move_movea( case AddrMode::kImmediate: return disasm_verbatim(node, instr); } + // XXX Assuming that moving long immediate value into address register is + // basically a sneaky LEA. It may not be true in some cases. + if (src.type == ArgType::kImmediate && dst.type == ArgType::kAn) { + if (opsize == OpSize::kLong) { + node.ref1_addr = static_cast<uint32_t>(src.lword); + node.ref_kinds |= kRef1ImmMask | kRef1ReadMask; + } else if (opsize == OpSize::kWord) { + node.ref1_addr = static_cast<int16_t>(static_cast<uint16_t>(src.lword)); + node.ref_kinds |= kRef1ImmMask | kRef1ReadMask; + } + } const auto opcode = (dst.mode == AddrMode::kAn) ? OpCode::kMOVEA : OpCode::kMOVE; node.op = Op::Typical(opcode, opsize, src, dst); return node.size = kInstructionSizeStepBytes + src.Size(opsize) + dst.Size(opsize); @@ -1879,7 +1890,15 @@ int Arg::SNPrint( RegNum(d8_pc_xi.xi), SizeSpecChar(d8_pc_xi.xi)); case ArgType::kImmediate: - if (imm_as_hex) { + if (ref_kinds & kRef1ImmMask) { + if (static_cast<uint32_t>(lword) == ref_addr) { + return snprintf(buf, bufsz, "#.L%08x", ref_addr); + } else { + // It has to be AFTER the mark we are gonna reference here + assert(static_cast<uint32_t>(lword) > ref_addr); + return snprintf(buf, bufsz, "#.L%08x+%d", ref_addr, lword - ref_addr); + } + } else if (imm_as_hex) { return snprintf(buf, bufsz, "#0x%x", lword); } else { return snprintf(buf, bufsz, "#%d", lword); |