From 89bcb73d479009d13a8002d652432dc124e1e936 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 12 Feb 2026 01:45:22 +0100 Subject: [PATCH] [dynarmic] x86 direct immediate call for host calls within 2G (#3508) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3508 Reviewed-by: DraVee Reviewed-by: CamilleLaVey Co-authored-by: lizzie Co-committed-by: lizzie --- .../src/dynarmic/backend/x64/emit_x64.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp b/src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp index 072b790fd4..2b0540e4a7 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/emit_x64.cpp @@ -71,11 +71,22 @@ void EmitX64::EmitBreakpoint(EmitContext&, IR::Inst*) { code.int3(); } +constexpr bool IsWithin2G(uintptr_t ref, uintptr_t target) { + const u64 distance = target - (ref + 5); + return !(distance >= 0x8000'0000ULL && distance <= ~0x8000'0000ULL); +} + void EmitX64::EmitCallHostFunction(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(code, nullptr, args[1], args[2], args[3]); - code.mov(rax, args[0].GetImmediateU64()); - code.call(rax); + auto target = args[0].GetImmediateU64(); + if (IsWithin2G(uintptr_t(code.getCurr()), target)) { + auto const f = std::bit_cast(target); + code.call(f); + } else { + code.mov(rax, target); + code.call(rax); + } } void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, IR::LocationDescriptor target) {