[Decompiler] Put likely delay slots in their own block (#237)

* first part of fix

* atomic op conversion fix

* update tests

* oops
This commit is contained in:
water111
2021-02-06 17:04:03 -05:00
committed by GitHub
parent 5b6a8dcf98
commit f8b63a3f92
16 changed files with 669 additions and 383 deletions
+19 -1
View File
@@ -23,7 +23,7 @@ std::vector<BasicBlock> find_blocks_in_function(const LinkedObjectFile& file,
const auto& instr = func.instructions.at(i);
const auto& instr_info = instr.get_info();
if (instr_info.is_branch || instr_info.is_branch_likely) {
if (instr_info.is_branch && !instr_info.is_branch_likely) {
// make sure the delay slot of this branch is included in the function
assert(i + func.start_word < func.end_word - 1);
// divider after delay slot
@@ -37,6 +37,24 @@ std::vector<BasicBlock> find_blocks_in_function(const LinkedObjectFile& file,
assert(label.offset / 4 < func.end_word - 1);
dividers.push_back(label.offset / 4 - func.start_word);
}
// for branch likely, we treat the likely instruction as a separate block.
if (instr_info.is_branch_likely) {
assert(i + func.start_word < func.end_word - 1);
// divider after branch instruction
dividers.push_back(i + 1);
// divider after likely delay slot.
dividers.push_back(i + 2);
// divider at the destination.
auto label_id = instr.get_label_target();
assert(label_id != -1);
const auto& label = file.labels.at(label_id);
// should only jump to within our own function
assert(label.target_segment == seg);
assert(label.offset / 4 > func.start_word);
assert(label.offset / 4 < func.end_word - 1);
dividers.push_back(label.offset / 4 - func.start_word);
}
}
std::sort(dividers.begin(), dividers.end());