mirror of
https://github.com/Mr-Wiseguy/N64Recomp.git
synced 2024-12-26 17:36:16 +00:00
Allow zero-sized symbols in a specific range for patches, fixed cases where errors didn't terminate the recompiler
This commit is contained in:
parent
4161ef68cc
commit
424a509b22
|
@ -45,9 +45,13 @@ JalResolutionResult resolve_jal(const RecompPort::Context& context, size_t cur_s
|
|||
for (size_t target_func_index : matching_funcs_find->second) {
|
||||
const auto& target_func = context.functions[target_func_index];
|
||||
|
||||
// Skip zero-sized symbols.
|
||||
// Zero-sized symbol handling. unless there's only one matching target.
|
||||
if (target_func.words.empty()) {
|
||||
continue;
|
||||
// Allow zero-sized symbols between 0x8F000000 and 0x90000000 for use with patches.
|
||||
// TODO make this configurable or come up with a more sensible solution for dealing with manual symbols for patches.
|
||||
if (target_func.vram < 0x8F000000 || target_func.vram > 0x90000000) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Immediately accept a function in the same section as this one, since it must also be loaded if the current function is.
|
||||
|
@ -218,7 +222,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
if (reloc_index + 1 < section.relocs.size() && next_vram > section.relocs[reloc_index].address) {
|
||||
next_reloc_index++;
|
||||
}
|
||||
process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, false, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out);
|
||||
if (!process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, false, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
print_indent();
|
||||
fmt::vprint(output_file, fmt_str, fmt::make_format_args(args...));
|
||||
|
@ -227,6 +233,7 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
} else {
|
||||
fmt::print(output_file, ";\n");
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
auto print_func_call = [reloc_target_section_offset, reloc_reference_symbol, reloc_type, &context, §ion, &func, &static_funcs_out, &needs_link_branch, &print_unconditional_branch]
|
||||
|
@ -292,10 +299,12 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
if (context.functions_by_vram.find(branch_target) != context.functions_by_vram.end()) {
|
||||
fmt::print(output_file, "{{\n ");
|
||||
fmt::print("Tail call in {} to 0x{:08X}\n", func.name, branch_target);
|
||||
print_func_call(branch_target, false, true);
|
||||
if (!print_func_call(branch_target, false, true)) {
|
||||
return false;
|
||||
}
|
||||
print_line(" return");
|
||||
fmt::print(output_file, " }}\n");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
fmt::print(stderr, "[Warn] Function {} is branching outside of the function (to 0x{:08X})\n", func.name, branch_target);
|
||||
|
@ -310,7 +319,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
if (reloc_index + 1 < section.relocs.size() && next_vram > section.relocs[reloc_index].address) {
|
||||
next_reloc_index++;
|
||||
}
|
||||
process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, true, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out);
|
||||
if (!process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, true, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fmt::print(output_file, " ");
|
||||
|
@ -319,6 +330,7 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
fmt::print(output_file, ";\n goto after_{}", link_branch_index);
|
||||
}
|
||||
fmt::print(output_file, ";\n }}\n");
|
||||
return true;
|
||||
};
|
||||
|
||||
if (indent) {
|
||||
|
@ -621,7 +633,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
|
||||
// Branches
|
||||
case InstrId::cpu_jal:
|
||||
print_func_call(instr.getBranchVramGeneric());
|
||||
if (!print_func_call(instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_jalr:
|
||||
// jalr can only be handled with $ra as the return address register
|
||||
|
@ -657,7 +671,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
// FIXME: how to deal with static functions?
|
||||
else if (context.functions_by_vram.find(branch_target) != context.functions_by_vram.end()) {
|
||||
fmt::print("Tail call in {} to 0x{:08X}\n", func.name, branch_target);
|
||||
print_func_call(branch_target, false);
|
||||
if (!print_func_call(branch_target, false)) {
|
||||
return false;
|
||||
}
|
||||
print_line("return");
|
||||
}
|
||||
else {
|
||||
|
@ -683,7 +699,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
if (reloc_index + 1 < section.relocs.size() && next_vram > section.relocs[reloc_index].address) {
|
||||
next_reloc_index++;
|
||||
}
|
||||
process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, false, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out);
|
||||
if (!process_instruction(context, config, func, stats, skipped_insns, instr_index + 1, instructions, output_file, false, false, link_branch_index, next_reloc_index, dummy_needs_link_branch, dummy_is_branch_likely, static_funcs_out)) {
|
||||
return false;
|
||||
}
|
||||
print_indent();
|
||||
fmt::print(output_file, "switch (jr_addend_{:08X} >> 2) {{\n", cur_jtbl.jr_vram);
|
||||
for (size_t entry_index = 0; entry_index < cur_jtbl.entries.size(); entry_index++) {
|
||||
|
@ -731,7 +749,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bne:
|
||||
print_indent();
|
||||
print_branch_condition("if ({}{} != {}{})", ctx_gpr_prefix(rs), rs, ctx_gpr_prefix(rt), rt);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_beql:
|
||||
is_branch_likely = true;
|
||||
|
@ -739,7 +759,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_beq:
|
||||
print_indent();
|
||||
print_branch_condition("if ({}{} == {}{})", ctx_gpr_prefix(rs), rs, ctx_gpr_prefix(rt), rt);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_bgezl:
|
||||
is_branch_likely = true;
|
||||
|
@ -747,7 +769,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bgez:
|
||||
print_indent();
|
||||
print_branch_condition("if (SIGNED({}{}) >= 0)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_bgtzl:
|
||||
is_branch_likely = true;
|
||||
|
@ -755,7 +779,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bgtz:
|
||||
print_indent();
|
||||
print_branch_condition("if (SIGNED({}{}) > 0)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_blezl:
|
||||
is_branch_likely = true;
|
||||
|
@ -763,7 +789,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_blez:
|
||||
print_indent();
|
||||
print_branch_condition("if (SIGNED({}{}) <= 0)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_bltzl:
|
||||
is_branch_likely = true;
|
||||
|
@ -771,7 +799,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bltz:
|
||||
print_indent();
|
||||
print_branch_condition("if (SIGNED({}{}) < 0)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_break:
|
||||
print_line("do_break({})", instr_vram);
|
||||
|
@ -782,7 +812,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bgezal:
|
||||
print_indent();
|
||||
print_branch_condition("if (SIGNED({}{}) >= 0) {{", ctx_gpr_prefix(rs), rs);
|
||||
print_func_call(instr.getBranchVramGeneric());
|
||||
if (!print_func_call(instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
print_line("}}");
|
||||
break;
|
||||
|
||||
|
@ -952,7 +984,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bc1t:
|
||||
print_indent();
|
||||
print_branch_condition("if (c1cs)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_bc1fl:
|
||||
is_branch_likely = true;
|
||||
|
@ -960,7 +994,9 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
case InstrId::cpu_bc1f:
|
||||
print_indent();
|
||||
print_branch_condition("if (!c1cs)", ctx_gpr_prefix(rs), rs);
|
||||
print_branch((uint32_t)instr.getBranchVramGeneric());
|
||||
if (!print_branch((uint32_t)instr.getBranchVramGeneric())) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
// Cop1 arithmetic
|
||||
|
|
Loading…
Reference in a new issue