diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 122 |
1 files changed, 59 insertions, 63 deletions
diff --git a/src/main.cpp b/src/main.cpp index 338b92b..2a060df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -78,11 +78,9 @@ static constexpr bool ShouldPrintAsRaw(const Op& op) static constexpr bool HasCallReference(const DisasmNode &node) { - for (const ReferenceNode *ref{node.ref_by}; ref; ref = ref->next) { - for (size_t i = 0; i < ref->refs_count; i++) { - if (ref->refs[i].type == ReferenceType::kCall) { - return true; - } + for (const ReferenceRecord *ref{node.ref_by}; ref; ref = ref->next) { + if (ref->type == ReferenceType::kCall) { + return true; } } return false; @@ -99,49 +97,46 @@ static constexpr size_t GetNodeSizeByAddress(const DisasmMap &disasm_map, const static constexpr bool IsLocalLocation(const DisasmMap &disasm_map, const DisasmNode &node) { - for (const ReferenceNode *ref{node.ref_by}; ref; ref = ref->next) { - for (size_t i = 0; i < ref->refs_count; i++) { - // Check symtab, because we may be crossing a symbol - const DisasmNode *ref_node = disasm_map.FindNodeByAddress(ref->refs[i].address); - if (ref_node != nullptr) { - // We won't cross a symbol at the address if the reference is - // backwards ('1b') and we will cross a symbol if the reference - // is forwards ('1f') - that's why we shift the range one - // instruction forward by adding a size to the address and the - // length. - // TODO write tests for it - uint32_t const address = (node.address < ref_node->address) - ? node.address + node.size - : ref_node->address + ref_node->size; - size_t const length = (node.address < ref_node->address) - ? ref_node->address + ref_node->size - (node.address + node.size) - : node.address + node.size - (ref_node->address + ref_node->size); - if (disasm_map.HasSymbolsInRange(address, length)) { - return false; - } - } - const ReferenceRecord &ref_rec = ref->refs[i]; - if (ref_rec.type == ReferenceType::kCall) { - // Locals are definitely not made for calls + for (const ReferenceRecord *ref{node.ref_by}; ref; ref = ref->next) { + // Check symtab, because we may be crossing a symbol + const DisasmNode *ref_node = disasm_map.FindNodeByAddress(ref->address); + if (ref_node != nullptr) { + // We won't cross a symbol at the address if the reference is + // backwards ('1b') and we will cross a symbol if the reference + // is forwards ('1f') - that's why we shift the range one + // instruction forward by adding a size to the address and the + // length. + // TODO write tests for it + uint32_t const address = (node.address < ref_node->address) + ? node.address + node.size + : ref_node->address + ref_node->size; + size_t const length = (node.address < ref_node->address) + ? ref_node->address + ref_node->size - (node.address + node.size) + : node.address + node.size - (ref_node->address + ref_node->size); + if (disasm_map.HasSymbolsInRange(address, length)) { return false; } - const bool forward = ref_rec.address < node.address; - const size_t min_addr = forward ? ref_rec.address : node.address; - const size_t start = min_addr + GetNodeSizeByAddress(disasm_map, min_addr); - const size_t max_addr = forward ? node.address : ref_rec.address; - const size_t end = max_addr + (forward ? 0 : GetNodeSizeByAddress(disasm_map, min_addr)); - for (size_t addr = start; addr < end;) { - const auto *intermediate_node = disasm_map.FindNodeByAddress(addr); - if (intermediate_node) { - if (intermediate_node->ref_by) { - // Another labeled node detected on the jump path, hence - // current node's location cannot be considered local - return false; - } - addr += intermediate_node->size; - } else { - addr += kInstructionSizeStepBytes; + } + if (ref->type == ReferenceType::kCall) { + // Locals are definitely not made for calls + return false; + } + const bool forward = ref->address < node.address; + const size_t min_addr = forward ? ref->address : node.address; + const size_t start = min_addr + GetNodeSizeByAddress(disasm_map, min_addr); + const size_t max_addr = forward ? node.address : ref->address; + const size_t end = max_addr + (forward ? 0 : GetNodeSizeByAddress(disasm_map, min_addr)); + for (size_t addr = start; addr < end;) { + const auto *intermediate_node = disasm_map.FindNodeByAddress(addr); + if (intermediate_node) { + if (intermediate_node->ref_by) { + // Another labeled node detected on the jump path, hence + // current node's location cannot be considered local + return false; } + addr += intermediate_node->size; + } else { + addr += kInstructionSizeStepBytes; } } } @@ -329,6 +324,11 @@ struct EmitContext { size_t last_rendered_function_symbol_addr{SIZE_MAX}; }; +static constexpr const char *commentSequence(const Settings &s) +{ + return s.target_asm == TargetAssembler::kGnuAs ? "|" : ";"; +} + static bool EmitNodeDisassembly( const EmitContext &ctx, const DisasmMap &disasm_map, @@ -363,8 +363,7 @@ static bool EmitNodeDisassembly( if (s.labels && !is_local) { const bool export_this_function = s.export_functions && have_call_reference; const bool export_this_label = s.export_all_labels || - (s.export_labels && node.ref_by && (node.ref_by->refs_count > 1)) || - export_this_function; + (s.export_labels && node.ref_by) || export_this_function; if (export_this_label) { fprintf(output, "\n%s.globl\t%s\n", s.indent, name); if (export_this_function) { @@ -382,24 +381,21 @@ static bool EmitNodeDisassembly( } } while (0); if (s.xrefs_from && (have_symbol || !is_local)) { - if (s.target_asm == TargetAssembler::kGnuAs) { - fprintf(output, "| XREFS:\n"); - } else { - fprintf(output, "; XREFS:\n"); - } - for (const ReferenceNode *ref{node.ref_by}; ref; ref = ref->next) { - if (ref->refs_count == 0) { - continue; + assert(s.xrefs_per_line >= 1); + fprintf(output, "%s XREFS:\n", commentSequence(s)); + size_t refs_count = 0; + for (const ReferenceRecord *ref{node.ref_by}; ref; ref = ref->next) { + if (refs_count == 0) { + fprintf(output, commentSequence(s)); } - if (s.target_asm == TargetAssembler::kGnuAs) { - fprintf(output, "|"); - } else { - fprintf(output, ";"); - } - for (size_t i = 0; i < ref->refs_count; i++) { - const ReferenceRecord r = ref->refs[i]; - fprintf(output, " %s @%08x", ReferenceTypeToString(r.type), r.address); + fprintf(output, " %s @%08x", ReferenceTypeToString(ref->type), ref->address); + refs_count++; + if (refs_count >= s.xrefs_per_line) { + fprintf(output, "\n"); + refs_count = 0; } + } + if (refs_count != 0) { fprintf(output, "\n"); } } |