MCPcopy Create free account
hub / github.com/N64Recomp/N64Recomp / process_instruction

Function process_instruction

src/recompilation.cpp:115–760  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

113
114template <typename GeneratorType>
115bool process_instruction(GeneratorType& generator, const N64Recomp::Context& context, const N64Recomp::Function& func, size_t func_index, const N64Recomp::FunctionStats& stats, const std::unordered_set<uint32_t>& jtbl_lw_instructions, size_t instr_index, const std::vector<rabbitizer::InstructionCpu>& instructions, std::ostream& output_file, bool indent, bool emit_link_branch, int link_branch_index, size_t reloc_index, bool& needs_link_branch, bool& is_branch_likely, bool tag_reference_relocs, std::span<std::vector<uint32_t>> static_funcs_out) {
116 using namespace N64Recomp;
117
118 const auto& section = context.sections[func.section_index];
119 const auto& instr = instructions[instr_index];
120 needs_link_branch = false;
121 is_branch_likely = false;
122 uint32_t instr_vram = instr.getVram();
123 InstrId instr_id = instr.getUniqueId();
124
125 auto print_indent = [&]() {
126 fmt::print(output_file, " ");
127 };
128
129 auto hook_find = func.function_hooks.find(instr_index);
130 if (hook_find != func.function_hooks.end()) {
131 fmt::print(output_file, " {}\n", hook_find->second);
132 if (indent) {
133 print_indent();
134 }
135 }
136
137 // Output a comment with the original instruction
138 print_indent();
139 if (instr.isBranch() || instr_id == InstrId::cpu_j) {
140 generator.emit_comment(fmt::format("0x{:08X}: {}", instr_vram, instr.disassemble(0, fmt::format("L_{:08X}", (uint32_t)instr.getBranchVramGeneric()))));
141 } else if (instr_id == InstrId::cpu_jal) {
142 generator.emit_comment(fmt::format("0x{:08X}: {}", instr_vram, instr.disassemble(0, fmt::format("0x{:08X}", (uint32_t)instr.getBranchVramGeneric()))));
143 } else {
144 generator.emit_comment(fmt::format("0x{:08X}: {}", instr_vram, instr.disassemble(0)));
145 }
146
147 // Replace loads for jump table entries into addiu. This leaves the jump table entry's address in the output register
148 // instead of the entry's value, which can then be used to determine the offset from the start of the jump table.
149 if (jtbl_lw_instructions.contains(instr_vram)) {
150 assert(instr_id == InstrId::cpu_lw);
151 instr_id = InstrId::cpu_addiu;
152 }
153
154 N64Recomp::RelocType reloc_type = N64Recomp::RelocType::R_MIPS_NONE;
155 bool has_reloc = false;
156 uint32_t reloc_section = 0;
157 uint32_t reloc_target_section_offset = 0;
158 size_t reloc_reference_symbol = (size_t)-1;
159
160 uint32_t func_vram_end = func.vram + func.words.size() * sizeof(func.words[0]);
161
162 uint16_t imm = instr.Get_immediate();
163
164 // Check if this instruction has a reloc.
165 if (section.relocs.size() > 0 && section.relocs[reloc_index].address == instr_vram) {
166 has_reloc = true;
167 // Get the reloc data for this instruction
168 const auto& reloc = section.relocs[reloc_index];
169 reloc_section = reloc.target_section;
170
171 // Check if the relocation references a relocatable section.
172 bool target_relocatable = false;

Callers 1

recompile_function_implFunction · 0.70

Calls 15

resolve_jalFunction · 0.85
emit_commentMethod · 0.45
emit_gotoMethod · 0.45
emit_returnMethod · 0.45
emit_trigger_eventMethod · 0.45
emit_function_callMethod · 0.45

Tested by

no test coverage detected