diff --git a/src/backend_x64/a32_emit_x64.cpp b/src/backend_x64/a32_emit_x64.cpp index e7320795..c4050faa 100644 --- a/src/backend_x64/a32_emit_x64.cpp +++ b/src/backend_x64/a32_emit_x64.cpp @@ -154,56 +154,56 @@ void A32EmitX64::GenMemoryAccessors() { code.align(); read_memory_8 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryRead8).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryRead8>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); read_memory_16 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryRead16).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryRead16>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); read_memory_32 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryRead32).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryRead32>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); read_memory_64 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryRead64).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryRead64>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); write_memory_8 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryWrite8).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryWrite8>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); write_memory_16 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryWrite16).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryWrite16>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); write_memory_32 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryWrite32).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryWrite32>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); code.align(); write_memory_64 = code.getCurr(); ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); - DEVIRT(config.callbacks, &A32::UserCallbacks::MemoryWrite64).EmitCall(code); + Devirtualize<&A32::UserCallbacks::MemoryWrite64>(config.callbacks).EmitCall(code); ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, ABI_RETURN); code.ret(); } @@ -605,12 +605,12 @@ void A32EmitX64::EmitA32CallSupervisor(A32EmitContext& ctx, IR::Inst* inst) { code.SwitchMxcsrOnExit(); code.mov(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_to_run)]); code.sub(code.ABI_PARAM2, qword[r15 + offsetof(A32JitState, cycles_remaining)]); - DEVIRT(config.callbacks, &A32::UserCallbacks::AddTicks).EmitCall(code); + Devirtualize<&A32::UserCallbacks::AddTicks>(config.callbacks).EmitCall(code); ctx.reg_alloc.EndOfAllocScope(); auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0]); - DEVIRT(config.callbacks, &A32::UserCallbacks::CallSVC).EmitCall(code); - DEVIRT(config.callbacks, &A32::UserCallbacks::GetTicksRemaining).EmitCall(code); + Devirtualize<&A32::UserCallbacks::CallSVC>(config.callbacks).EmitCall(code); + Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(config.callbacks).EmitCall(code); code.mov(qword[r15 + offsetof(A32JitState, cycles_to_run)], code.ABI_RETURN); code.mov(qword[r15 + offsetof(A32JitState, cycles_remaining)], code.ABI_RETURN); code.SwitchMxcsrOnEntry(); @@ -622,7 +622,7 @@ void A32EmitX64::EmitA32ExceptionRaised(A32EmitContext& ctx, IR::Inst* inst) { ASSERT(args[0].IsImmediate() && args[1].IsImmediate()); u32 pc = args[0].GetImmediateU32(); u64 exception = args[1].GetImmediateU64(); - DEVIRT(config.callbacks, &A32::UserCallbacks::ExceptionRaised).EmitCall(code, [&](RegList param) { + Devirtualize<&A32::UserCallbacks::ExceptionRaised>(config.callbacks).EmitCall(code, [&](RegList param) { code.mov(param[0], pc); code.mov(param[1], exception); }); @@ -691,7 +691,7 @@ static void ReadMemory(BlockOfCode& code, RegAlloc& reg_alloc, IR::Inst* inst, c if (!config.page_table) { reg_alloc.HostCall(inst, {}, args[0]); - DEVIRT(config.callbacks, raw_fn).EmitCall(code); + Devirtualize(config.callbacks).EmitCall(code); return; } @@ -744,7 +744,7 @@ static void WriteMemory(BlockOfCode& code, RegAlloc& reg_alloc, IR::Inst* inst, if (!config.page_table) { reg_alloc.HostCall(nullptr, {}, args[0], args[1]); - DEVIRT(config.callbacks, raw_fn).EmitCall(code); + Devirtualize(config.callbacks).EmitCall(code); return; } @@ -848,7 +848,7 @@ static void ExclusiveWrite(BlockOfCode& code, RegAlloc& reg_alloc, IR::Inst* ins code.shl(code.ABI_PARAM4, 32); code.or_(code.ABI_PARAM3, code.ABI_PARAM4); } - DEVIRT(config.callbacks, fn).EmitCall(code); + Devirtualize(config.callbacks).EmitCall(code); code.xor_(passed, passed); code.L(end); @@ -1143,7 +1143,7 @@ void A32EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDesc code.mov(code.ABI_PARAM3.cvt32(), 1); code.mov(MJitStateReg(A32::Reg::PC), code.ABI_PARAM2.cvt32()); code.SwitchMxcsrOnExit(); - DEVIRT(config.callbacks, &A32::UserCallbacks::InterpreterFallback).EmitCall(code); + Devirtualize<&A32::UserCallbacks::InterpreterFallback>(config.callbacks).EmitCall(code); code.ReturnFromRunCode(true); // TODO: Check cycles } diff --git a/src/backend_x64/a32_interface.cpp b/src/backend_x64/a32_interface.cpp index 7cf2503e..ef71ce2d 100644 --- a/src/backend_x64/a32_interface.cpp +++ b/src/backend_x64/a32_interface.cpp @@ -33,8 +33,8 @@ using namespace BackendX64; static RunCodeCallbacks GenRunCodeCallbacks(A32::UserCallbacks* cb, CodePtr (*LookupBlock)(void* lookup_block_arg), void* arg) { return RunCodeCallbacks{ std::make_unique(LookupBlock, reinterpret_cast(arg)), - std::make_unique(DEVIRT(cb, &A32::UserCallbacks::AddTicks)), - std::make_unique(DEVIRT(cb, &A32::UserCallbacks::GetTicksRemaining)), + std::make_unique(Devirtualize<&A32::UserCallbacks::AddTicks>(cb)), + std::make_unique(Devirtualize<&A32::UserCallbacks::GetTicksRemaining>(cb)), }; } diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp index 287dfc41..e8a5eb05 100644 --- a/src/backend_x64/a64_emit_x64.cpp +++ b/src/backend_x64/a64_emit_x64.cpp @@ -140,16 +140,17 @@ void A64EmitX64::GenMemory128Accessors() { code.align(); memory_read_128 = code.getCurr(); #ifdef _WIN32 - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCallWithReturnPointer(code, [&](Xbyak::Reg64 return_value_ptr, RegList args) { - code.mov(code.ABI_PARAM3, code.ABI_PARAM2); - code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE); - code.lea(return_value_ptr, ptr[rsp + ABI_SHADOW_SPACE]); - }); + Devirtualize<&A64::UserCallbacks::MemoryRead128>(conf.callbacks).EmitCallWithReturnPointer(code, + [&](Xbyak::Reg64 return_value_ptr, RegList args) { + code.mov(code.ABI_PARAM3, code.ABI_PARAM2); + code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE); + code.lea(return_value_ptr, ptr[rsp + ABI_SHADOW_SPACE]); + }); code.movups(xmm1, xword[code.ABI_RETURN]); code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE); #else code.sub(rsp, 8); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead128).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryRead128>(conf.callbacks).EmitCall(code); if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE41)) { code.movq(xmm1, code.ABI_RETURN); code.pinsrq(xmm1, code.ABI_RETURN2, 1); @@ -168,7 +169,7 @@ void A64EmitX64::GenMemory128Accessors() { code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE); code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]); code.movaps(xword[code.ABI_PARAM3], xmm1); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite128>(conf.callbacks).EmitCall(code); code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE); #else code.sub(rsp, 8); @@ -180,7 +181,7 @@ void A64EmitX64::GenMemory128Accessors() { code.punpckhqdq(xmm1, xmm1); code.movq(code.ABI_PARAM4, xmm1); } - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite128).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite128>(conf.callbacks).EmitCall(code); code.add(rsp, 8); #endif code.ret(); @@ -189,16 +190,16 @@ void A64EmitX64::GenMemory128Accessors() { void A64EmitX64::GenFastmemFallbacks() { const std::initializer_list idxes{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; const std::vector> read_callbacks { - {8, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead8)}, - {16, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead16)}, - {32, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead32)}, - {64, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead64)}, + {8, Devirtualize<&A64::UserCallbacks::MemoryRead8>(conf.callbacks)}, + {16, Devirtualize<&A64::UserCallbacks::MemoryRead16>(conf.callbacks)}, + {32, Devirtualize<&A64::UserCallbacks::MemoryRead32>(conf.callbacks)}, + {64, Devirtualize<&A64::UserCallbacks::MemoryRead64>(conf.callbacks)}, }; const std::vector> write_callbacks { - {8, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite8)}, - {16, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite16)}, - {32, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite32)}, - {64, DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite64)}, + {8, Devirtualize<&A64::UserCallbacks::MemoryWrite8>(conf.callbacks)}, + {16, Devirtualize<&A64::UserCallbacks::MemoryWrite16>(conf.callbacks)}, + {32, Devirtualize<&A64::UserCallbacks::MemoryWrite32>(conf.callbacks)}, + {64, Devirtualize<&A64::UserCallbacks::MemoryWrite64>(conf.callbacks)}, }; for (int vaddr_idx : idxes) { @@ -502,9 +503,10 @@ void A64EmitX64::EmitA64CallSupervisor(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ASSERT(args[0].IsImmediate()); u32 imm = args[0].GetImmediateU32(); - DEVIRT(conf.callbacks, &A64::UserCallbacks::CallSVC).EmitCall(code, [&](RegList param) { - code.mov(param[0], imm); - }); + Devirtualize<&A64::UserCallbacks::CallSVC>(conf.callbacks).EmitCall(code, + [&](RegList param) { + code.mov(param[0], imm); + }); // The kernel would have to execute ERET to get here, which would clear exclusive state. code.mov(code.byte[r15 + offsetof(A64JitState, exclusive_state)], u8(0)); } @@ -515,16 +517,17 @@ void A64EmitX64::EmitA64ExceptionRaised(A64EmitContext& ctx, IR::Inst* inst) { ASSERT(args[0].IsImmediate() && args[1].IsImmediate()); u64 pc = args[0].GetImmediateU64(); u64 exception = args[1].GetImmediateU64(); - DEVIRT(conf.callbacks, &A64::UserCallbacks::ExceptionRaised).EmitCall(code, [&](RegList param) { - code.mov(param[0], pc); - code.mov(param[1], exception); - }); + Devirtualize<&A64::UserCallbacks::ExceptionRaised>(conf.callbacks).EmitCall(code, + [&](RegList param) { + code.mov(param[0], pc); + code.mov(param[1], exception); + }); } void A64EmitX64::EmitA64DataCacheOperationRaised(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, args[0], args[1]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::DataCacheOperationRaised).EmitCall(code); + Devirtualize<&A64::UserCallbacks::DataCacheOperationRaised>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64DataSynchronizationBarrier(A64EmitContext&, IR::Inst*) { @@ -538,7 +541,7 @@ void A64EmitX64::EmitA64DataMemoryBarrier(A64EmitContext&, IR::Inst*) { void A64EmitX64::EmitA64GetCNTPCT(A64EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(inst); code.UpdateTicks(); - DEVIRT(conf.callbacks, &A64::UserCallbacks::GetCNTPCT).EmitCall(code); + Devirtualize<&A64::UserCallbacks::GetCNTPCT>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64GetCTR(A64EmitContext& ctx, IR::Inst* inst) { @@ -719,7 +722,7 @@ void A64EmitX64::EmitA64ReadMemory8(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, {}, args[0]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead8).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryRead8>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64ReadMemory16(A64EmitContext& ctx, IR::Inst* inst) { @@ -730,7 +733,7 @@ void A64EmitX64::EmitA64ReadMemory16(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, {}, args[0]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead16).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryRead16>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64ReadMemory32(A64EmitContext& ctx, IR::Inst* inst) { @@ -741,7 +744,7 @@ void A64EmitX64::EmitA64ReadMemory32(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, {}, args[0]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead32).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryRead32>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64ReadMemory64(A64EmitContext& ctx, IR::Inst* inst) { @@ -752,7 +755,7 @@ void A64EmitX64::EmitA64ReadMemory64(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(inst, {}, args[0]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryRead64).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryRead64>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64ReadMemory128(A64EmitContext& ctx, IR::Inst* inst) { @@ -791,7 +794,7 @@ void A64EmitX64::EmitA64WriteMemory8(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite8).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite8>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64WriteMemory16(A64EmitContext& ctx, IR::Inst* inst) { @@ -802,7 +805,7 @@ void A64EmitX64::EmitA64WriteMemory16(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite16).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite16>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64WriteMemory32(A64EmitContext& ctx, IR::Inst* inst) { @@ -813,7 +816,7 @@ void A64EmitX64::EmitA64WriteMemory32(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite32).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite32>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64WriteMemory64(A64EmitContext& ctx, IR::Inst* inst) { @@ -824,7 +827,7 @@ void A64EmitX64::EmitA64WriteMemory64(A64EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); ctx.reg_alloc.HostCall(nullptr, {}, args[0], args[1]); - DEVIRT(conf.callbacks, &A64::UserCallbacks::MemoryWrite64).EmitCall(code); + Devirtualize<&A64::UserCallbacks::MemoryWrite64>(conf.callbacks).EmitCall(code); } void A64EmitX64::EmitA64WriteMemory128(A64EmitContext& ctx, IR::Inst* inst) { @@ -979,11 +982,12 @@ void A64EmitX64::EmitA64ExclusiveWriteMemory128(A64EmitContext& ctx, IR::Inst* i void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) { code.SwitchMxcsrOnExit(); - DEVIRT(conf.callbacks, &A64::UserCallbacks::InterpreterFallback).EmitCall(code, [&](RegList param) { - code.mov(param[0], A64::LocationDescriptor{terminal.next}.PC()); - code.mov(qword[r15 + offsetof(A64JitState, pc)], param[0]); - code.mov(param[1].cvt32(), terminal.num_instructions); - }); + Devirtualize<&A64::UserCallbacks::InterpreterFallback>(conf.callbacks).EmitCall(code, + [&](RegList param) { + code.mov(param[0], A64::LocationDescriptor{terminal.next}.PC()); + code.mov(qword[r15 + offsetof(A64JitState, pc)], param[0]); + code.mov(param[1].cvt32(), terminal.num_instructions); + }); code.ReturnFromRunCode(true); // TODO: Check cycles } diff --git a/src/backend_x64/a64_interface.cpp b/src/backend_x64/a64_interface.cpp index 6d55fbe9..9a7ebfc6 100644 --- a/src/backend_x64/a64_interface.cpp +++ b/src/backend_x64/a64_interface.cpp @@ -29,8 +29,8 @@ using namespace BackendX64; static RunCodeCallbacks GenRunCodeCallbacks(A64::UserCallbacks* cb, CodePtr (*LookupBlock)(void* lookup_block_arg), void* arg) { return RunCodeCallbacks{ std::make_unique(LookupBlock, reinterpret_cast(arg)), - std::make_unique(DEVIRT(cb, &A64::UserCallbacks::AddTicks)), - std::make_unique(DEVIRT(cb, &A64::UserCallbacks::GetTicksRemaining)), + std::make_unique(Devirtualize<&A64::UserCallbacks::AddTicks>(cb)), + std::make_unique(Devirtualize<&A64::UserCallbacks::GetTicksRemaining>(cb)), }; } diff --git a/src/backend_x64/devirtualize.h b/src/backend_x64/devirtualize.h index 908f2651..59857fd2 100644 --- a/src/backend_x64/devirtualize.h +++ b/src/backend_x64/devirtualize.h @@ -32,19 +32,19 @@ struct ThunkBuilder { } // namespace impl -template -ArgCallback DevirtualizeGeneric(Common::mp::class_type_t* this_) { - return ArgCallback{&impl::ThunkBuilder::Thunk, reinterpret_cast(this_)}; +template +ArgCallback DevirtualizeGeneric(Common::mp::class_type_t* this_) { + return ArgCallback{&impl::ThunkBuilder::Thunk, reinterpret_cast(this_)}; } -template -ArgCallback DevirtualizeWindows(Common::mp::class_type_t* this_) { +template +ArgCallback DevirtualizeWindows(Common::mp::class_type_t* this_) { static_assert(sizeof(mfp) == 8); return ArgCallback{Common::BitCast(mfp), reinterpret_cast(this_)}; } -template -ArgCallback DevirtualizeItanium(Common::mp::class_type_t* this_) { +template +ArgCallback DevirtualizeItanium(Common::mp::class_type_t* this_) { struct MemberFunctionPointer { /// For a non-virtual function, this is a simple function pointer. /// For a virtual function, it is (1 + virtual table offset in bytes). @@ -65,15 +65,18 @@ ArgCallback DevirtualizeItanium(Common::mp::class_type_t* this_) { return ArgCallback{fn_ptr, this_ptr}; } +template +ArgCallback Devirtualize(Common::mp::class_type_t* this_) { #if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__) -#define DEVIRT(this_, mfp) Dynarmic::BackendX64::DevirtualizeItanium(this_) + return DevirtualizeItanium(this_); #elif defined(__MINGW64__) -#define DEVIRT(this_, mfp) Dynarmic::BackendX64::DevirtualizeItanium(this_) + return DevirtualizeItanium(this_); #elif defined(_WIN32) -#define DEVIRT(this_, mfp) Dynarmic::BackendX64::DevirtualizeWindows(this_) + return DevirtualizeWindows(this_); #else -#define DEVIRT(this_, mfp) Dynarmic::BackendX64::DevirtualizeGeneric(this_) + return DevirtualizeGeneric(this_); #endif +} } // namespace BackendX64 } // namespace Dynarmic