diff --git a/LiveRecomp/live_generator.cpp b/LiveRecomp/live_generator.cpp index 2c9c78d..1447d5e 100644 --- a/LiveRecomp/live_generator.cpp +++ b/LiveRecomp/live_generator.cpp @@ -1375,6 +1375,12 @@ void N64Recomp::LiveGenerator::emit_function_call(const Context&, size_t functio context->inner_calls.emplace_back(InnerCall{ .target_func_index = function_index, .jump = call_jump }); } +void N64Recomp::LiveGenerator::emit_named_function_call(const std::string& function_name) const { + // The live recompiler can't call functions by name. This is only used for statics, so it's not an issue. + assert(false); + errored = true; +} + void N64Recomp::LiveGenerator::emit_goto(const std::string& target) const { sljit_jump* jump = sljit_emit_jump(compiler, SLJIT_JUMP); // Check if the label already exists. diff --git a/include/recompiler/generator.h b/include/recompiler/generator.h index 737e920..0ffde0b 100644 --- a/include/recompiler/generator.h +++ b/include/recompiler/generator.h @@ -38,6 +38,7 @@ namespace N64Recomp { // but for live recompilation the reference symbol list is unavailable so it's still provided. virtual void emit_function_call_reference_symbol(const Context& context, uint16_t section_index, size_t symbol_index, uint32_t target_section_offset) const = 0; virtual void emit_function_call(const Context& context, size_t function_index) const = 0; + virtual void emit_named_function_call(const std::string& function_name) const = 0; virtual void emit_goto(const std::string& target) const = 0; virtual void emit_label(const std::string& label_name) const = 0; virtual void emit_jtbl_addend_declaration(const JumpTable& jtbl, int reg) const = 0; @@ -74,6 +75,7 @@ namespace N64Recomp { void emit_function_call_by_register(int reg) const final; void emit_function_call_reference_symbol(const Context& context, uint16_t section_index, size_t symbol_index, uint32_t target_section_offset) const final; void emit_function_call(const Context& context, size_t function_index) const final; + void emit_named_function_call(const std::string& function_name) const final; void emit_goto(const std::string& target) const final; void emit_label(const std::string& label_name) const final; void emit_jtbl_addend_declaration(const JumpTable& jtbl, int reg) const final; diff --git a/include/recompiler/live_recompiler.h b/include/recompiler/live_recompiler.h index 840746d..1b92d95 100644 --- a/include/recompiler/live_recompiler.h +++ b/include/recompiler/live_recompiler.h @@ -99,6 +99,7 @@ namespace N64Recomp { void emit_function_call_by_register(int reg) const final; void emit_function_call_reference_symbol(const Context& context, uint16_t section_index, size_t symbol_index, uint32_t target_section_offset) const final; void emit_function_call(const Context& context, size_t function_index) const final; + void emit_named_function_call(const std::string& function_name) const final; void emit_goto(const std::string& target) const final; void emit_label(const std::string& label_name) const final; void emit_jtbl_addend_declaration(const JumpTable& jtbl, int reg) const final; diff --git a/src/cgenerator.cpp b/src/cgenerator.cpp index 4b8f3f8..175ea12 100644 --- a/src/cgenerator.cpp +++ b/src/cgenerator.cpp @@ -423,6 +423,10 @@ void N64Recomp::CGenerator::emit_function_call(const Context& context, size_t fu fmt::print(output_file, "{}(rdram, ctx);\n", context.functions[function_index].name); } +void N64Recomp::CGenerator::emit_named_function_call(const std::string& function_name) const { + fmt::print(output_file, "{}(rdram, ctx);\n", function_name); +} + void N64Recomp::CGenerator::emit_goto(const std::string& target) const { fmt::print(output_file, " goto {};\n", target); @@ -489,7 +493,7 @@ void N64Recomp::CGenerator::emit_cop0_status_read(int reg) const { } void N64Recomp::CGenerator::emit_cop0_status_write(int reg) const { - fmt::print(output_file, "cop0_status_write(ctx, {})", gpr_to_string(reg)); + fmt::print(output_file, "cop0_status_write(ctx, {});", gpr_to_string(reg)); } void N64Recomp::CGenerator::emit_cop1_cs_read(int reg) const { diff --git a/src/recompilation.cpp b/src/recompilation.cpp index d8cc16d..cf12c49 100644 --- a/src/recompilation.cpp +++ b/src/recompilation.cpp @@ -267,6 +267,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con (uint32_t target_func_vram, bool tail_call = false, bool indent = false) { bool call_by_lookup = false; + bool call_by_name = false; // Event symbol, emit a call to the runtime to trigger this event. if (reloc_section == N64Recomp::SectionEvent) { needs_link_branch = !tail_call; @@ -312,8 +313,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con // Create a static function add it to the static function list for this section. jal_target_name = fmt::format("static_{}_{:08X}", func.section_index, target_func_vram); static_funcs_out[func.section_index].push_back(target_func_vram); - // TODO skip lookup for static functions. - call_by_lookup = true; + call_by_name = true; break; case JalResolutionResult::Ambiguous: fmt::print(stderr, "[Info] Ambiguous jal target 0x{:08X} in function {}, falling back to function lookup\n", target_func_vram, func.name); @@ -341,6 +341,9 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con else if (call_by_lookup) { generator.emit_function_call_lookup(target_func_vram); } + else if (call_by_name) { + generator.emit_named_function_call(jal_target_name); + } else { generator.emit_function_call(context, matched_func_index); }