diff options
author | Rahul Kumar <rahku@microsoft.com> | 2016-05-05 15:53:07 -0700 |
---|---|---|
committer | Rahul Kumar <rahku@microsoft.com> | 2016-05-09 10:26:12 -0700 |
commit | 559719a62aa7134da929d22f40c3c772e5d06348 (patch) | |
tree | 860b42836e8c58fa7bec845a92edbd0a907e1561 /src/vm/arm64/stubs.cpp | |
parent | ef04d7d2083c8e6fb8f3cf6294f2ae06928dae10 (diff) | |
download | coreclr-559719a62aa7134da929d22f40c3c772e5d06348.tar.gz coreclr-559719a62aa7134da929d22f40c3c772e5d06348.tar.bz2 coreclr-559719a62aa7134da929d22f40c3c772e5d06348.zip |
[Arm64] Helpers for ReadyToRun
Diffstat (limited to 'src/vm/arm64/stubs.cpp')
-rw-r--r-- | src/vm/arm64/stubs.cpp | 258 |
1 files changed, 244 insertions, 14 deletions
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp index e7700f5389..426093b6c8 100644 --- a/src/vm/arm64/stubs.cpp +++ b/src/vm/arm64/stubs.cpp @@ -1709,53 +1709,283 @@ void StubLinkerCPU::EmitUnboxMethodStub(MethodDesc *pMD) EmitCallManagedMethod(pMD, TRUE /* tail call */); } -#endif // CROSSGEN_COMPILE +#ifdef FEATURE_READYTORUN -#endif // #ifndef DACCESS_COMPILE +// +// Allocation of dynamic helpers +// + +#define DYNAMIC_HELPER_ALIGNMENT sizeof(TADDR) + +#define BEGIN_DYNAMIC_HELPER_EMIT(size) \ + SIZE_T cb = size; \ + SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \ + BYTE * pStart = (BYTE *)(void *)pAllocator->GetDynamicHelpersHeap()->AllocAlignedMem(cbAligned, DYNAMIC_HELPER_ALIGNMENT); \ + BYTE * p = pStart; + +#define END_DYNAMIC_HELPER_EMIT() \ + _ASSERTE(pStart + cb == p); \ + while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\ + ClrFlushInstructionCache(pStart, cbAligned); \ + return (PCODE)pStart + +// Uses x8 as scratch register to store address of data label +// After load x8 is increment to point to next data +// only accepts positive offsets +static void LoadRegPair(BYTE* p, int reg1, int reg2, UINT32 offset) +{ + LIMITED_METHOD_CONTRACT; + + // adr x8, <label> + *(DWORD*)(p + 0) = 0x10000008 | ((offset >> 2) << 5); + // ldp reg1, reg2, [x8], #16 ; postindex & wback + *(DWORD*)(p + 4) = 0xa8c10100 | (reg2 << 10) | reg1; +} -#ifdef FEATURE_READYTORUN PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(32); + + // adr x8, <label> + // ldp x0, x12, [x8] + LoadRegPair(p, 0, 12, 16); + p += 8; + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + + // padding to make 8 byte aligned + *(DWORD*)p = 0xBADC0DF0; p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + // target + *(PCODE*)p = target; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateHelperWithArg(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(32); + + // adr x8, <label> + // ldp x1, x12, [x8] + LoadRegPair(p, 1, 12, 16); + p += 8; + + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + + // padding to make 8 byte aligned + *(DWORD*)p = 0xBADC0DF0; p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + // target + *(PCODE*)p = target; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateHelper(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(40); + + // adr x8, <label> + // ldp x0, x1, [x8] ; wback + LoadRegPair(p, 0, 1, 16); + p += 8; + + // ldr x12, [x8] + *(DWORD*)p = 0xf940010c; + p += 4; + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + // label: + // arg + *(TADDR*)p = arg; + p += 8; + // arg2 + *(TADDR*)p = arg2; + p += 8; + // target + *(TADDR*)p = target; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateHelperArgMove(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(32); + + // mov x1, x0 + *(DWORD*)p = 0x91000001; + p += 4; + + // adr x8, <label> + // ldp x0, x12, [x8] + LoadRegPair(p, 0, 12, 12); + p += 8; + + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + // target + *(TADDR*)p = target; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateReturn(LoaderAllocator * pAllocator) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(4); + + // br lr + *(DWORD*)p = 0xd61f03c0; + p += 4; + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateReturnConst(LoaderAllocator * pAllocator, TADDR arg) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(16); + + // ldr x0, <lable> + *(DWORD*)p = 0x58000040; + p += 4; + + // br lr + *(DWORD*)p = 0xd61f03c0; + p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateReturnIndirConst(LoaderAllocator * pAllocator, TADDR arg, INT8 offset) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(24); + + // ldr x0, <label> + *(DWORD*)p = 0x58000080; + p += 4; + + // ldr x0, [x0] + *(DWORD*)p = 0xf9400000; + p += 4; + + // add x0, x0, offset + *(DWORD*)p = 0x91000000 | (offset << 10); + p += 4; + + // br lr + *(DWORD*)p = 0xd61f03c0; + p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, PCODE target) { - UNREACHABLE(); + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(32); + + // adr x8, <label> + // ldp x2, x12, [x8] + LoadRegPair(p, 2, 12, 16); + p += 8; + + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + + // padding to make 8 byte aligned + *(DWORD*)p = 0xBADC0DF0; p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + + // target + *(TADDR*)p = target; + p += 8; + END_DYNAMIC_HELPER_EMIT(); } PCODE DynamicHelpers::CreateHelperWithTwoArgs(LoaderAllocator * pAllocator, TADDR arg, TADDR arg2, PCODE target) { - UNREACHABLE(); -} -#endif + STANDARD_VM_CONTRACT; + + BEGIN_DYNAMIC_HELPER_EMIT(40); + + // adr x8, <label> + // ldp x2, x3, [x8]; wback + LoadRegPair(p, 2, 3, 16); + p += 8; + + // ldr x12, [x8] + *(DWORD*)p = 0xf940010c; + p += 4; + + // br x12 + *(DWORD*)p = 0xd61f0180; + p += 4; + + // label: + // arg + *(TADDR*)p = arg; + p += 8; + // arg2 + *(TADDR*)p = arg2; + p += 8; + // target + *(TADDR*)p = target; + p += 8; + END_DYNAMIC_HELPER_EMIT(); +} +#endif // FEATURE_READYTORUN + +#endif // CROSSGEN_COMPILE + +#endif // #ifndef DACCESS_COMPILE |