From 4dbf5a7b1a4446d965e239f07dd1515f3c7f6eb4 Mon Sep 17 00:00:00 2001 From: Oxore Date: Mon, 15 May 2023 02:18:15 +0300 Subject: Permit unaligned branching --- disasm.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/disasm.cpp b/disasm.cpp index 6a836dc..6f19b94 100644 --- a/disasm.cpp +++ b/disasm.cpp @@ -354,25 +354,24 @@ static size_t disasm_chk( static size_t disasm_bra_bsr_bcc( DisasmNode &node, const uint16_t instr, const DataBuffer &code) { - int16_t dispmt = static_cast(instr & 0xff); - if (dispmt % static_cast(kInstructionSizeStepBytes)) { + const int16_t dispmt0 = static_cast(instr & 0xff); + if (dispmt0 == -1) { + // This will definitely lead to executing invalid instruction and is + // also invalid for GNU AS to assemble return disasm_verbatim(node, instr); } - const auto opsize = dispmt ? OpSize::kShort : OpSize::kWord; - if (dispmt == 0) { + const auto opsize = dispmt0 ? OpSize::kShort : OpSize::kWord; + if (dispmt0 == 0) { // Check the boundaries if (node.offset + kInstructionSizeStepBytes >= code.occupied_size) { return disasm_verbatim(node, instr); } - dispmt = GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes); - if (dispmt % kInstructionSizeStepBytes) { - return disasm_verbatim(node, instr); - } node.size = kInstructionSizeStepBytes * 2; } else { node.size = kInstructionSizeStepBytes; } - dispmt += kInstructionSizeStepBytes; + const int16_t dispmt = kInstructionSizeStepBytes + (dispmt0 + ? dispmt0 : GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes)); const uint32_t branch_addr = static_cast(node.offset + dispmt); Condition condition = static_cast((instr >> 8) & 0xf); // False condition Indicates BSR @@ -999,9 +998,6 @@ static size_t disasm_dbcc(DisasmNode &node, const uint16_t instr, const DataBuff return disasm_verbatim(node, instr); } const int16_t dispmt_raw = GetI16BE(code.buffer + node.offset + kInstructionSizeStepBytes); - if (dispmt_raw % static_cast(kInstructionSizeStepBytes)) { - return disasm_verbatim(node, instr); - } const int32_t dispmt = dispmt_raw + kInstructionSizeStepBytes; node.branch_addr = static_cast(node.offset + dispmt); node.has_branch_addr = true; @@ -1703,7 +1699,7 @@ static size_t snprint_reg_mask( size_t written = 0; bool first_printed = 0; size_t span = 0; - // 17-th bit used to close the span with 0 value unconditionaly + // 17-th bit used to close the span with 0 value unconditionally for (int i = 0; i < 17; i++) { const uint32_t mask = 1 << (arg_type == ArgType::kRegMaskPredecrement ? (15 - i) : i); const bool hit = regmask & mask; -- cgit v1.2.3