summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-21 22:15:11 +0300
committerOxore <oxore@protonmail.com>2023-05-21 22:38:55 +0300
commitd4aa0bf9d642df7da85d25246ffb99ddca814f8f (patch)
tree384c6897eca675a9b2675791538a222787aee073
parentbefd06430f141cbe95ea2393603046020cb14019 (diff)
Impl imm refs for MOVEA
-rw-r--r--Readme.md2
-rw-r--r--common.h5
-rw-r--r--disasm.cpp21
-rw-r--r--main.cpp7
4 files changed, 32 insertions, 3 deletions
diff --git a/Readme.md b/Readme.md
index 251adf0..2197e07 100644
--- a/Readme.md
+++ b/Readme.md
@@ -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
diff --git a/common.h b/common.h
index 074823a..8ec55ba 100644
--- a/common.h
+++ b/common.h
@@ -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;
diff --git a/disasm.cpp b/disasm.cpp
index 7741963..3ee1e31 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -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);
diff --git a/main.cpp b/main.cpp
index ce40cc4..a05b380 100644
--- a/main.cpp
+++ b/main.cpp
@@ -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");