summaryrefslogtreecommitdiff
path: root/src/vm/arm/pinvokestubs.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/arm/pinvokestubs.S')
-rw-r--r--src/vm/arm/pinvokestubs.S106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/vm/arm/pinvokestubs.S b/src/vm/arm/pinvokestubs.S
new file mode 100644
index 0000000000..202792550e
--- /dev/null
+++ b/src/vm/arm/pinvokestubs.S
@@ -0,0 +1,106 @@
+// 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"
+
+.syntax unified
+.thumb
+
+// ------------------------------------------------------------------
+// Macro to generate PInvoke Stubs.
+// Params :-
+// \__PInvokeStubFuncName : function which calls the actual stub obtained from VASigCookie
+// \__PInvokeGenStubFuncName : function which generates the IL stubs for PInvoke
+// \__PInvokeStubWorkerName : prefix of the function name for the stub
+// \VASigCookieReg : register which contains the VASigCookie
+// \SaveFPArgs : "1" or "0" . For varidic functions FP Args are not present in FP regs
+// So need not save FP Args registers for vararg Pinvoke
+.macro PINVOKE_STUB __PInvokeStubFuncName,__PInvokeGenStubFuncName,__PInvokeStubWorkerName,VASigCookieReg,SaveFPArgs
+
+ NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler
+
+ // save reg value before using the reg
+ PROLOG_PUSH {\VASigCookieReg}
+
+ // get the stub
+ ldr \VASigCookieReg, [\VASigCookieReg,#VASigCookie__pNDirectILStub]
+
+ // if null goto stub generation
+ cbz \VASigCookieReg, \__PInvokeStubFuncName\()Label
+
+ EPILOG_STACK_FREE 4
+ EPILOG_BRANCH_REG \VASigCookieReg
+
+\__PInvokeStubFuncName\()Label:
+ EPILOG_POP {\VASigCookieReg}
+ EPILOG_BRANCH \__PInvokeGenStubFuncName
+
+ NESTED_END \__PInvokeStubFuncName, _TEXT
+
+
+ NESTED_ENTRY \__PInvokeGenStubFuncName, _TEXT, NoHandler
+
+ PROLOG_WITH_TRANSITION_BLOCK 0, \SaveFPArgs
+
+ // r2 = UnmanagedTarget\ MethodDesc
+ mov r2, r12
+
+ // r1 = VaSigCookie
+ .ifnc \VASigCookieReg, r1
+ mov r1, \VASigCookieReg
+ .endif
+
+ // r0 = pTransitionBlock
+ add r0, sp, #__PWTB_TransitionBlock
+
+ // save hidden arg
+ mov r4, r12
+
+ bl \__PInvokeStubWorkerName
+
+ // restore hidden arg (method desc or unmanaged target)
+ mov r12, r4
+
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+ EPILOG_BRANCH \__PInvokeStubFuncName
+
+ NESTED_END \__PInvokeGenStubFuncName, _TEXT
+
+.endmacro
+
+// ------------------------------------------------------------------
+// VarargPInvokeStub & VarargPInvokeGenILStub
+// There is a separate stub when the method has a hidden return buffer arg.
+//
+// in:
+// r0 = VASigCookie*
+// r12 = MethodDesc *
+//
+PINVOKE_STUB VarargPInvokeStub, VarargPInvokeGenILStub, VarargPInvokeStubWorker, r0, 0
+
+// ------------------------------------------------------------------
+// GenericPInvokeCalliHelper & GenericPInvokeCalliGenILStub
+// Helper for generic pinvoke calli instruction
+//
+// in:
+// r4 = VASigCookie*
+// r12 = Unmanaged target
+//
+PINVOKE_STUB GenericPInvokeCalliHelper, GenericPInvokeCalliGenILStub, GenericPInvokeCalliStubWorker r4, 1
+
+// ------------------------------------------------------------------
+// VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg
+// Vararg PInvoke Stub when the method has a hidden return buffer arg
+//
+// in:
+// r1 = VASigCookie*
+// r12 = MethodDesc*
+//
+PINVOKE_STUB VarargPInvokeStub_RetBuffArg, VarargPInvokeGenILStub_RetBuffArg, VarargPInvokeStubWorker, r1, 0