diff options
| author | Petar Jovanovic <petar.jovanovic@imgtec.com> | 2015-05-28 13:48:41 +0000 |
|---|---|---|
| committer | Petar Jovanovic <petar.jovanovic@imgtec.com> | 2015-05-28 13:48:41 +0000 |
| commit | 9720283e994c6c3187cff8724bf0c2ed59d04f8c (patch) | |
| tree | 9044d2123f55226de7b7b33e074b8807ff3aea22 /llvm | |
| parent | fb7d5b8384a58fcf59518273e8aeade078acd44b (diff) | |
| download | bcm5719-llvm-9720283e994c6c3187cff8724bf0c2ed59d04f8c.tar.gz bcm5719-llvm-9720283e994c6c3187cff8724bf0c2ed59d04f8c.zip | |
[Mips64] Add support for MCJIT for MIPS64r2 and MIPS64r6
Add support for resolving MIPS64r2 and MIPS64r6 relocations in MCJIT.
Patch by Vladimir Radosavljevic.
Differential Revision: http://reviews.llvm.org/D9667
llvm-svn: 238424
Diffstat (limited to 'llvm')
32 files changed, 469 insertions, 33 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 24a3ec19aed..89535095dae 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -149,6 +149,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Save information about our target Arch = (Triple::ArchType)Obj.getArch(); IsTargetLittleEndian = Obj.isLittleEndian(); + setMipsABI(Obj); // Compute the memory size required to load all sections to be loaded // and pass this information to the memory manager @@ -689,7 +690,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr, // and stubs for branches Thumb - ARM and ARM - Thumb. writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label> return Addr + 4; - } else if (Arch == Triple::mipsel || Arch == Triple::mips) { + } else if (IsMipsO32ABI) { // 0: 3c190000 lui t9,%hi(addr). // 4: 27390000 addiu t9,t9,%lo(addr). // 8: 03200008 jr t9. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 95421b35db5..c0823c9cbf7 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -507,6 +507,199 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, } } +void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { + if (!StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) { + IsMipsO32ABI = false; + IsMipsN64ABI = false; + return; + } + unsigned AbiVariant; + Obj.getPlatformFlags(AbiVariant); + IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32; + IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips"); + if (AbiVariant & ELF::EF_MIPS_ABI2) + llvm_unreachable("Mips N32 ABI is not supported yet"); +} + +void RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type, int64_t Addend, + uint64_t SymOffset, + SID SectionID) { + uint32_t r_type = Type & 0xff; + uint32_t r_type2 = (Type >> 8) & 0xff; + uint32_t r_type3 = (Type >> 16) & 0xff; + + // RelType is used to keep information for which relocation type we are + // applying relocation. + uint32_t RelType = r_type; + int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value, + RelType, Addend, + SymOffset, SectionID); + if (r_type2 != ELF::R_MIPS_NONE) { + RelType = r_type2; + CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, + CalculatedValue, SymOffset, + SectionID); + } + if (r_type3 != ELF::R_MIPS_NONE) { + RelType = r_type3; + CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, + CalculatedValue, SymOffset, + SectionID); + } + applyMIPS64Relocation(Section.Address + Offset, CalculatedValue, RelType); +} + +int64_t +RuntimeDyldELF::evaluateMIPS64Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID) { + + DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x" + << format("%llx", Section.Address + Offset) + << " FinalAddress: 0x" + << format("%llx", Section.LoadAddress + Offset) + << " Value: 0x" << format("%llx", Value) << " Type: 0x" + << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) + << " SymOffset: " << format("%x", SymOffset) + << "\n"); + + switch (Type) { + default: + llvm_unreachable("Not implemented relocation type!"); + break; + case ELF::R_MIPS_JALR: + case ELF::R_MIPS_NONE: + break; + case ELF::R_MIPS_32: + case ELF::R_MIPS_64: + return Value + Addend; + case ELF::R_MIPS_26: + return ((Value + Addend) >> 2) & 0x3ffffff; + case ELF::R_MIPS_GPREL16: { + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + return Value + Addend - (GOTAddr + 0x7ff0); + } + case ELF::R_MIPS_SUB: + return Value - Addend; + case ELF::R_MIPS_HI16: + // Get the higher 16-bits. Also add 1 if bit 15 is 1. + return ((Value + Addend + 0x8000) >> 16) & 0xffff; + case ELF::R_MIPS_LO16: + return (Value + Addend) & 0xffff; + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GOT_DISP: + case ELF::R_MIPS_GOT_PAGE: { + uint8_t *LocalGOTAddr = + getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset; + uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, 8); + + Value += Addend; + if (Type == ELF::R_MIPS_GOT_PAGE) + Value = (Value + 0x8000) & ~0xffff; + + if (GOTEntry) + assert(GOTEntry == Value && + "GOT entry has two different addresses."); + else + writeBytesUnaligned(Value, LocalGOTAddr, 8); + + return (SymOffset - 0x7ff0) & 0xffff; + } + case ELF::R_MIPS_GOT_OFST: { + int64_t page = (Value + Addend + 0x8000) & ~0xffff; + return (Value + Addend - page) & 0xffff; + } + case ELF::R_MIPS_GPREL32: { + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + return Value + Addend - (GOTAddr + 0x7ff0); + } + case ELF::R_MIPS_PC16: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - FinalAddress - 4) >> 2) & 0xffff; + } + case ELF::R_MIPS_PC18_S3: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - ((FinalAddress | 7) ^ 7)) >> 3) & 0x3ffff; + } + case ELF::R_MIPS_PC19_S2: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0x7ffff; + } + case ELF::R_MIPS_PC21_S2: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff; + } + case ELF::R_MIPS_PC26_S2: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff; + } + case ELF::R_MIPS_PCHI16: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff; + } + case ELF::R_MIPS_PCLO16: { + uint64_t FinalAddress = (Section.LoadAddress + Offset); + return (Value + Addend - FinalAddress) & 0xffff; + } + } + return 0; +} + +void RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr, + int64_t CalculatedValue, + uint32_t Type) { + uint32_t Insn = readBytesUnaligned(TargetPtr, 4); + + switch (Type) { + default: + break; + case ELF::R_MIPS_32: + case ELF::R_MIPS_GPREL32: + writeBytesUnaligned(CalculatedValue & 0xffffffff, TargetPtr, 4); + break; + case ELF::R_MIPS_64: + case ELF::R_MIPS_SUB: + writeBytesUnaligned(CalculatedValue, TargetPtr, 8); + break; + case ELF::R_MIPS_26: + case ELF::R_MIPS_PC26_S2: + Insn = (Insn & 0xfc000000) | CalculatedValue; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_GPREL16: + Insn = (Insn & 0xffff0000) | (CalculatedValue & 0xffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_PCHI16: + case ELF::R_MIPS_PCLO16: + case ELF::R_MIPS_PC16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GOT_DISP: + case ELF::R_MIPS_GOT_PAGE: + case ELF::R_MIPS_GOT_OFST: + Insn = (Insn & 0xffff0000) | CalculatedValue; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC18_S3: + Insn = (Insn & 0xfffc0000) | CalculatedValue; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC19_S2: + Insn = (Insn & 0xfff80000) | CalculatedValue; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC21_S2: + Insn = (Insn & 0xffe00000) | CalculatedValue; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } +} + // Return the .TOC. section and offset. void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj, ObjSectionToIDMap &LocalSections, @@ -784,13 +977,13 @@ void RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE, uint64_t Value) { const SectionEntry &Section = Sections[RE.SectionID]; return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, - RE.SymOffset); + RE.SymOffset, RE.SectionID); } void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, - uint64_t SymOffset) { + uint64_t SymOffset, SID SectionID) { switch (Arch) { case Triple::x86_64: resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset); @@ -812,8 +1005,16 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, break; case Triple::mips: // Fall through. case Triple::mipsel: - resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), - Type, (uint32_t)(Addend & 0xffffffffL)); + case Triple::mips64: + case Triple::mips64el: + if (IsMipsO32ABI) + resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), + Type, (uint32_t)(Addend & 0xffffffffL)); + else if (IsMipsN64ABI) + resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset, + SectionID); + else + llvm_unreachable("Mips ABI not handled"); break; case Triple::ppc64: // Fall through. case Triple::ppc64le: @@ -999,7 +1200,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( } processSimpleRelocation(SectionID, Offset, RelType, Value); } - } else if ((Arch == Triple::mipsel || Arch == Triple::mips)) { + } else if (IsMipsO32ABI) { uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset)); if (RelType == ELF::R_MIPS_26) { // This is an Mips branch relocation, need to use a stub function. @@ -1054,6 +1255,23 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( Value.Addend += *Placeholder; processSimpleRelocation(SectionID, Offset, RelType, Value); } + } else if (IsMipsN64ABI) { + uint32_t r_type = RelType & 0xff; + RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); + if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE + || r_type == ELF::R_MIPS_GOT_DISP) { + StringMap<uint64_t>::iterator i = GOTSymbolOffsets.find(TargetName); + if (i != GOTSymbolOffsets.end()) + RE.SymOffset = i->second; + else { + RE.SymOffset = allocateGOTEntries(SectionID, 1); + GOTSymbolOffsets[TargetName] = RE.SymOffset; + } + } + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { if (RelType == ELF::R_PPC64_REL24) { // Determine ABI variant in use for this object. @@ -1356,9 +1574,18 @@ size_t RuntimeDyldELF::getGOTEntrySize() { case Triple::x86: case Triple::arm: case Triple::thumb: + Result = sizeof(uint32_t); + break; case Triple::mips: case Triple::mipsel: - Result = sizeof(uint32_t); + case Triple::mips64: + case Triple::mips64el: + if (IsMipsO32ABI) + Result = sizeof(uint32_t); + else if (IsMipsN64ABI) + Result = sizeof(uint64_t); + else + llvm_unreachable("Mips ABI not handled"); break; default: llvm_unreachable("Unsupported CPU type!"); @@ -1413,6 +1640,20 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, // For now, initialize all GOT entries to zero. We'll fill them in as // needed when GOT-based relocations are applied. memset(Addr, 0, TotalSize); + if (IsMipsN64ABI) { + // To correctly resolve Mips GOT relocations, we need a mapping from + // object's sections to GOTs. + for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); + SI != SE; ++SI) { + if (SI->relocation_begin() != SI->relocation_end()) { + section_iterator RelocatedSection = SI->getRelocatedSection(); + ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection); + assert (i != SectionMap.end()); + SectionToGOTMap[i->second] = GOTSectionID; + } + } + GOTSymbolOffsets.clear(); + } } // Look for and record the EH frame section. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 9a4a8630e4c..3a377a2e162 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -25,7 +25,7 @@ class RuntimeDyldELF : public RuntimeDyldImpl { void resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, - uint64_t SymOffset = 0); + uint64_t SymOffset = 0, SID SectionID = 0); void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, @@ -49,12 +49,24 @@ class RuntimeDyldELF : public RuntimeDyldImpl { void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); + void resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID); + + int64_t evaluateMIPS64Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID); + + void applyMIPS64Relocation(uint8_t *TargetPtr, int64_t CalculatedValue, + uint32_t Type); + unsigned getMaxStubSize() override { if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) return 20; // movz; movk; movk; movk; br if (Arch == Triple::arm || Arch == Triple::thumb) return 8; // 32-bit instruction and 32-bit address - else if (Arch == Triple::mipsel || Arch == Triple::mips) + else if (IsMipsO32ABI) return 16; else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) return 44; @@ -73,6 +85,8 @@ class RuntimeDyldELF : public RuntimeDyldImpl { return 1; } + void setMipsABI(const ObjectFile &Obj) override; + void findPPC64TOCSection(const ObjectFile &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel); @@ -114,6 +128,13 @@ class RuntimeDyldELF : public RuntimeDyldImpl { // that consume more than one slot) unsigned CurrentGOTIndex; + // A map from section to a GOT section that has entries for section's GOT + // relocations. (Mips64 specific) + DenseMap<SID, SID> SectionToGOTMap; + + // A map to avoid duplicate got entries (Mips64 specific) + StringMap<uint64_t> GOTSymbolOffsets; + // When a module is loaded we save the SectionID of the EH frame section // in a table until we receive a request to register all unregistered // EH frame sections with the memory manager. diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 90e61a50a1b..e085a9296e8 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -236,6 +236,8 @@ protected: Triple::ArchType Arch; bool IsTargetLittleEndian; + bool IsMipsO32ABI; + bool IsMipsN64ABI; // True if all sections should be passed to the memory manager, false if only // sections containing relocations should be. Defaults to 'false'. @@ -303,6 +305,11 @@ protected: *(Addr + 7) = Value & 0xFF; } + virtual void setMipsABI(const ObjectFile &Obj) { + IsMipsO32ABI = false; + IsMipsN64ABI = false; + } + /// Endian-aware read Read the least significant Size bytes from Src. uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const; diff --git a/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp b/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp index 3615c146a52..6a65943515b 100644 --- a/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp +++ b/llvm/lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp @@ -23,9 +23,9 @@ extern "C" void LLVMInitializeMipsTargetInfo() { /*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel"); RegisterTarget<Triple::mips64, - /*HasJIT=*/false> A(TheMips64Target, "mips64", "Mips64 [experimental]"); + /*HasJIT=*/true> A(TheMips64Target, "mips64", "Mips64 [experimental]"); RegisterTarget<Triple::mips64el, - /*HasJIT=*/false> B(TheMips64elTarget, + /*HasJIT=*/true> B(TheMips64elTarget, "mips64el", "Mips64el [experimental]"); } diff --git a/llvm/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll index eb414249bdc..04331990db3 100644 --- a/llvm/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/MCJIT/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll b/llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll index 9277ec4a8ca..222196f81c4 100644 --- a/llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/eh-lg-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=large %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/ExecutionEngine/MCJIT/eh-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/eh-sm-pic.ll index 37fb628cf0a..c73dcca5ee1 100644 --- a/llvm/test/ExecutionEngine/MCJIT/eh-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/eh-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=small %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll index 01faecc6495..7e5710dbf9c 100644 --- a/llvm/test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/MCJIT/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll index d47fc6cffbb..415fd25409d 100644 --- a/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/MCJIT/remote/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll index d248c4b2a94..3e020dc853a 100644 --- a/llvm/test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/MCJIT/remote/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll index f9184b4077b..e350b85a8bc 100644 --- a/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 diff --git a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll index d9a4faa8e6b..7162e927de0 100644 --- a/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -remote-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 diff --git a/llvm/test/ExecutionEngine/MCJIT/stubs-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/stubs-sm-pic.ll index 6eebe44e3ff..46545ce5342 100644 --- a/llvm/test/ExecutionEngine/MCJIT/stubs-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/stubs-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s -; XFAIL: mips, i686, i386, aarch64, arm +; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm define i32 @main() nounwind { entry: diff --git a/llvm/test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll index 8ae496d0fab..e54135fc7cb 100644 --- a/llvm/test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 diff --git a/llvm/test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll b/llvm/test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll index d50ba9dd5a0..eea6fde2e2c 100644 --- a/llvm/test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll +++ b/llvm/test/ExecutionEngine/MCJIT/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll index 4f5afd0ed47..9af82e7486f 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll index 32b53c4847b..47674dd9cdc 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=large %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll index a54795ead56..c279720cdb0 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/eh-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s -; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan +; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan declare i8* @__cxa_allocate_exception(i64) declare void @__cxa_throw(i8*, i8*, i8*) declare i32 @__gxx_personality_v0(...) diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll index 80b8e163d5d..0052c012652 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386 +; XFAIL: mips-, mipsel-, i686, i386 declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll index c8979043857..4326fc1e526 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/remote/cross-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll b/llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll index 41812d25169..18a2d7e87d0 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-sm-pic-a.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, i686, i386, arm +; XFAIL: mips-, mipsel-, i686, i386, arm declare i32 @FB() diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll index ec9e1ae1a03..f1e93133b22 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll index 61321ac1b94..cac800ef5e7 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll index f354a0de093..ec4183bc724 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s -; XFAIL: mips, i686, i386, aarch64, arm +; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm define i32 @main() nounwind { entry: diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll index 7f66aec7707..c9b6cf755b7 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s > /dev/null -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @count = global i32 1, align 4 diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll b/llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll index 6e0a425623b..d0bb070110c 100644 --- a/llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll +++ b/llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll @@ -1,5 +1,5 @@ ; RUN: %lli -jit-kind=orc-mcjit -O0 -relocation-model=pic -code-model=small %s -; XFAIL: mips, aarch64, arm, i686, i386 +; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1 @ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4 diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s new file mode 100644 index 00000000000..d59d1350f39 --- /dev/null +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_Mips64r2N64_PIC_relocations.s @@ -0,0 +1,155 @@ +# RUN: llvm-mc -triple=mips64el-unknown-linux -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_Mips64N64.o %s +# RUN: llc -mtriple=mips64el-unknown-linux -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_Mips64N64.o %S/Inputs/ExternalFunction.ll +# RUN: llvm-rtdyld -triple=mips64el-unknown-linux -verify -map-section test_ELF_Mips64N64.o,.text=0x1000 -map-section test_ELF_ExternalFunction_Mips64N64.o,.text=0x10000 -check=%s %/T/test_ELF_Mips64N64.o %T/test_ELF_ExternalFunction_Mips64N64.o + + .text + .abicalls + .section .mdebug.abi64,"",@progbits + .nan legacy + .file "ELF_Mips64N64_PIC_relocations.ll" + .text + .globl bar + .align 3 + .type bar,@function + .set nomicromips + .set nomips16 + .ent bar +bar: + .frame $fp,40,$ra + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + .set noat + daddiu $sp, $sp, -40 + sd $ra, 32($sp) + sd $fp, 24($sp) + move $fp, $sp + sd $4, 16($fp) + lb $2, 0($4) + sd $4, 8($fp) + +# Test R_MIPS_26 relocation. +# rtdyld-check: decode_operand(insn1, 0)[25:0] = foo +insn1: + jal foo + nop + +# Test R_MIPS_PC16 relocation. +# rtdyld-check: decode_operand(insn2, 1)[15:0] = foo - insn2 +insn2: + bal foo + nop + + move $sp, $fp + ld $ra, 32($sp) + ld $fp, 24($sp) + daddiu $sp, $sp, 32 + jr $ra + nop + .set at + .set macro + .set reorder + .end bar +$func_end0: + .size bar, ($func_end0)-bar + + .globl main + .align 3 + .type main,@function + .set nomicromips + .set nomips16 + .ent main +main: + .frame $fp,32,$ra + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + .set noat + daddiu $sp, $sp, -32 + sd $ra, 24($sp) + sd $fp, 16($sp) + sd $gp, 8($sp) + move $fp, $sp + +# Check upper 16-bits of offset between the address of main function +# and the global offset table. +# rtdyld-check: decode_operand(insn3, 1)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main + 0x8000)[31:16] +insn3: + lui $1, %hi(%neg(%gp_rel(main))) + daddu $1, $1, $25 + +# Check lower 16-bits of offset between the address of main function +# and the global offset table. +# rtdyld-check: decode_operand(insn4, 2)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main)[15:0] +insn4: + daddiu $1, $1, %lo(%neg(%gp_rel(main))) + sw $zero, 4($fp) + +# $gp register contains address of the .got section + 0x7FF0. 0x7FF0 is +# the offset of $gp from the beginning of the .got section. Check that we are +# loading address of the page pointer from correct offset. In this case +# the page pointer is the first entry in the .got section, so offset will be +# 0 - 0x7FF0. +# rtdyld-check: decode_operand(insn5, 2)[15:0] = 0x8010 +# +# Check that the global offset table contains the page pointer. +# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got)) = (_str + 0x8000) & 0xffffffffffff0000 +insn5: + ld $25, %got_page(_str)($1) + +# Check the offset of _str from the page pointer. +# rtdyld-check: decode_operand(insn6, 2)[15:0] = _str[15:0] +insn6: + daddiu $25, $25, %got_ofst(_str) + +# Check that we are loading address of var from correct offset. In this case +# var is the second entry in the .got section, so offset will be 8 - 0x7FF0. +# rtdyld-check: decode_operand(insn7, 2)[15:0] = 0x8018 +# +# Check that the global offset table contains the address of the var. +# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got) + 8) = var +insn7: + ld $2, %got_disp(var)($1) + sd $25, 0($2) + +# Check that we are loading address of bar from correct offset. In this case +# bar is the third entry in the .got section, so offset will be 16 - 0x7FF0. +# rtdyld-check: decode_operand(insn8, 2)[15:0] = 0x8020 +# +# Check that the global offset table contains the address of the bar. +# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got) + 16) = bar +insn8: + ld $2, %call16(bar)($1) + + move $4, $25 + move $gp, $1 + move $25, $2 + jalr $25 + nop + move $sp, $fp + ld $gp, 8($sp) + ld $fp, 16($sp) + ld $ra, 24($sp) + daddiu $sp, $sp, 32 + jr $ra + nop + .set at + .set macro + .set reorder + .end main +$func_end1: + .size main, ($func_end1)-main + + .type _str,@object + .section .rodata.str1.1,"aMS",@progbits,1 +_str: + .asciz "test" + .size _str, 5 + + .type var,@object + .comm var,8,8 + + .section ".note.GNU-stack","",@progbits + .text diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/Inputs/ExternalFunction.ll b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/Inputs/ExternalFunction.ll new file mode 100644 index 00000000000..a59d68c1e18 --- /dev/null +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/Inputs/ExternalFunction.ll @@ -0,0 +1,4 @@ +define void @foo() { +entry: + ret void +} diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg new file mode 100644 index 00000000000..a3183a25afa --- /dev/null +++ b/llvm/test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg @@ -0,0 +1,3 @@ +if not 'Mips' in config.root.targets: + config.unsupported = True + diff --git a/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp index a7c9ae02b38..c7d4dd757cf 100644 --- a/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp +++ b/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp @@ -127,6 +127,8 @@ protected: SupportedArchs.push_back(Triple::aarch64); SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); + SupportedArchs.push_back(Triple::mips64); + SupportedArchs.push_back(Triple::mips64el); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64); diff --git a/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h index 901f142d09c..0749a1dfb9c 100644 --- a/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h +++ b/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h @@ -298,6 +298,8 @@ protected: SupportedArchs.push_back(Triple::arm); SupportedArchs.push_back(Triple::mips); SupportedArchs.push_back(Triple::mipsel); + SupportedArchs.push_back(Triple::mips64); + SupportedArchs.push_back(Triple::mips64el); SupportedArchs.push_back(Triple::x86); SupportedArchs.push_back(Triple::x86_64); |

