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

Method analyze_function

src/analysis.cpp:267–351  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

265}
266
267bool N64Recomp::analyze_function(const N64Recomp::Context& context, const N64Recomp::Function& func,
268 const std::vector<rabbitizer::InstructionCpu>& instructions, N64Recomp::FunctionStats& stats) {
269 const Section* section = &context.sections[func.section_index];
270 std::optional<uint32_t> got_ram_addr = section->got_ram_addr;
271
272 // Create a state to track each register (r0 won't be used)
273 RegState reg_states[32] {};
274 std::vector<RegState> stack_states{};
275
276 // Look for jump tables
277 // A linear search through the func won't be accurate due to not taking control flow into account, but it'll work for finding jtables
278 for (const auto& instr : instructions) {
279 if (!analyze_instruction(instr, func, stats, reg_states, stack_states, got_ram_addr.has_value())) {
280 return false;
281 }
282 }
283
284 // Calculate absolute addresses for position-independent jump tables
285 if (got_ram_addr.has_value()) {
286 uint32_t got_rom_addr = got_ram_addr.value() + func.rom - func.vram;
287
288 for (size_t i = 0; i < stats.jump_tables.size(); i++) {
289 JumpTable& cur_jtbl = stats.jump_tables[i];
290
291 if (cur_jtbl.got_offset.has_value()) {
292 uint32_t got_word = byteswap(*reinterpret_cast<const uint32_t*>(&context.rom[got_rom_addr + cur_jtbl.got_offset.value()]));
293
294 cur_jtbl.vram += (section->ram_addr + got_word);
295 }
296 }
297 }
298
299 // Sort jump tables by their address
300 std::sort(stats.jump_tables.begin(), stats.jump_tables.end(),
301 [](const JumpTable& a, const JumpTable& b)
302 {
303 return a.vram < b.vram;
304 });
305
306 // Determine jump table sizes
307 for (size_t i = 0; i < stats.jump_tables.size(); i++) {
308 JumpTable& cur_jtbl = stats.jump_tables[i];
309 uint32_t end_address = (uint32_t)-1;
310 uint32_t entry_count = 0;
311 uint32_t vram = cur_jtbl.vram;
312
313 if (i < stats.jump_tables.size() - 1) {
314 end_address = stats.jump_tables[i + 1].vram;
315 }
316
317 // TODO this assumes that the jump table is in the same section as the function itself
318 cur_jtbl.rom = cur_jtbl.vram + func.rom - func.vram;
319 cur_jtbl.section_index = func.section_index;
320
321 while (vram < end_address) {
322 // Retrieve the current entry of the jump table
323 // TODO same as above
324 uint32_t rom_addr = vram + func.rom - func.vram;

Callers

nothing calls this directly

Calls 2

analyze_instructionFunction · 0.85
byteswapFunction · 0.50

Tested by

no test coverage detected