mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 15:00:17 +02:00
Merge pull request #3225 from neobrain/fix_32bit_funcptrs
Thunks: Fix function pointer support on 32-bit
This commit is contained in:
3 files changed
+23
-17
No files matched your search
@@ -393,7 +393,7 @@ void Dispatcher::EmitDispatcher() {
|
||||
LoadConstant(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r0, CTX->X86CodeGen.CallbackReturn);
|
||||
|
||||
ldr(ARMEmitter::XReg::x2, STATE_PTR(CpuStateFrame, State.gregs[X86State::REG_RSP]));
|
||||
sub(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, ARMEmitter::Reg::r2, 16);
|
||||
sub(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, ARMEmitter::Reg::r2, CTX->Config.Is64BitMode ? 16 : 12);
|
||||
str(ARMEmitter::XReg::x2, STATE_PTR(CpuStateFrame, State.gregs[X86State::REG_RSP]));
|
||||
|
||||
// Store the trampoline to the guest stack
|
||||
|
||||
@@ -171,8 +171,14 @@ namespace FEXCore {
|
||||
Set arg0/1 to arg regs, use CTX::HandleCallback to handle the callback
|
||||
*/
|
||||
static void CallCallback(void *callback, void *arg0, void* arg1) {
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
|
||||
auto CTX = static_cast<Context::ContextImpl*>(Thread->CTX);
|
||||
if (CTX->Config.Is64BitMode) {
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0;
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1;
|
||||
} else {
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RCX] = (uintptr_t)arg0;
|
||||
Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDX] = (uintptr_t)arg1;
|
||||
}
|
||||
|
||||
Thread->CTX->HandleCallback(Thread, (uintptr_t)callback);
|
||||
}
|
||||
@@ -220,7 +226,7 @@ namespace FEXCore {
|
||||
emit->_StoreRegister(emit->_Constant(Entrypoint), false, offsetof(Core::CPUState, gregs[X86State::REG_R11]), IR::GPRClass, IR::GPRFixedClass, GPRSize);
|
||||
}
|
||||
else {
|
||||
emit->_StoreRegister(emit->_Constant(Entrypoint), false, offsetof(Core::CPUState, mm[0][0]), IR::GPRClass, IR::GPRFixedClass, GPRSize);
|
||||
emit->_StoreContext(GPRSize, IR::FPRClass, emit->_VCastFromGPR(8, 8, emit->_Constant(Entrypoint)), offsetof(Core::CPUState, mm[0][0]));
|
||||
}
|
||||
emit->_ExitFunction(emit->_Constant(GuestThunkEntrypoint));
|
||||
}, CTX->ThunkHandler.get(), (void*)args->target_addr);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#ifdef __clang__
|
||||
#define THUNK_ABI __fastcall
|
||||
#else
|
||||
#define THUNK_ABI [[gnu::fastcall]]
|
||||
#define THUNK_ABI __attribute__((fastcall))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -75,8 +75,8 @@ MAKE_THUNK(fex, allocate_host_trampoline_for_guest_function, "0x9b, 0xb2, 0xf4,
|
||||
|
||||
inline void LinkAddressToFunction(uintptr_t addr, uintptr_t target) {
|
||||
struct args_t {
|
||||
uintptr_t original_callee;
|
||||
uintptr_t target_addr; // Function to call when branching to replaced_addr
|
||||
uint64_t original_callee;
|
||||
uint64_t target_addr; // Function to call when branching to replaced_addr
|
||||
};
|
||||
args_t args = { addr, target };
|
||||
fexthunks_fex_link_address_to_function(&args);
|
||||
@@ -126,14 +126,14 @@ inline Result CallHostFunction(Args... args) {
|
||||
// Use mm0 to pass in host_addr (chosen to avoid conflicts with vectorcall).
|
||||
// Note this register overlaps the x87 st(0) register (used to return float values),
|
||||
// so applications that expect this register to be preserved could run into problems.
|
||||
register uintptr_t host_addr asm ("mm0");
|
||||
asm volatile("" : "=r" (host_addr));
|
||||
uintptr_t host_addr; \
|
||||
asm volatile("movd %%mm0, %0" : "=r" (host_addr));
|
||||
#endif
|
||||
#else
|
||||
uintptr_t host_addr = 0;
|
||||
#endif
|
||||
|
||||
PackedArguments<Result, Args..., uintptr_t> packed_args = {
|
||||
PackedArguments<Result, Args..., uint64_t> packed_args = {
|
||||
args...,
|
||||
host_addr
|
||||
// Return value not explicitly initialized since an initializer would fail to compile for the void case
|
||||
@@ -162,20 +162,20 @@ inline void MakeHostFunctionGuestCallable(THUNK_ABI Result (*host_func)(Args...)
|
||||
}
|
||||
|
||||
template<typename Target>
|
||||
inline Target *AllocateHostTrampolineForGuestFunction(void (*GuestUnpacker)(uintptr_t, void*), Target *GuestTarget) {
|
||||
inline Target* AllocateHostTrampolineForGuestFunction(void THUNK_ABI (*GuestUnpacker)(uintptr_t, void*), Target *GuestTarget) {
|
||||
if (!GuestTarget) {
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
uintptr_t GuestUnpacker;
|
||||
uintptr_t GuestTarget;
|
||||
uintptr_t rv;
|
||||
uint64_t GuestUnpacker;
|
||||
uint64_t GuestTarget;
|
||||
uint64_t rv;
|
||||
} argsrv = { (uintptr_t)GuestUnpacker, (uintptr_t)GuestTarget };
|
||||
|
||||
fexthunks_fex_allocate_host_trampoline_for_guest_function((void*)&argsrv);
|
||||
|
||||
return (Target *)argsrv.rv;
|
||||
return (Target*)argsrv.rv;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
@@ -183,7 +183,7 @@ struct CallbackUnpack;
|
||||
|
||||
template<typename Result, typename... Args>
|
||||
struct CallbackUnpack<Result(Args...)> {
|
||||
static void Unpack(uintptr_t cb, void* argsv) {
|
||||
static void THUNK_ABI Unpack(uintptr_t cb, void* argsv) {
|
||||
using fn_t = Result(Args...);
|
||||
auto callback = reinterpret_cast<fn_t*>(cb);
|
||||
auto args = reinterpret_cast<PackedArguments<Result, Args...>*>(argsv);
|
||||
|
||||
Reference in new issue
Block a user