summaryrefslogtreecommitdiff
path: root/disasm.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-20 14:42:01 +0300
committerOxore <oxore@protonmail.com>2023-05-20 14:42:01 +0300
commitdc752c3b87cb998f194ab81f6f8fbdf490374474 (patch)
tree7fbaedf8c5fdf6e11f237d565dc050fc3f6b2a37 /disasm.cpp
parent935f386f61b63267bd6516a1888cf939b8eef238 (diff)
Impl data references, debuting with LEA
Diffstat (limited to 'disasm.cpp')
-rw-r--r--disasm.cpp61
1 files changed, 37 insertions, 24 deletions
diff --git a/disasm.cpp b/disasm.cpp
index e5ec421..a5223c7 100644
--- a/disasm.cpp
+++ b/disasm.cpp
@@ -178,23 +178,23 @@ static size_t disasm_jsr_jmp(
case AddrMode::kWord: // 4eb8 / 4ef8
{
const uint32_t ref_addr = static_cast<uint32_t>(a.lword);
- node.ref_addr = ref_addr;
- node.has_ref = true;
+ node.ref1_addr = ref_addr;
+ node.ref_kinds = kRef1AbsMask;
}
break;
case AddrMode::kLong: // 4eb9 / 4ef9
{
const uint32_t ref_addr = static_cast<uint32_t>(a.lword);
- node.ref_addr = ref_addr;
- node.has_ref = true;
+ node.ref1_addr = ref_addr;
+ node.ref_kinds = kRef1AbsMask;
}
break;
case AddrMode::kD16PCAddr: // 4eba / 4efa
{
const uint32_t ref_addr = node.offset + kInstructionSizeStepBytes +
static_cast<uint32_t>(a.d16_pc.d16);
- node.ref_addr = ref_addr;
- node.has_ref = true;
+ node.ref1_addr = ref_addr;
+ node.ref_kinds = kRef1RelMask;
}
break;
case AddrMode::kD8PCXiAddr: // 4ebb / 4efb
@@ -205,7 +205,7 @@ static size_t disasm_jsr_jmp(
return disasm_verbatim(node, instr);
}
const bool is_jmp = instr & 0x40;
- node.is_call = !is_jmp;
+ node.ref_kinds |= is_jmp ? 0 : kRefCallMask;
node.op = Op::Typical(is_jmp ? OpCode::kJMP : OpCode::kJSR, OpSize::kNone, a);
return node.size = kInstructionSizeStepBytes + a.Size(opsize);
}
@@ -299,9 +299,17 @@ static size_t disasm_lea(
return disasm_verbatim(node, instr);
case AddrMode::kD16AnAddr:
case AddrMode::kD8AnXiAddr:
+ break;
case AddrMode::kWord:
case AddrMode::kLong:
+ node.ref1_addr = static_cast<uint32_t>(addr.lword);
+ node.ref_kinds = kRef1AbsMask | kRefReadMask;
+ break;
case AddrMode::kD16PCAddr:
+ node.ref1_addr = node.offset + kInstructionSizeStepBytes +
+ static_cast<uint32_t>(addr.d16_pc.d16);
+ node.ref_kinds = kRef1RelMask | kRefReadMask;
+ break;
case AddrMode::kD8PCXiAddr:
break;
case AddrMode::kImmediate:
@@ -369,9 +377,8 @@ static size_t disasm_bra_bsr_bcc(
const uint32_t ref_addr = static_cast<uint32_t>(node.offset + dispmt);
Condition condition = static_cast<Condition>((instr >> 8) & 0xf);
// False condition Indicates BSR
- node.is_call = (condition == Condition::kF);
- node.ref_addr = ref_addr;
- node.has_ref = true;
+ node.ref1_addr = ref_addr;
+ node.ref_kinds = kRef1RelMask | ((condition == Condition::kF) ? kRefCallMask : 0);
node.op = Op{OpCode::kBcc, opsize, condition, Arg::Displacement(dispmt)};
return node.size;
}
@@ -992,8 +999,8 @@ static size_t disasm_dbcc(DisasmNode &node, const uint16_t instr, const DataBuff
}
const int16_t dispmt_raw = GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes);
const int32_t dispmt = dispmt_raw + kInstructionSizeStepBytes;
- node.ref_addr = static_cast<uint32_t>(node.offset + dispmt);
- node.has_ref = true;
+ node.ref2_addr = static_cast<uint32_t>(node.offset + dispmt);
+ node.ref_kinds = kRef2RelMask;
node.op = Op{
OpCode::kDBcc,
OpSize::kNone,
@@ -1499,11 +1506,16 @@ size_t DisasmNode::Disasm(const DataBuffer &code)
return this->size;
}
size = kInstructionSizeStepBytes;
- has_ref = 0;
- ref_addr = 0;
- is_call = false;
+ ref_kinds = 0;
+ ref1_addr = 0;
+ ref2_addr = 0;
const uint16_t instr = GetU16BE(code.buffer + this->offset);
- return m68k_disasm(*this, instr, code);
+ if (this->type == TracedNodeType::kInstruction) {
+ return m68k_disasm(*this, instr, code);
+ } else {
+ // Data should not be disassembled
+ return disasm_verbatim(*this, instr);
+ }
}
size_t DisasmNode::DisasmAsRaw(const DataBuffer &code)
@@ -1511,9 +1523,9 @@ size_t DisasmNode::DisasmAsRaw(const DataBuffer &code)
// We assume that machine have no MMU and ROM data always starts with 0
assert(this->offset < code.occupied_size);
size = kInstructionSizeStepBytes;
- has_ref = 0;
- ref_addr = 0;
- is_call = false;
+ ref_kinds = 0;
+ ref1_addr = 0;
+ ref2_addr = 0;
const uint16_t instr = GetU16BE(code.buffer + this->offset);
return disasm_verbatim(*this, instr);
}
@@ -1735,7 +1747,7 @@ static size_t snprint_reg_mask(
int Arg::SNPrint(
char *const buf,
const size_t bufsz,
- const unsigned ref_kinds,
+ const RefKindMask ref_kinds,
const uint32_t self_addr,
const uint32_t ref_addr) const
{
@@ -1828,19 +1840,20 @@ int Arg::SNPrint(
int Op::FPrint(
FILE *const stream,
- const unsigned ref_kinds,
+ const RefKindMask ref_kinds,
const uint32_t self_addr,
- const uint32_t ref_addr) const
+ const uint32_t ref1_addr,
+ const uint32_t ref2_addr) const
{
assert(opcode != OpCode::kNone);
char mnemonic_str[kMnemonicBufferSize]{};
OpcodeSNPrintf(mnemonic_str, kMnemonicBufferSize, opcode, condition, size_spec);
if (arg1.type != ArgType::kNone) {
char arg1_str[kArgsBufferSize]{};
- arg1.SNPrint(arg1_str, kArgsBufferSize, ref_kinds, self_addr, ref_addr);
+ arg1.SNPrint(arg1_str, kArgsBufferSize, ref_kinds & kRef1Mask, self_addr, ref1_addr);
if (arg2.type != ArgType::kNone) {
char arg2_str[kArgsBufferSize]{};
- arg2.SNPrint(arg2_str, kArgsBufferSize, ref_kinds, self_addr, ref_addr);
+ arg2.SNPrint(arg2_str, kArgsBufferSize, ref_kinds & kRef2Mask, self_addr, ref2_addr);
return fprintf(stream, " %s %s,%s", mnemonic_str, arg1_str, arg2_str);
} else {
return fprintf(stream, " %s %s", mnemonic_str, arg1_str);