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 | |
parent | befd06430f141cbe95ea2393603046020cb14019 (diff) |
Impl imm refs for MOVEA
-rw-r--r-- | Readme.md | 2 | ||||
-rw-r--r-- | common.h | 5 | ||||
-rw-r--r-- | disasm.cpp | 21 | ||||
-rw-r--r-- | main.cpp | 7 |
4 files changed, 32 insertions, 3 deletions
@@ -94,7 +94,7 @@ trace table. Rr better with marks analysis and some fancy raw comments: ``` -./cmake-build/m68k-disasm -frdc -fxrefs-to -fxrefs-from -fmarks -fabs-marks -frel-marks -t pc-trace.txt -o disasm.S rom.bin +./cmake-build/m68k-disasm -frdc -fxrefs-to -fxrefs-from -fmarks -fabs-marks -frel-marks -fimm-marks -t pc-trace.txt -o disasm.S rom.bin ``` It will produce `disasm.S` which you can modify and assemble as shown in @@ -7,6 +7,7 @@ struct Settings { bool marks{}; bool rel_marks{}; bool abs_marks{}; + bool imm_marks{}; bool xrefs_to{}; bool xrefs_from{}; bool raw_data_comment{}; @@ -27,8 +28,10 @@ constexpr RefKindMask kRef2WriteMask = (1 << 7); // For second argument constexpr RefKindMask kRefCallMask = (1 << 8); /// Hack flag for MOVEM with PC relative value when -frel-marks is set constexpr RefKindMask kRefPcRelFix2Bytes = (1 << 9); +/// Register 1 may have immediate moving to address register which may be a mark +constexpr RefKindMask kRef1ImmMask = (1 << 10); /// Everything for first argument -constexpr RefKindMask kRef1Mask = kRef1RelMask | kRef1AbsMask | kRef1ReadMask | kRef1WriteMask; +constexpr RefKindMask kRef1Mask = kRef1RelMask | kRef1AbsMask | kRef1ReadMask | kRef1WriteMask | kRef1ImmMask; /// Everything for Second argument constexpr RefKindMask kRef2Mask = kRef2RelMask | kRef2AbsMask | kRef2ReadMask | kRef2WriteMask; constexpr RefKindMask kRefRelMask = kRef1RelMask | kRef2RelMask; @@ -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); @@ -301,6 +301,7 @@ static void RenderDisassembly( ? ((ref1 ? (node->ref_kinds & kRef1RelMask) : 0) | (ref2 ? (node->ref_kinds & kRef2RelMask) : 0)) : 0) | + ((s.imm_marks && ref1) ? (node->ref_kinds & kRef1ImmMask) : 0) | (node->ref_kinds & (kRefDataMask | kRefPcRelFix2Bytes)); node->op.FPrint(output, ref_kinds, node->offset, ref1_addr, ref2_addr); if (s.xrefs_to && ref1) { @@ -468,6 +469,8 @@ static bool IsValidFeature(const char *feature) return true; } else if (0 == strcmp(feature, "abs-marks")) { return true; + } else if (0 == strcmp(feature, "imm-marks")) { + return true; } else if (0 == strcmp(feature, "xrefs-from")) { return true; } else if (0 == strcmp(feature, "xrefs-to")) { @@ -492,6 +495,8 @@ static void ApplyFeature(Settings& s, const char *feature) s.rel_marks = !disable; } else if (0 == strcmp(feature, "abs-marks")) { s.abs_marks = !disable; + } else if (0 == strcmp(feature, "imm-marks")) { + s.imm_marks = !disable; } else if (0 == strcmp(feature, "xrefs-from")) { s.xrefs_from = !disable; } else if (0 == strcmp(feature, "xrefs-to")) { @@ -516,6 +521,8 @@ static void PrintUsage(FILE *s, const char *argv0) fprintf(s, " branch or call\n"); fprintf(s, " abs-marks use mark instead of number on absolute\n"); fprintf(s, " branch or call\n"); + fprintf(s, " imm-marks use mark instead of number when immediate\n"); + fprintf(s, " value moved to address register\n"); fprintf(s, " xrefs-from print xrefs comments above all places that\n"); fprintf(s, " have xrefs\n"); fprintf(s, " xrefs-to print xrefs comments after all branch \n"); |