summaryrefslogtreecommitdiff
path: root/src/vm/arm
diff options
context:
space:
mode:
authorManu <manu-silicon@users.noreply.github.com>2016-03-22 17:36:44 +0900
committerManu <manu-silicon@users.noreply.github.com>2016-03-23 08:42:09 +0900
commit7d69a10cff9272c84b3211fe366f7a280781f18b (patch)
treeeec1906051234db5a5795f5210c46f461fb33264 /src/vm/arm
parent21cbca6a3165ac9f3e2a3c1753ac6ee023aa9443 (diff)
downloadcoreclr-7d69a10cff9272c84b3211fe366f7a280781f18b.tar.gz
coreclr-7d69a10cff9272c84b3211fe366f7a280781f18b.tar.bz2
coreclr-7d69a10cff9272c84b3211fe366f7a280781f18b.zip
Implement GenericPInvokeCalliHelper on ARM
Add assemlby implementation for pinvoke stubs on ARM by porting the Windows ARM code to Linux ARM assembly.
Diffstat (limited to 'src/vm/arm')
-rw-r--r--src/vm/arm/pinvokestubs.S106
-rw-r--r--src/vm/arm/unixstubs.cpp15
2 files changed, 106 insertions, 15 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
diff --git a/src/vm/arm/unixstubs.cpp b/src/vm/arm/unixstubs.cpp
index 9fd4cbf985..fa0f204e11 100644
--- a/src/vm/arm/unixstubs.cpp
+++ b/src/vm/arm/unixstubs.cpp
@@ -11,26 +11,11 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
- void GenericPInvokeCalliHelper()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget)
{
PORTABILITY_ASSERT("Implement for PAL");
}
- void VarargPInvokeStub()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
- void VarargPInvokeStub_RetBuffArg()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
void RedirectForThreadAbort()
{
PORTABILITY_ASSERT("Implement for PAL");