summaryrefslogtreecommitdiff
path: root/src/vm/arm
diff options
context:
space:
mode:
authorgbalykov <g.balykov@samsung.com>2017-05-05 23:07:44 +0300
committerJan Kotas <jkotas@microsoft.com>2017-05-05 13:07:44 -0700
commit980c1204d68f54be77eb840cc3f2e4fe2df42a26 (patch)
tree1c9de18ed9660a833e156a8bf1be5ebb01d9c82e /src/vm/arm
parentf32af15fd8c5ceae9ac10b5d2ef0eed9c66ca4e3 (diff)
downloadcoreclr-980c1204d68f54be77eb840cc3f2e4fe2df42a26.tar.gz
coreclr-980c1204d68f54be77eb840cc3f2e4fe2df42a26.tar.bz2
coreclr-980c1204d68f54be77eb840cc3f2e4fe2df42a26.zip
Add compact entry points for ARM (#11109)
Diffstat (limited to 'src/vm/arm')
-rw-r--r--src/vm/arm/asmhelpers.S18
-rw-r--r--src/vm/arm/asmhelpers.asm21
-rw-r--r--src/vm/arm/cgencpu.h55
-rw-r--r--src/vm/arm/stubs.cpp7
4 files changed, 100 insertions, 1 deletions
diff --git a/src/vm/arm/asmhelpers.S b/src/vm/arm/asmhelpers.S
index 04d7527180..36933f5ea6 100644
--- a/src/vm/arm/asmhelpers.S
+++ b/src/vm/arm/asmhelpers.S
@@ -509,6 +509,24 @@ LOCAL_LABEL(UM2MThunk_WrapperHelper_ArgumentsSetup):
NESTED_END ThePreStub, _TEXT
// ------------------------------------------------------------------
+ NESTED_ENTRY ThePreStubCompactARM, _TEXT, NoHandler
+
+ // r12 - address of compact entry point + PC_REG_RELATIVE_OFFSET
+
+ PROLOG_WITH_TRANSITION_BLOCK
+
+ mov r0, r12
+
+ bl C_FUNC(PreStubGetMethodDescForCompactEntryPoint)
+
+ mov r12, r0 // pMethodDesc
+
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ b C_FUNC(ThePreStub)
+
+ NESTED_END ThePreStubCompactARM, _TEXT
+// ------------------------------------------------------------------
// This method does nothing. It's just a fixed function for the debugger to put a breakpoint on.
LEAF_ENTRY ThePreStubPatch, _TEXT
nop
diff --git a/src/vm/arm/asmhelpers.asm b/src/vm/arm/asmhelpers.asm
index 542bdc65cc..e5fd41a513 100644
--- a/src/vm/arm/asmhelpers.asm
+++ b/src/vm/arm/asmhelpers.asm
@@ -24,6 +24,7 @@
IMPORT UMThunkStubRareDisableWorker
IMPORT UM2MDoADCallBack
IMPORT PreStubWorker
+ IMPORT PreStubGetMethodDescForCompactEntryPoint
IMPORT NDirectImportWorker
IMPORT ObjIsInstanceOfNoGC
IMPORT ArrayStoreCheck
@@ -571,6 +572,26 @@ UM2MThunk_WrapperHelper_ArgumentsSetup
NESTED_END
; ------------------------------------------------------------------
+
+ NESTED_ENTRY ThePreStubCompactARM
+
+ ; r12 - address of compact entry point + PC_REG_RELATIVE_OFFSET
+
+ PROLOG_WITH_TRANSITION_BLOCK
+
+ mov r0, r12
+
+ bl PreStubGetMethodDescForCompactEntryPoint
+
+ mov r12, r0 ; pMethodDesc
+
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ b ThePreStub
+
+ NESTED_END
+
+; ------------------------------------------------------------------
; This method does nothing. It's just a fixed function for the debugger to put a breakpoint on.
LEAF_ENTRY ThePreStubPatch
nop
diff --git a/src/vm/arm/cgencpu.h b/src/vm/arm/cgencpu.h
index 34af8187b2..181d5f10eb 100644
--- a/src/vm/arm/cgencpu.h
+++ b/src/vm/arm/cgencpu.h
@@ -57,7 +57,7 @@ EXTERN_C void checkStack(void);
#define JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a jump instruction
#define BACK_TO_BACK_JUMP_ALLOCATE_SIZE 8 // # bytes to allocate for a back to back jump instruction
-//#define HAS_COMPACT_ENTRYPOINTS 1
+#define HAS_COMPACT_ENTRYPOINTS 1
#define HAS_NDIRECT_IMPORT_PRECODE 1
@@ -90,6 +90,12 @@ EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
// this is the offset by which it should be decremented to arrive at the callsite.
#define STACKWALK_CONTROLPC_ADJUST_OFFSET 2
+// Max offset for unconditional thumb branch
+#define MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB 2048
+
+// Offset of pc register
+#define PC_REG_RELATIVE_OFFSET 4
+
//=======================================================================
// IMPORTANT: This value is used to figure out how much to allocate
// for a fixed array of FieldMarshaler's. That means it must be at least
@@ -236,6 +242,53 @@ void emitCOMStubCall (ComCallMethodDesc *pCOMMethod, PCODE target);
#endif // FEATURE_COMINTEROP
//------------------------------------------------------------------------
+inline void emitUnconditionalBranchThumb(LPBYTE pBuffer, int16_t offset)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ uint16_t *pInstr = (uint16_t *) pBuffer;
+
+ // offset from -2KB to +2KB
+ _ASSERTE (offset >= - MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB && offset < MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB);
+
+ if (offset >= 0)
+ {
+ offset = offset >> 1;
+ }
+ else
+ {
+ offset = ((MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB + offset) >> 1) | 0x400;
+ }
+
+ *pInstr = 0xE000 | offset;
+}
+
+//------------------------------------------------------------------------
+inline int16_t decodeUnconditionalBranchThumb(LPBYTE pBuffer)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ uint16_t *pInstr = (uint16_t *) pBuffer;
+
+ int16_t offset = (~0xE000) & (*pInstr);
+
+ if ((offset & 0x400) == 0)
+ {
+ offset = offset << 1;
+ }
+ else
+ {
+ offset = (~0x400) & offset;
+ offset = (offset << 1) - MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB;
+ }
+
+ // offset from -2KB to +2KB
+ _ASSERTE (offset >= - MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB && offset < MAX_OFFSET_UNCONDITIONAL_BRANCH_THUMB);
+
+ return offset;
+}
+
+//------------------------------------------------------------------------
inline void emitJump(LPBYTE pBuffer, LPVOID target)
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp
index f1ba278ada..3088761f0b 100644
--- a/src/vm/arm/stubs.cpp
+++ b/src/vm/arm/stubs.cpp
@@ -1333,6 +1333,13 @@ BOOL DoesSlotCallPrestub(PCODE pCode)
{
PTR_WORD pInstr = dac_cast<PTR_WORD>(PCODEToPINSTR(pCode));
+#ifdef HAS_COMPACT_ENTRYPOINTS
+ if (MethodDescChunk::GetMethodDescFromCompactEntryPoint(pCode, TRUE) != NULL)
+ {
+ return TRUE;
+ }
+#endif // HAS_COMPACT_ENTRYPOINTS
+
// FixupPrecode
if (pInstr[0] == 0x46fc && // // mov r12, pc
pInstr[1] == 0xf8df &&