[llvm] r341934 - [MIPS] ORC JIT support
Petar Jovanovic via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 11 06:10:04 PDT 2018
Author: petarj
Date: Tue Sep 11 06:10:04 2018
New Revision: 341934
URL: http://llvm.org/viewvc/llvm-project?rev=341934&view=rev
Log:
[MIPS] ORC JIT support
This patch adds support for ORC JIT for mips/mips64 architecture.
In common code $static is changed to __ORCstatic because on MIPS
architecture "$" is a reserved character.
Patch by Luka Ercegovcevic
Differential Revision: https://reviews.llvm.org/D49665
Modified:
llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp
llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
llvm/trunk/test/ExecutionEngine/OrcLazy/lit.local.cfg
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcABISupport.h?rev=341934&r1=341933&r2=341934&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcABISupport.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcABISupport.h Tue Sep 11 06:10:04 2018
@@ -238,7 +238,78 @@ public:
unsigned MinStubs, void *InitialPtrVal);
};
-} // end namespace orc
-} // end namespace llvm
+// @brief Mips32 support.
+//
+// Mips32 supports lazy JITing.
+class OrcMips32_Base {
+public:
+ static const unsigned PointerSize = 4;
+ static const unsigned TrampolineSize = 20;
+ static const unsigned ResolverCodeSize = 0xfc;
+ using IndirectStubsInfo = GenericIndirectStubsInfo<16>;
+
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
+ /// @brief Write the requsted number of trampolines into the given memory,
+ /// which must be big enough to hold 1 pointer, plus NumTrampolines
+ /// trampolines.
+ static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
+ /// @brief Write the resolver code into the given memory. The user is be
+ /// responsible for allocating the memory and setting permissions.
+ static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr, bool isBigEndian);
+ /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
+ /// the nearest page size.
+ ///
+ /// E.g. Asking for 4 stubs on Mips32, where stubs are 8-bytes, with 4k
+ /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
+ /// will return a block of 1024 (2-pages worth).
+ static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+};
+
+
+class OrcMips32Le : public OrcMips32_Base {
+public:
+ static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
+ { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, false); }
+};
+
+class OrcMips32Be : public OrcMips32_Base {
+public:
+ static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
+ { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, true); }
+};
+
+// @brief Mips64 support.
+//
+// Mips64 supports lazy JITing.
+class OrcMips64 {
+public:
+ static const unsigned PointerSize = 8;
+ static const unsigned TrampolineSize = 40;
+ static const unsigned ResolverCodeSize = 0x11C;
+
+ using IndirectStubsInfo = GenericIndirectStubsInfo<32>;
+ using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
+ void *TrampolineId);
+ /// @brief Write the resolver code into the given memory. The user is be
+ /// responsible for allocating the memory and setting permissions.
+ static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr);
+
+ /// @brief Write the requsted number of trampolines into the given memory,
+ /// which must be big enough to hold 1 pointer, plus NumTrampolines
+ /// trampolines.
+ static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
+
+ /// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
+ /// the nearest page size.
+ ///
+ /// E.g. Asking for 4 stubs on Mips64, where stubs are 8-bytes, with 4k
+ /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
+ /// will return a block of 1024 (2-pages worth).
+ static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+};
+
+ } // end namespace orc
+ } // end namespace llvm
#endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
Modified: llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp?rev=341934&r1=341933&r2=341934&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/IndirectionUtils.cpp Tue Sep 11 06:10:04 2018
@@ -123,6 +123,21 @@ createLocalCompileCallbackManager(const
return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
}
+ case Triple::mips: {
+ typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Be> CCMgrT;
+ return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
+ }
+ case Triple::mipsel: {
+ typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Le> CCMgrT;
+ return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
+ }
+
+ case Triple::mips64:
+ case Triple::mips64el: {
+ typedef orc::LocalJITCompileCallbackManager<orc::OrcMips64> CCMgrT;
+ return llvm::make_unique<CCMgrT>(ES, ErrorHandlerAddress);
+ }
+
case Triple::x86_64: {
if ( T.getOS() == Triple::OSType::Win32 ) {
typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT;
@@ -157,6 +172,25 @@ createLocalIndirectStubsManagerBuilder(c
orc::LocalIndirectStubsManager<orc::OrcI386>>();
};
+ case Triple::mips:
+ return [](){
+ return llvm::make_unique<
+ orc::LocalIndirectStubsManager<orc::OrcMips32Be>>();
+ };
+
+ case Triple::mipsel:
+ return [](){
+ return llvm::make_unique<
+ orc::LocalIndirectStubsManager<orc::OrcMips32Le>>();
+ };
+
+ case Triple::mips64:
+ case Triple::mips64el:
+ return [](){
+ return llvm::make_unique<
+ orc::LocalIndirectStubsManager<orc::OrcMips64>>();
+ };
+
case Triple::x86_64:
if (T.getOS() == Triple::OSType::Win32) {
return [](){
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp?rev=341934&r1=341933&r2=341934&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcABISupport.cpp Tue Sep 11 06:10:04 2018
@@ -537,5 +537,460 @@ Error OrcI386::emitIndirectStubsBlock(In
return Error::success();
}
+void OrcMips32_Base::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
+ void *CallbackMgr, bool isBigEndian) {
+
+ const uint32_t ResolverCode[] = {
+ // resolver_entry:
+ 0x27bdff98, // 0x00: addiu $sp,$sp,-104
+ 0xafa20000, // 0x04: sw $v0,0($sp)
+ 0xafa30004, // 0x08: sw $v1,4($sp)
+ 0xafa40008, // 0x0c: sw $a0,8($sp)
+ 0xafa5000c, // 0x10: sw $a1,12($sp)
+ 0xafa60010, // 0x14: sw $a2,16($sp)
+ 0xafa70014, // 0x18: sw $a3,20($sp)
+ 0xafb00018, // 0x1c: sw $s0,24($sp)
+ 0xafb1001c, // 0x20: sw $s1,28($sp)
+ 0xafb20020, // 0x24: sw $s2,32($sp)
+ 0xafb30024, // 0x28: sw $s3,36($sp)
+ 0xafb40028, // 0x2c: sw $s4,40($sp)
+ 0xafb5002c, // 0x30: sw $s5,44($sp)
+ 0xafb60030, // 0x34: sw $s6,48($sp)
+ 0xafb70034, // 0x38: sw $s7,52($sp)
+ 0xafa80038, // 0x3c: sw $t0,56($sp)
+ 0xafa9003c, // 0x40: sw $t1,60($sp)
+ 0xafaa0040, // 0x44: sw $t2,64($sp)
+ 0xafab0044, // 0x48: sw $t3,68($sp)
+ 0xafac0048, // 0x4c: sw $t4,72($sp)
+ 0xafad004c, // 0x50: sw $t5,76($sp)
+ 0xafae0050, // 0x54: sw $t6,80($sp)
+ 0xafaf0054, // 0x58: sw $t7,84($sp)
+ 0xafb80058, // 0x5c: sw $t8,88($sp)
+ 0xafb9005c, // 0x60: sw $t9,92($sp)
+ 0xafbe0060, // 0x64: sw $fp,96($sp)
+ 0xafbf0064, // 0x68: sw $ra,100($sp)
+
+ // Callback manager addr.
+ 0x00000000, // 0x6c: lui $a0,callbackmgr
+ 0x00000000, // 0x70: addiu $a0,$a0,callbackmgr
+
+ 0x03e02825, // 0x74: move $a1, $ra
+ 0x24a5ffec, // 0x78: addiu $a1,$a1,-20
+
+ // JIT re-entry fn addr:
+ 0x00000000, // 0x7c: lui $t9,reentry
+ 0x00000000, // 0x80: addiu $t9,$t9,reentry
+
+ 0x0320f809, // 0x84: jalr $t9
+ 0x00000000, // 0x88: nop
+ 0x8fbf0064, // 0x8c: lw $ra,100($sp)
+ 0x8fbe0060, // 0x90: lw $fp,96($sp)
+ 0x8fb9005c, // 0x94: lw $t9,92($sp)
+ 0x8fb80058, // 0x98: lw $t8,88($sp)
+ 0x8faf0054, // 0x9c: lw $t7,84($sp)
+ 0x8fae0050, // 0xa0: lw $t6,80($sp)
+ 0x8fad004c, // 0xa4: lw $t5,76($sp)
+ 0x8fac0048, // 0xa8: lw $t4,72($sp)
+ 0x8fab0044, // 0xac: lw $t3,68($sp)
+ 0x8faa0040, // 0xb0: lw $t2,64($sp)
+ 0x8fa9003c, // 0xb4: lw $t1,60($sp)
+ 0x8fa80038, // 0xb8: lw $t0,56($sp)
+ 0x8fb70034, // 0xbc: lw $s7,52($sp)
+ 0x8fb60030, // 0xc0: lw $s6,48($sp)
+ 0x8fb5002c, // 0xc4: lw $s5,44($sp)
+ 0x8fb40028, // 0xc8: lw $s4,40($sp)
+ 0x8fb30024, // 0xcc: lw $s3,36($sp)
+ 0x8fb20020, // 0xd0: lw $s2,32($sp)
+ 0x8fb1001c, // 0xd4: lw $s1,28($sp)
+ 0x8fb00018, // 0xd8: lw $s0,24($sp)
+ 0x8fa70014, // 0xdc: lw $a3,20($sp)
+ 0x8fa70014, // 0xe0: lw $a3,20($sp)
+ 0x8fa60010, // 0xe4: lw $a2,16($sp)
+ 0x8fa5000c, // 0xe8: lw $a1,12($sp)
+ 0x8fa40008, // 0xec: lw $a0,8($sp)
+ 0x27bd0068, // 0xf4: addiu $sp,$sp,104
+ 0x0300f825, // 0xf8: move $ra, $t8
+ 0x00000000 // 0xfc: jr $v0/v1
+ };
+
+
+ const unsigned ReentryFnAddrOffset = 0x7c; // JIT re-entry fn addr lui
+ const unsigned CallbackMgrAddrOffset = 0x6c; // Callback manager addr lui
+ const unsigned offsett = 0xfc;
+
+ memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
+
+ //Depending on endian return value will be in v0 or v1.
+ uint32_t JumpV0 = 0x00400008;
+ uint32_t JumpV1 = 0x00600008;
+
+ if(isBigEndian == true)
+ memcpy(ResolverMem + offsett, &JumpV1,
+ sizeof(JumpV1));
+ else
+ memcpy(ResolverMem + offsett, &JumpV0,
+ sizeof(JumpV0));
+
+ uint64_t CallMgrAddr = reinterpret_cast<uint64_t>(CallbackMgr);
+ uint32_t CallMgrLUi = 0x3c040000 | (((CallMgrAddr + 0x8000) >> 16) & 0xFFFF);
+ uint32_t CallMgrADDiu = 0x24840000 | ((CallMgrAddr) & 0xFFFF);
+ memcpy(ResolverMem + CallbackMgrAddrOffset, &CallMgrLUi,
+ sizeof(CallMgrLUi));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 4), &CallMgrADDiu,
+ sizeof(CallMgrADDiu));
+
+ uint64_t ReentryAddr = reinterpret_cast<uint64_t>(ReentryFn);
+ uint32_t ReentryLUi = 0x3c190000 | (((ReentryAddr + 0x8000) >> 16) & 0xFFFF);
+ uint32_t ReentryADDiu = 0x27390000 | ((ReentryAddr) & 0xFFFF);
+ memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryLUi,
+ sizeof(ReentryLUi));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 4), &ReentryADDiu,
+ sizeof(ReentryADDiu));
+}
+
+void OrcMips32_Base::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ unsigned NumTrampolines) {
+
+ uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem);
+ uint64_t ResolveAddr = reinterpret_cast<uint64_t>(ResolverAddr);
+ uint32_t RHiAddr = ((ResolveAddr + 0x8000) >> 16);
+
+ for (unsigned I = 0; I < NumTrampolines; ++I) {
+ Trampolines[5 * I + 0] = 0x03e0c025; // move $t8,$ra
+ Trampolines[5 * I + 1] = 0x3c190000 | (RHiAddr & 0xFFFF); // lui $t9,resolveAddr
+ Trampolines[5 * I + 2] = 0x27390000 | (ResolveAddr & 0xFFFF); // addiu $t9,$t9,resolveAddr
+ Trampolines[5 * I + 3] = 0x0320f809; // jalr $t9
+ Trampolines[5 * I + 4] = 0x00000000; // nop
+ }
+
+}
+
+Error OrcMips32_Base::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
+ unsigned MinStubs,
+ void *InitialPtrVal) {
+ // Stub format is:
+ //
+ // .section __orc_stubs
+ // stub1:
+ // lui $t9, ptr1
+ // lw $t9, %lo(ptr1)($t9)
+ // jr $t9
+ // stub2:
+ // lui $t9, ptr2
+ // lw $t9,%lo(ptr1)($t9)
+ // jr $t9
+ //
+ // ...
+ //
+ // .section __orc_ptrs
+ // ptr1:
+ // .word 0x0
+ // ptr2:
+ // .word 0x0
+ //
+ // ...
+
+ const unsigned StubSize = IndirectStubsInfo::StubSize;
+
+ // Emit at least MinStubs, rounded up to fill the pages allocated.
+ unsigned PageSize = sys::Process::getPageSize();
+ unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
+ unsigned NumStubs = (NumPages * PageSize) / StubSize;
+
+ // Allocate memory for stubs and pointers in one call.
+ std::error_code EC;
+ auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
+ 2 * NumPages * PageSize, nullptr,
+ sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
+
+ if (EC)
+ return errorCodeToError(EC);
+
+ // Create separate MemoryBlocks representing the stubs and pointers.
+ sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
+ sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) +
+ NumPages * PageSize,
+ NumPages * PageSize);
+
+ // Populate the stubs page stubs and mark it executable.
+ uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlock.base());
+ uint64_t PtrAddr = reinterpret_cast<uint64_t>(Stub) + NumPages * PageSize;
+
+ for (unsigned I = 0; I < NumStubs; ++I) {
+ uint32_t HiAddr = ((PtrAddr + 0x8000) >> 16);
+ Stub[4 * I + 0] = 0x3c190000 | (HiAddr & 0xFFFF); // lui $t9,ptr1
+ Stub[4 * I + 1] = 0x8f390000 | (PtrAddr & 0xFFFF); // lw $t9,%lo(ptr1)($t9)
+ Stub[4 * I + 2] = 0x03200008; // jr $t9
+ Stub[4 * I + 3] = 0x00000000; // nop
+ PtrAddr += 4;
+ }
+
+ if (auto EC = sys::Memory::protectMappedMemory(
+ StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
+ return errorCodeToError(EC);
+
+ // Initialize all pointers to point at FailureAddress.
+ void **Ptr = reinterpret_cast<void **>(PtrsBlock.base());
+ for (unsigned I = 0; I < NumStubs; ++I)
+ Ptr[I] = InitialPtrVal;
+
+ StubsInfo = IndirectStubsInfo(NumStubs, std::move(StubsMem));
+
+ return Error::success();
+}
+
+void OrcMips64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
+ void *CallbackMgr) {
+
+ const uint32_t ResolverCode[] = {
+ //resolver_entry:
+ 0x67bdff30, // 0x00: daddiu $sp,$sp,-208
+ 0xffa20000, // 0x04: sd v0,0(sp)
+ 0xffa30008, // 0x08: sd v1,8(sp)
+ 0xffa40010, // 0x0c: sd a0,16(sp)
+ 0xffa50018, // 0x10: sd a1,24(sp)
+ 0xffa60020, // 0x14: sd a2,32(sp)
+ 0xffa70028, // 0x18: sd a3,40(sp)
+ 0xffa80030, // 0x1c: sd a4,48(sp)
+ 0xffa90038, // 0x20: sd a5,56(sp)
+ 0xffaa0040, // 0x24: sd a6,64(sp)
+ 0xffab0048, // 0x28: sd a7,72(sp)
+ 0xffac0050, // 0x2c: sd t0,80(sp)
+ 0xffad0058, // 0x30: sd t1,88(sp)
+ 0xffae0060, // 0x34: sd t2,96(sp)
+ 0xffaf0068, // 0x38: sd t3,104(sp)
+ 0xffb00070, // 0x3c: sd s0,112(sp)
+ 0xffb10078, // 0x40: sd s1,120(sp)
+ 0xffb20080, // 0x44: sd s2,128(sp)
+ 0xffb30088, // 0x48: sd s3,136(sp)
+ 0xffb40090, // 0x4c: sd s4,144(sp)
+ 0xffb50098, // 0x50: sd s5,152(sp)
+ 0xffb600a0, // 0x54: sd s6,160(sp)
+ 0xffb700a8, // 0x58: sd s7,168(sp)
+ 0xffb800b0, // 0x5c: sd t8,176(sp)
+ 0xffb900b8, // 0x60: sd t9,184(sp)
+ 0xffbe00c0, // 0x64: sd s8,192(sp)
+ 0xffbf00c8, // 0x68: sd ra,200(sp)
+
+ // Callback manager addr.
+ 0x00000000, // 0x6c: lui $a0,heighest(callbackmgr)
+ 0x00000000, // 0x70: daddiu $a0,$a0,heigher(callbackmgr)
+ 0x00000000, // 0x74: dsll $a0,$a0,16
+ 0x00000000, // 0x78: daddiu $a0,$a0,hi(callbackmgr)
+ 0x00000000, // 0x7c: dsll $a0,$a0,16
+ 0x00000000, // 0x80: daddiu $a0,$a0,lo(callbackmgr)
+
+ 0x03e02825, // 0x84: move $a1, $ra
+ 0x64a5ffdc, // 0x88: daddiu $a1,$a1,-36
+
+ // JIT re-entry fn addr:
+ 0x00000000, // 0x8c: lui $t9,reentry
+ 0x00000000, // 0x90: daddiu $t9,$t9,reentry
+ 0x00000000, // 0x94: dsll $t9,$t9,
+ 0x00000000, // 0x98: daddiu $t9,$t9,
+ 0x00000000, // 0x9c: dsll $t9,$t9,
+ 0x00000000, // 0xa0: daddiu $t9,$t9,
+ 0x0320f809, // 0xa4: jalr $t9
+ 0x00000000, // 0xa8: nop
+ 0xdfbf00c8, // 0xac: ld ra, 200(sp)
+ 0xdfbe00c0, // 0xb0: ld s8, 192(sp)
+ 0xdfb900b8, // 0xb4: ld t9, 184(sp)
+ 0xdfb800b0, // 0xb8: ld t8, 176(sp)
+ 0xdfb700a8, // 0xbc: ld s7, 168(sp)
+ 0xdfb600a0, // 0xc0: ld s6, 160(sp)
+ 0xdfb50098, // 0xc4: ld s5, 152(sp)
+ 0xdfb40090, // 0xc8: ld s4, 144(sp)
+ 0xdfb30088, // 0xcc: ld s3, 136(sp)
+ 0xdfb20080, // 0xd0: ld s2, 128(sp)
+ 0xdfb10078, // 0xd4: ld s1, 120(sp)
+ 0xdfb00070, // 0xd8: ld s0, 112(sp)
+ 0xdfaf0068, // 0xdc: ld t3, 104(sp)
+ 0xdfae0060, // 0xe0: ld t2, 96(sp)
+ 0xdfad0058, // 0xe4: ld t1, 88(sp)
+ 0xdfac0050, // 0xe8: ld t0, 80(sp)
+ 0xdfab0048, // 0xec: ld a7, 72(sp)
+ 0xdfaa0040, // 0xf0: ld a6, 64(sp)
+ 0xdfa90038, // 0xf4: ld a5, 56(sp)
+ 0xdfa80030, // 0xf8: ld a4, 48(sp)
+ 0xdfa70028, // 0xfc: ld a3, 40(sp)
+ 0xdfa60020, // 0x100: ld a2, 32(sp)
+ 0xdfa50018, // 0x104: ld a1, 24(sp)
+ 0xdfa40010, // 0x108: ld a0, 16(sp)
+ 0xdfa30008, // 0x10c: ld v1, 8(sp)
+ 0x67bd00d0, // 0x110: daddiu $sp,$sp,208
+ 0x0300f825, // 0x114: move $ra, $t8
+ 0x00400008 // 0x118: jr $v0
+ };
+
+ const unsigned ReentryFnAddrOffset = 0x8c; // JIT re-entry fn addr lui
+ const unsigned CallbackMgrAddrOffset = 0x6c; // Callback manager addr lui
+
+ memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
+
+
+ uint64_t CallMgrAddr = reinterpret_cast<uint64_t>(CallbackMgr);
+
+ uint32_t CallMgrLUi =
+ 0x3c040000 | (((CallMgrAddr + 0x800080008000) >> 48) & 0xFFFF);
+ uint32_t CallMgrDADDiu =
+ 0x64840000 | (((CallMgrAddr + 0x80008000) >> 32) & 0xFFFF);
+ uint32_t CallMgrDSLL = 0x00042438;
+ uint32_t CallMgrDADDiu2 =
+ 0x64840000 | ((((CallMgrAddr + 0x8000) >> 16) & 0xFFFF));
+ uint32_t CallMgrDSLL2 = 0x00042438;
+ uint32_t CallMgrDADDiu3 = 0x64840000 | ((CallMgrAddr) & 0xFFFF);
+
+ memcpy(ResolverMem + CallbackMgrAddrOffset, &CallMgrLUi,
+ sizeof(CallMgrLUi));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 4), &CallMgrDADDiu,
+ sizeof(CallMgrDADDiu));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 8), &CallMgrDSLL,
+ sizeof(CallMgrDSLL));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 12), &CallMgrDADDiu2,
+ sizeof(CallMgrDADDiu2));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 16), &CallMgrDSLL2,
+ sizeof(CallMgrDSLL2));
+ memcpy(ResolverMem + (CallbackMgrAddrOffset + 20), &CallMgrDADDiu3,
+ sizeof(CallMgrDADDiu3));
+
+ uint64_t ReentryAddr = reinterpret_cast<uint64_t>(ReentryFn);
+
+ uint32_t ReentryLUi =
+ 0x3c190000 | (((ReentryAddr + 0x800080008000) >> 48) & 0xFFFF);
+
+ uint32_t ReentryDADDiu =
+ 0x67390000 | (((ReentryAddr + 0x80008000) >> 32) & 0xFFFF);
+
+ uint32_t ReentryDSLL = 0x0019cc38;
+
+ uint32_t ReentryDADDiu2 =
+ 0x67390000 | (((ReentryAddr + 0x8000) >> 16) & 0xFFFF);
+
+ uint32_t ReentryDSLL2 = 0x0019cc38;
+
+ uint32_t ReentryDADDiu3 = 0x67390000 | ((ReentryAddr) & 0xFFFF);
+
+ memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryLUi,
+ sizeof(ReentryLUi));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 4), &ReentryDADDiu,
+ sizeof(ReentryDADDiu));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 8), &ReentryDSLL,
+ sizeof(ReentryDSLL));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 12), &ReentryDADDiu2,
+ sizeof(ReentryDADDiu2));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 16), &ReentryDSLL2,
+ sizeof(ReentryDSLL2));
+ memcpy(ResolverMem + (ReentryFnAddrOffset + 20), &ReentryDADDiu3,
+ sizeof(ReentryDADDiu3));
+}
+
+void OrcMips64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ unsigned NumTrampolines) {
+
+ uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem);
+ uint64_t ResolveAddr = reinterpret_cast<uint64_t>(ResolverAddr);
+
+ uint64_t HeighestAddr = ((ResolveAddr + 0x800080008000) >> 48);
+ uint64_t HeigherAddr = ((ResolveAddr + 0x80008000) >> 32);
+ uint64_t HiAddr = ((ResolveAddr + 0x8000) >> 16);
+
+ for (unsigned I = 0; I < NumTrampolines; ++I) {
+ Trampolines[10 * I + 0] = 0x03e0c025; // move $t8,$ra
+ Trampolines[10 * I + 1] = 0x3c190000 | (HeighestAddr & 0xFFFF); // lui $t9,resolveAddr
+ Trampolines[10 * I + 2] = 0x67390000 | (HeigherAddr & 0xFFFF); // daddiu $t9,$t9,%higher(resolveAddr)
+ Trampolines[10 * I + 3] = 0x0019cc38; // dsll $t9,$t9,16
+ Trampolines[10 * I + 4] = 0x67390000 | (HiAddr & 0xFFFF); // daddiu $t9,$t9,%hi(ptr)
+ Trampolines[10 * I + 5] = 0x0019cc38; // dsll $t9,$t9,16
+ Trampolines[10 * I + 6] = 0x67390000 | (ResolveAddr & 0xFFFF); // daddiu $t9,$t9,%lo(ptr)
+ Trampolines[10 * I + 7] = 0x0320f809; // jalr $t9
+ Trampolines[10 * I + 8] = 0x00000000; // nop
+ Trampolines[10 * I + 9] = 0x00000000; // nop
+ }
+
+}
+
+Error OrcMips64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
+ unsigned MinStubs,
+ void *InitialPtrVal) {
+ // Stub format is:
+ //
+ // .section __orc_stubs
+ // stub1:
+ // lui $t9,ptr1
+ // dsll $t9,$t9,16
+ // daddiu $t9,$t9,%hi(ptr)
+ // dsll $t9,$t9,16
+ // ld $t9,%lo(ptr)
+ // jr $t9
+ // stub2:
+ // lui $t9,ptr1
+ // dsll $t9,$t9,16
+ // daddiu $t9,$t9,%hi(ptr)
+ // dsll $t9,$t9,16
+ // ld $t9,%lo(ptr)
+ // jr $t9
+ //
+ // ...
+ //
+ // .section __orc_ptrs
+ // ptr1:
+ // .dword 0x0
+ // ptr2:
+ // .dword 0x0
+ //
+ // ...
+ const unsigned StubSize = IndirectStubsInfo::StubSize;
+
+ // Emit at least MinStubs, rounded up to fill the pages allocated.
+ unsigned PageSize = sys::Process::getPageSize();
+ unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
+ unsigned NumStubs = (NumPages * PageSize) / StubSize;
+
+ // Allocate memory for stubs and pointers in one call.
+ std::error_code EC;
+ auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
+ 2 * NumPages * PageSize, nullptr,
+ sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
+
+ if (EC)
+ return errorCodeToError(EC);
+
+ // Create separate MemoryBlocks representing the stubs and pointers.
+ sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
+ sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) +
+ NumPages * PageSize,
+ NumPages * PageSize);
+
+ // Populate the stubs page stubs and mark it executable.
+ uint32_t *Stub = reinterpret_cast<uint32_t *>(StubsBlock.base());
+ uint64_t PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base());
+
+ for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 8) {
+ uint64_t HeighestAddr = ((PtrAddr + 0x800080008000) >> 48);
+ uint64_t HeigherAddr = ((PtrAddr + 0x80008000) >> 32);
+ uint64_t HiAddr = ((PtrAddr + 0x8000) >> 16);
+ Stub[8 * I + 0] = 0x3c190000 | (HeighestAddr & 0xFFFF); // lui $t9,ptr1
+ Stub[8 * I + 1] = 0x67390000 | (HeigherAddr & 0xFFFF); // daddiu $t9,$t9,%higher(ptr)
+ Stub[8 * I + 2] = 0x0019cc38; // dsll $t9,$t9,16
+ Stub[8 * I + 3] = 0x67390000 | (HiAddr & 0xFFFF); // daddiu $t9,$t9,%hi(ptr)
+ Stub[8 * I + 4] = 0x0019cc38; // dsll $t9,$t9,16
+ Stub[8 * I + 5] = 0xdf390000 | (PtrAddr & 0xFFFF); // ld $t9,%lo(ptr)
+ Stub[8 * I + 6] = 0x03200008; // jr $t9
+ Stub[8 * I + 7] = 0x00000000; // nop
+ }
+
+ if (auto EC = sys::Memory::protectMappedMemory(
+ StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
+ return errorCodeToError(EC);
+
+ // Initialize all pointers to point at FailureAddress.
+ void **Ptr = reinterpret_cast<void **>(PtrsBlock.base());
+ for (unsigned I = 0; I < NumStubs; ++I)
+ Ptr[I] = InitialPtrVal;
+
+ StubsInfo = IndirectStubsInfo(NumStubs, std::move(StubsMem));
+
+ return Error::success();
+}
} // End namespace orc.
} // End namespace llvm.
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=341934&r1=341933&r2=341934&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Tue Sep 11 06:10:04 2018
@@ -275,14 +275,14 @@ public:
{
unsigned CtorId = 0, DtorId = 0;
for (auto Ctor : orc::getConstructors(*M)) {
- std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str();
+ std::string NewCtorName = ("__ORCstatic_ctor." + Twine(CtorId++)).str();
Ctor.Func->setName(NewCtorName);
Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
CtorNames.push_back(mangle(NewCtorName));
}
for (auto Dtor : orc::getDestructors(*M)) {
- std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str();
+ std::string NewDtorName = ("__ORCstatic_dtor." + Twine(DtorId++)).str();
dbgs() << "Found dtor: " << NewDtorName << "\n";
Dtor.Func->setName(NewDtorName);
Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
Modified: llvm/trunk/test/ExecutionEngine/OrcLazy/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/lit.local.cfg?rev=341934&r1=341933&r2=341934&view=diff
==============================================================================
--- llvm/trunk/test/ExecutionEngine/OrcLazy/lit.local.cfg (original)
+++ llvm/trunk/test/ExecutionEngine/OrcLazy/lit.local.cfg Tue Sep 11 06:10:04 2018
@@ -1,6 +1,6 @@
import sys
-if config.root.host_arch not in ['i386', 'x86', 'x86_64', 'AMD64']:
+if config.root.host_arch not in ['i386', 'x86', 'x86_64', 'AMD64', 'mips', 'mipsel', 'mips64', 'mips64el']:
config.unsupported = True
# FIXME: These tests don't pass with the COFF rtld.
More information about the llvm-commits
mailing list