mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-03-15 07:20:58 +00:00
Implement shim function generation (#128)
This commit is contained in:
parent
198de1b5cf
commit
2af6f2d161
@ -1896,3 +1896,29 @@ bool N64Recomp::recompile_function_live(LiveGenerator& generator, const Context&
|
||||
return recompile_function_custom(generator, context, function_index, output_file, static_funcs_out, tag_reference_relocs);
|
||||
}
|
||||
|
||||
N64Recomp::ShimFunction::ShimFunction(recomp_func_ext_t* to_shim, uintptr_t value) {
|
||||
sljit_compiler* compiler = sljit_create_compiler(nullptr);
|
||||
|
||||
// Create the function.
|
||||
sljit_label* func_label = sljit_emit_label(compiler);
|
||||
sljit_emit_enter(compiler, 0, SLJIT_ARGS2V(P_R, P_R), 3, 0, 0);
|
||||
|
||||
// Move the provided value into the third argument.
|
||||
sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, sljit_sw(value));
|
||||
|
||||
// Tail call the provided function.
|
||||
sljit_emit_icall(compiler, SLJIT_CALL | SLJIT_CALL_RETURN, SLJIT_ARGS3V(P, P, W), SLJIT_IMM, sljit_sw(to_shim));
|
||||
|
||||
// Generate the function's code and get the address to the function.
|
||||
code = sljit_generate_code(compiler, 0, nullptr);
|
||||
func = reinterpret_cast<recomp_func_t*>(sljit_get_label_addr(func_label));
|
||||
|
||||
// Cleanup.
|
||||
sljit_free_compiler(compiler);
|
||||
}
|
||||
|
||||
N64Recomp::ShimFunction::~ShimFunction() {
|
||||
sljit_free_code(code, nullptr);
|
||||
code = nullptr;
|
||||
func = nullptr;
|
||||
}
|
||||
|
@ -439,7 +439,11 @@ gpr cop0_status_read(recomp_context* ctx);
|
||||
void switch_error(const char* func, uint32_t vram, uint32_t jtbl);
|
||||
void do_break(uint32_t vram);
|
||||
|
||||
// The function signature for all recompiler output functions.
|
||||
typedef void (recomp_func_t)(uint8_t* rdram, recomp_context* ctx);
|
||||
// The function signature for special functions that need a third argument.
|
||||
// These get called via generated shims to allow providing some information about the caller, such as mod id.
|
||||
typedef void (recomp_func_ext_t)(uint8_t* rdram, recomp_context* ctx, uintptr_t arg);
|
||||
|
||||
recomp_func_t* get_function(int32_t vram);
|
||||
|
||||
|
@ -141,6 +141,16 @@ namespace N64Recomp {
|
||||
|
||||
void live_recompiler_init();
|
||||
bool recompile_function_live(LiveGenerator& generator, const Context& context, size_t function_index, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs);
|
||||
|
||||
class ShimFunction {
|
||||
private:
|
||||
void* code;
|
||||
recomp_func_t* func;
|
||||
public:
|
||||
ShimFunction(recomp_func_ext_t* to_shim, uintptr_t value);
|
||||
~ShimFunction();
|
||||
recomp_func_t* get_func() { return func; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user