From 8c53b88cc33df7fcbe780f1e557493a50f0d3418 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 29 Jan 2015 01:49:25 -0600 Subject: [PATCH] [AArch64] Implement a way to call lambdas in the emitter --- Source/Core/Common/Arm64Emitter.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Source/Core/Common/Arm64Emitter.h b/Source/Core/Common/Arm64Emitter.h index a7c65e4137..78052def11 100644 --- a/Source/Core/Common/Arm64Emitter.h +++ b/Source/Core/Common/Arm64Emitter.h @@ -597,6 +597,29 @@ public: // ABI related void ABI_PushRegisters(BitSet32 registers); void ABI_PopRegisters(BitSet32 registers, BitSet32 ignore_mask = BitSet32(0)); + + // Utility to generate a call to a std::function object. + // + // Unfortunately, calling operator() directly is undefined behavior in C++ + // (this method might be a thunk in the case of multi-inheritance) so we + // have to go through a trampoline function. + template + static void CallLambdaTrampoline(const std::function* f, + Args... args) + { + (*f)(args...); + } + + // This function expects you to have set up the state. + // Overwrites X0 and X30 + template + ARM64Reg ABI_SetupLambda(const std::function* f) + { + auto trampoline = &ARM64XEmitter::CallLambdaTrampoline; + MOVI2R(X30, (u64)trampoline); + MOVI2R(X0, (u64)const_cast((const void*)f)); + return X30; + } }; class ARM64FloatEmitter