diff options
author | gbalykov <g.balykov@samsung.com> | 2017-05-05 23:07:44 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-05-05 13:07:44 -0700 |
commit | 980c1204d68f54be77eb840cc3f2e4fe2df42a26 (patch) | |
tree | 1c9de18ed9660a833e156a8bf1be5ebb01d9c82e /src/vm/arm | |
parent | f32af15fd8c5ceae9ac10b5d2ef0eed9c66ca4e3 (diff) | |
download | coreclr-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.S | 18 | ||||
-rw-r--r-- | src/vm/arm/asmhelpers.asm | 21 | ||||
-rw-r--r-- | src/vm/arm/cgencpu.h | 55 | ||||
-rw-r--r-- | src/vm/arm/stubs.cpp | 7 |
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 && |