diff options
Diffstat (limited to 'src/vm/arm64/pinvokestubs.S')
-rw-r--r-- | src/vm/arm64/pinvokestubs.S | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/vm/arm64/pinvokestubs.S b/src/vm/arm64/pinvokestubs.S new file mode 100644 index 0000000000..f6c33ba4c2 --- /dev/null +++ b/src/vm/arm64/pinvokestubs.S @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// ==++== +// + +// +// ==--== +#include "asmconstants.h" +#include "unixasmmacros.inc" + +// ------------------------------------------------------------------ +// Macro to generate PInvoke Stubs. +// $__PInvokeStubFuncName : function which calls the actual stub obtained from VASigCookie +// $__PInvokeGenStubFuncName : function which generates the IL stubs for PInvoke +// +// Params :- +// $FuncPrefix : prefix of the function name for the stub +// Eg. VarargPinvoke, GenericPInvokeCalli +// $VASigCookieReg : register which contains the VASigCookie +// $SaveFPArgs : "Yes" or "No" . For varidic functions FP Args are not present in FP regs +// So need not save FP Args registers for vararg Pinvoke +.macro PINVOKE_STUB FuncPrefix,VASigCookieReg,HiddenArg,SaveFPArgs + +#if NOTYET + GBLS __PInvokeStubFuncName + GBLS __PInvokeGenStubFuncName + GBLS __PInvokeStubWorkerName + + IF "\FuncPrefix" == "GenericPInvokeCalli" +__PInvokeStubFuncName SETS "\FuncPrefix":CC:"Helper" + ELSE +__PInvokeStubFuncName SETS "\FuncPrefix":CC:"Stub" + ENDIF +__PInvokeGenStubFuncName SETS "\FuncPrefix":CC:"GenILStub" +__PInvokeStubWorkerName SETS "\FuncPrefix":CC:"StubWorker" + + IF "\VASigCookieReg" == "x1" +__PInvokeStubFuncName SETS "\__PInvokeStubFuncName":CC:"_RetBuffArg" +__PInvokeGenStubFuncName SETS "\__PInvokeGenStubFuncName":CC:"_RetBuffArg" + ENDIF + + NESTED_ENTRY \__PInvokeStubFuncName + + // get the stub + ldr x9, [\VASigCookieReg, #VASigCookie__pNDirectILStub] + + // if null goto stub generation + cbz x9, %0 + + + EPILOG_BRANCH_REG x9 + +0 + EPILOG_BRANCH \__PInvokeGenStubFuncName + + NESTED_END + + + NESTED_ENTRY \__PInvokeGenStubFuncName + + PROLOG_WITH_TRANSITION_BLOCK 0, \SaveFPArgs + + // x2 = Umanaged Target\MethodDesc + mov x2, \HiddenArg + + // x1 = VaSigCookie + IF "\VASigCookieReg" != "x1" + mov x1, \VASigCookieReg + ENDIF + + // x0 = pTransitionBlock + add x0, sp, #__PWTB_TransitionBlock + + // save hidden arg + mov x19, \HiddenArg + + bl \__PInvokeStubWorkerName + + // restore hidden arg (method desc or unmanaged target) + mov \HiddenArg , x19 + + + EPILOG_WITH_TRANSITION_BLOCK_TAILCALL + + EPILOG_BRANCH \__PInvokeStubFuncName + + NESTED_END +#else + EMIT_BREAKPOINT +#endif +.endm + +// ------------------------------------------------------------------ +// VarargPInvokeStub & VarargPInvokeGenILStub +// There is a separate stub when the method has a hidden return buffer arg. +// +// in: +// x0 = VASigCookie* +// x12 = MethodDesc * +// +PINVOKE_STUB VarargPInvoke, x0, x12, 1 + + +// ------------------------------------------------------------------ +// GenericPInvokeCalliHelper & GenericPInvokeCalliGenILStub +// Helper for generic pinvoke calli instruction +// +// in: +// x15 = VASigCookie* +// x14 = Unmanaged target +// +PINVOKE_STUB GenericPInvokeCalli, x15, x14, 1 + +// ------------------------------------------------------------------ +// VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg +// Vararg PInvoke Stub when the method has a hidden return buffer arg +// +// in: +// x1 = VASigCookie* +// x12 = MethodDesc* +// +PINVOKE_STUB VarargPInvoke, x1, x12, 0 |