14#define DEBUG_TYPE "orc"
19template <
typename ORCABI>
23 constexpr unsigned MaxDisp = ORCABI::StubToPointerMaxDisplacement;
25 ExecutorAddr LastStub = FirstStub + ((NumStubs - 1) * ORCABI::StubSize);
27 ExecutorAddr LastPointer = FirstPointer + ((NumStubs - 1) * ORCABI::StubSize);
29 if (FirstStub < FirstPointer) {
30 if (LastStub >= FirstPointer)
32 return (FirstPointer - FirstStub <= MaxDisp) &&
33 (LastPointer - LastStub <= MaxDisp);
36 if (LastPointer >= FirstStub)
39 return (FirstStub - FirstPointer <= MaxDisp) &&
40 (LastStub - LastPointer <= MaxDisp);
127 const unsigned ReentryFnAddrOffset = 0x110;
128 const unsigned ReentryCtxAddrOffset = 0x118;
130 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
131 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
133 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
140 unsigned NumTrampolines) {
144 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
152 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
155 Trampolines[3 *
I + 0] = 0xaa1e03f1;
156 Trampolines[3 *
I + 1] = 0x58000010 | (OffsetToPtr << 3);
157 Trampolines[3 *
I + 2] = 0xd63f0200;
162 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
163 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
185 "Pointer and stub size must match for algorithm below");
186 assert(stubAndPointerRangesOk<OrcAArch64>(
187 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
188 "PointersBlock is out of range");
190 PointersBlockTargetAddress - StubsBlockTargetAddress;
192 uint64_t PtrOffsetField = PtrDisplacement << 3;
194 for (
unsigned I = 0;
I < NumStubs; ++
I)
195 Stub[
I] = 0xd61f020058000010 | PtrOffsetField;
201 unsigned NumTrampolines) {
205 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
209 reinterpret_cast<uint64_t *
>(TrampolineBlockWorkingMem);
210 uint64_t CallIndirPCRel = 0xf1c40000000015ff;
213 Trampolines[
I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
217 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
218 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
241 "Pointer and stub size must match for algorithm below");
242 assert(stubAndPointerRangesOk<OrcX86_64_Base>(
243 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
244 "PointersBlock is out of range");
247 (PointersBlockTargetAddress - StubsBlockTargetAddress - 6) << 16;
248 for (
unsigned I = 0;
I < NumStubs; ++
I)
249 Stub[
I] = 0xF1C40000000025ff | PtrOffsetField;
258 dbgs() <<
"Writing resolver code to "
259 <<
formatv(
"{0:x16}", ResolverTargetAddress) <<
"\n";
262 const uint8_t ResolverCode[] = {
280 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
281 0x48, 0x0f, 0xae, 0x04, 0x24,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x48, 0x8b, 0x75, 0x08,
288 0x48, 0x83, 0xee, 0x06,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x48, 0x89, 0x45, 0x08,
296 0x48, 0x0f, 0xae, 0x0c, 0x24,
297 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
316 const unsigned ReentryFnAddrOffset = 0x3a;
317 const unsigned ReentryCtxAddrOffset = 0x28;
319 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
320 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
322 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
334 const uint8_t ResolverCode[] = {
352 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,
353 0x48, 0x0f, 0xae, 0x04, 0x24,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x48, 0x8B, 0x55, 0x08,
360 0x48, 0x83, 0xea, 0x06,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x48, 0x83, 0xEC, 0x20,
371 0x48, 0x83, 0xC4, 0x20,
373 0x48, 0x89, 0x45, 0x08,
374 0x48, 0x0f, 0xae, 0x0c, 0x24,
375 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,
394 const unsigned ReentryFnAddrOffset = 0x3a;
395 const unsigned ReentryCtxAddrOffset = 0x28;
397 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
398 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
400 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
409 assert((ReentryFnAddr.
getValue() >> 32) == 0 &&
"ReentryFnAddr out of range");
411 "ReentryCtxAddr out of range");
413 const uint8_t ResolverCode[] = {
425 0x81, 0xec, 0x18, 0x02, 0x00, 0x00,
426 0x0f, 0xae, 0x44, 0x24, 0x10,
429 0x89, 0x74, 0x24, 0x04,
430 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00,
432 0xb8, 0x00, 0x00, 0x00, 0x00,
435 0x0f, 0xae, 0x4c, 0x24, 0x10,
436 0x81, 0xc4, 0x18, 0x02, 0x00, 0x00,
448 const unsigned ReentryFnAddrOffset = 0x2a;
449 const unsigned ReentryCtxAddrOffset = 0x25;
451 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
452 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
454 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
461 unsigned NumTrampolines) {
462 assert((ResolverAddr.
getValue() >> 32) == 0 &&
"ResolverAddr out of range");
464 uint64_t CallRelImm = 0xF1C4C400000000e8;
465 uint64_t ResolverRel = ResolverAddr - TrampolineBlockTargetAddress - 5;
469 Trampolines[
I] = CallRelImm | (ResolverRel << 8);
477 "StubsBlockTargetAddress is out of range");
479 "PointersBlockTargetAddress is out of range");
501 assert(stubAndPointerRangesOk<OrcI386>(
502 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
503 "PointersBlock is out of range");
507 for (
unsigned I = 0;
I < NumStubs; ++
I, PtrAddr += 4)
508 Stub[
I] = 0xF1C40000000025ff | (PtrAddr << 16);
590 const unsigned ReentryFnAddrOffset = 0x7c;
591 const unsigned ReentryCtxAddrOffset = 0x6c;
592 const unsigned Offsett = 0xf8;
594 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
598 memcpy(ResolverWorkingMem + Offsett, &MoveVxT9,
sizeof(MoveVxT9));
601 0x3c040000 | (((ReentryCtxAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
602 uint32_t ReentryCtxADDiu = 0x24840000 | (ReentryCtxAddr.
getValue() & 0xFFFF);
603 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
604 sizeof(ReentryCtxLUi));
605 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset + 4, &ReentryCtxADDiu,
606 sizeof(ReentryCtxADDiu));
609 0x3c190000 | (((ReentryFnAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
611 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
612 sizeof(ReentryFnLUi));
613 memcpy(ResolverWorkingMem + ReentryFnAddrOffset + 4, &ReentryFnADDiu,
614 sizeof(ReentryFnADDiu));
620 unsigned NumTrampolines) {
622 assert((ResolverAddr.
getValue() >> 32) == 0 &&
"ResolverAddr out of range");
625 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
628 for (
unsigned I = 0;
I < NumTrampolines; ++
I) {
634 Trampolines[5 *
I + 0] = 0x03e0c025;
635 Trampolines[5 *
I + 1] = 0x3c190000 | (RHiAddr & 0xFFFF);
636 Trampolines[5 *
I + 2] = 0x27390000 | (ResolverAddr.
getValue() & 0xFFFF);
637 Trampolines[5 *
I + 3] = 0x0320f809;
638 Trampolines[5 *
I + 4] = 0x00000000;
643 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
644 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
646 "InitialPtrVal is out of range");
670 assert(stubAndPointerRangesOk<OrcMips32_Base>(
671 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
672 "PointersBlock is out of range");
678 for (
unsigned I = 0;
I < NumStubs; ++
I) {
679 uint32_t HiAddr = ((PtrAddr + 0x8000) >> 16);
680 Stub[4 *
I + 0] = 0x3c190000 | (HiAddr & 0xFFFF);
681 Stub[4 *
I + 1] = 0x8f390000 | (PtrAddr & 0xFFFF);
682 Stub[4 *
I + 2] = 0x03200008;
683 Stub[4 *
I + 3] = 0x00000000;
774 const unsigned ReentryFnAddrOffset = 0x8c;
775 const unsigned ReentryCtxAddrOffset = 0x6c;
777 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
781 (((ReentryCtxAddr.
getValue() + 0x800080008000) >> 48) & 0xFFFF);
783 0x64840000 | (((ReentryCtxAddr.
getValue() + 0x80008000) >> 32) & 0xFFFF);
784 uint32_t ReentryCtxDSLL = 0x00042438;
786 0x64840000 | ((((ReentryCtxAddr.
getValue() + 0x8000) >> 16) & 0xFFFF));
787 uint32_t ReentryCtxDSLL2 = 0x00042438;
789 0x64840000 | (ReentryCtxAddr.
getValue() & 0xFFFF);
791 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxLUi,
792 sizeof(ReentryCtxLUi));
793 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 4), &ReentryCtxDADDiu,
794 sizeof(ReentryCtxDADDiu));
795 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 8), &ReentryCtxDSLL,
796 sizeof(ReentryCtxDSLL));
797 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 12), &ReentryCtxDADDiu2,
798 sizeof(ReentryCtxDADDiu2));
799 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 16), &ReentryCtxDSLL2,
800 sizeof(ReentryCtxDSLL2));
801 memcpy(ResolverWorkingMem + (ReentryCtxAddrOffset + 20), &ReentryCtxDADDiu3,
802 sizeof(ReentryCtxDADDiu3));
806 (((ReentryFnAddr.
getValue() + 0x800080008000) >> 48) & 0xFFFF);
809 0x67390000 | (((ReentryFnAddr.
getValue() + 0x80008000) >> 32) & 0xFFFF);
811 uint32_t ReentryFnDSLL = 0x0019cc38;
814 0x67390000 | (((ReentryFnAddr.
getValue() + 0x8000) >> 16) & 0xFFFF);
816 uint32_t ReentryFnDSLL2 = 0x0019cc38;
818 uint32_t ReentryFnDADDiu3 = 0x67390000 | (ReentryFnAddr.
getValue() & 0xFFFF);
820 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnLUi,
821 sizeof(ReentryFnLUi));
822 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 4), &ReentryFnDADDiu,
823 sizeof(ReentryFnDADDiu));
824 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 8), &ReentryFnDSLL,
825 sizeof(ReentryFnDSLL));
826 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 12), &ReentryFnDADDiu2,
827 sizeof(ReentryFnDADDiu2));
828 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 16), &ReentryFnDSLL2,
829 sizeof(ReentryFnDSLL2));
830 memcpy(ResolverWorkingMem + (ReentryFnAddrOffset + 20), &ReentryFnDADDiu3,
831 sizeof(ReentryFnDADDiu3));
837 unsigned NumTrampolines) {
840 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
846 for (
unsigned I = 0;
I < NumTrampolines; ++
I) {
847 Trampolines[10 *
I + 0] = 0x03e0c025;
848 Trampolines[10 *
I + 1] = 0x3c190000 | (HeighestAddr & 0xFFFF);
849 Trampolines[10 *
I + 2] = 0x67390000 | (HeigherAddr & 0xFFFF);
850 Trampolines[10 *
I + 3] = 0x0019cc38;
851 Trampolines[10 *
I + 4] = 0x67390000 | (HiAddr & 0xFFFF);
852 Trampolines[10 *
I + 5] = 0x0019cc38;
853 Trampolines[10 *
I + 6] = 0x67390000 | (ResolverAddr.
getValue() &
855 Trampolines[10 *
I + 7] = 0x0320f809;
856 Trampolines[10 *
I + 8] = 0x00000000;
857 Trampolines[10 *
I + 9] = 0x00000000;
893 assert(stubAndPointerRangesOk<OrcMips64>(
894 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
895 "PointersBlock is out of range");
901 for (
unsigned I = 0;
I < NumStubs; ++
I, PtrAddr += 8) {
902 uint64_t HeighestAddr = ((PtrAddr + 0x800080008000) >> 48);
903 uint64_t HeigherAddr = ((PtrAddr + 0x80008000) >> 32);
904 uint64_t HiAddr = ((PtrAddr + 0x8000) >> 16);
905 Stub[8 *
I + 0] = 0x3c190000 | (HeighestAddr & 0xFFFF);
906 Stub[8 *
I + 1] = 0x67390000 | (HeigherAddr & 0xFFFF);
907 Stub[8 *
I + 2] = 0x0019cc38;
908 Stub[8 *
I + 3] = 0x67390000 | (HiAddr & 0xFFFF);
909 Stub[8 *
I + 4] = 0x0019cc38;
910 Stub[8 *
I + 5] = 0xdf390000 | (PtrAddr & 0xFFFF);
911 Stub[8 *
I + 6] = 0x03200008;
912 Stub[8 *
I + 7] = 0x00000000;
1006 const unsigned ReentryCtxAddrOffset = 0x138;
1007 const unsigned ReentryFnAddrOffset = 0x140;
1009 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
1010 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1012 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1019 unsigned NumTrampolines) {
1023 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1027 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
1029 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xFFFFF000;
1030 uint32_t Lo12 = OffsetToPtr - Hi20;
1031 Trampolines[4 *
I + 0] = 0x00000297 | Hi20;
1032 Trampolines[4 *
I + 1] =
1033 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1034 Trampolines[4 *
I + 2] = 0x00028367;
1035 Trampolines[4 *
I + 3] = 0xdeadface;
1040 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
1041 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
1066 assert(stubAndPointerRangesOk<OrcRiscv64>(
1067 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1068 "PointersBlock is out of range");
1072 for (
unsigned I = 0;
I < NumStubs; ++
I) {
1074 PointersBlockTargetAddress - StubsBlockTargetAddress;
1075 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xFFFFF000;
1076 uint32_t Lo12 = PtrDisplacement - Hi20;
1077 Stub[4 *
I + 0] = 0x00000297 | Hi20;
1078 Stub[4 *
I + 1] = 0x0002b283 | ((Lo12 & 0xFFF) << 20);
1079 Stub[4 *
I + 2] = 0x00028067;
1080 Stub[4 *
I + 3] = 0xfeedbeef;
1082 StubsBlockTargetAddress +=
StubSize;
1092 dbgs() <<
"Writing resolver code to "
1093 <<
formatv(
"{0:x16}", ResolverTargetAddress) <<
"\n";
1149 const unsigned ReentryCtxAddrOffset = 0xb8;
1150 const unsigned ReentryFnAddrOffset = 0xc0;
1152 memcpy(ResolverWorkingMem, ResolverCode,
sizeof(ResolverCode));
1153 memcpy(ResolverWorkingMem + ReentryFnAddrOffset, &ReentryFnAddr,
1155 memcpy(ResolverWorkingMem + ReentryCtxAddrOffset, &ReentryCtxAddr,
1162 unsigned NumTrampolines) {
1165 dbgs() <<
"Writing trampoline code to "
1166 <<
formatv(
"{0:x16}", TrampolineBlockTargetAddress) <<
"\n";
1171 memcpy(TrampolineBlockWorkingMem + OffsetToPtr, &ResolverAddr,
1175 reinterpret_cast<uint32_t *
>(TrampolineBlockWorkingMem);
1177 uint32_t Hi20 = (OffsetToPtr + 0x800) & 0xfffff000;
1178 uint32_t Lo12 = OffsetToPtr - Hi20;
1179 Trampolines[4 *
I + 0] =
1181 (((Hi20 >> 12) & 0xfffff) << 5);
1182 Trampolines[4 *
I + 1] =
1183 0x28c0018c | ((Lo12 & 0xfff) << 10);
1184 Trampolines[4 *
I + 2] = 0x4c00018d;
1185 Trampolines[4 *
I + 3] = 0x0;
1190 char *StubsBlockWorkingMem,
ExecutorAddr StubsBlockTargetAddress,
1191 ExecutorAddr PointersBlockTargetAddress,
unsigned NumStubs) {
1214 dbgs() <<
"Writing stubs code to "
1215 <<
formatv(
"{0:x16}", StubsBlockTargetAddress) <<
"\n";
1217 assert(stubAndPointerRangesOk<OrcLoongArch64>(
1218 StubsBlockTargetAddress, PointersBlockTargetAddress, NumStubs) &&
1219 "PointersBlock is out of range");
1223 for (
unsigned I = 0;
I < NumStubs; ++
I) {
1225 PointersBlockTargetAddress - StubsBlockTargetAddress;
1226 uint32_t Hi20 = (PtrDisplacement + 0x800) & 0xfffff000;
1227 uint32_t Lo12 = PtrDisplacement - Hi20;
1228 Stub[4 *
I + 0] = 0x1c00000c | (((Hi20 >> 12) & 0xfffff)
1231 0x28c0018c | ((Lo12 & 0xfff) << 10);
1232 Stub[4 *
I + 2] = 0x4c000180;
1233 Stub[4 *
I + 3] = 0x0;
1235 StubsBlockTargetAddress +=
StubSize;
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
static bool stubAndPointerRangesOk(ExecutorAddr StubBlockAddr, ExecutorAddr PointerBlockAddr, unsigned NumStubs)
Provides a library for accessing information about this process and other processes on the operating ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represents an address in the executor process.
uint64_t getValue() const
static constexpr unsigned PointerSize
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr RentryCtxAddr)
Write the resolver code into the given memory.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned TrampolineSize
static constexpr unsigned StubSize
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned MinStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static constexpr unsigned TrampolineSize
static constexpr unsigned StubSize
static constexpr unsigned PointerSize
static constexpr unsigned TrampolineSize
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static void writeResolverCode(char *ResolverBlockWorkingMem, ExecutorAddr ResolverBlockTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr, bool isBigEndian)
Write the resolver code into the given memory.
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static constexpr unsigned StubSize
static constexpr unsigned TrampolineSize
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverFnAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned PointerSize
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static constexpr unsigned PointerSize
static constexpr unsigned StubSize
static void writeIndirectStubsBlock(char *StubsBlockWorkingMem, ExecutorAddr StubsBlockTargetAddress, ExecutorAddr PointersBlockTargetAddress, unsigned NumStubs)
Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
static void writeTrampolines(char *TrampolineBlockWorkingMem, ExecutorAddr TrampolineBlockTargetAddress, ExecutorAddr ResolverAddr, unsigned NumTrampolines)
Write the requested number of trampolines into the given memory, which must be big enough to hold 1 p...
static constexpr unsigned TrampolineSize
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
static void writeResolverCode(char *ResolverWorkingMem, ExecutorAddr ResolverTargetAddress, ExecutorAddr ReentryFnAddr, ExecutorAddr ReentryCtxAddr)
Write the resolver code into the given memory.
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.