summaryrefslogtreecommitdiff
path: root/src/vm/arm64/stubs.cpp
diff options
context:
space:
mode:
authorRahul Kumar <rahku@microsoft.com>2016-05-05 15:53:07 -0700
committerRahul Kumar <rahku@microsoft.com>2016-05-09 10:26:12 -0700
commit559719a62aa7134da929d22f40c3c772e5d06348 (patch)
tree860b42836e8c58fa7bec845a92edbd0a907e1561 /src/vm/arm64/stubs.cpp
parentef04d7d2083c8e6fb8f3cf6294f2ae06928dae10 (diff)
downloadcoreclr-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.cpp258
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