[lld] r278482 - [ELF][MIPS] Support .MIPS.abiflags section

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 11 23:28:49 PDT 2016


Author: atanasyan
Date: Fri Aug 12 01:28:49 2016
New Revision: 278482

URL: http://llvm.org/viewvc/llvm-project?rev=278482&view=rev
Log:
[ELF][MIPS] Support .MIPS.abiflags section

This section supersedes .reginfo and .MIPS.options sections. But for now
we have to support all three sections for ABI transition period.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/Mips.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.h
    lld/trunk/test/ELF/basic-mips.s
    lld/trunk/test/ELF/mips-elf-flags-err.s
    lld/trunk/test/ELF/mips-elf-flags.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Aug 12 01:28:49 2016
@@ -267,6 +267,10 @@ void elf::ObjectFile<ELFT>::initializeSe
       MipsOptions.reset(new MipsOptionsInputSection<ELFT>(this, &Sec));
       Sections[I] = MipsOptions.get();
       break;
+    case SHT_MIPS_ABIFLAGS:
+      MipsAbiFlags.reset(new MipsAbiFlagsInputSection<ELFT>(this, &Sec));
+      Sections[I] = MipsAbiFlags.get();
+      break;
     default:
       Sections[I] = createInputSection(Sec);
     }

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Fri Aug 12 01:28:49 2016
@@ -176,6 +176,8 @@ private:
   std::unique_ptr<MipsReginfoInputSection<ELFT>> MipsReginfo;
   // MIPS .MIPS.options section defined by this file.
   std::unique_ptr<MipsOptionsInputSection<ELFT>> MipsOptions;
+  // MIPS .MIPS.abiflags section defined by this file.
+  std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags;
 
   llvm::SpecificBumpPtrAllocator<InputSection<ELFT>> IAlloc;
   llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> MAlloc;

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Aug 12 01:28:49 2016
@@ -82,10 +82,11 @@ typename ELFT::uint InputSectionBase<ELF
     return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset);
   case MipsReginfo:
   case MipsOptions:
-    // MIPS .reginfo and .MIPS.options sections are consumed by the linker,
-    // and the linker produces a single output section. It is possible that
-    // input files contain section symbol points to the corresponding input
-    // section. Redirect it to the produced output section.
+  case MipsAbiFlags:
+    // MIPS .reginfo, .MIPS.options, and .MIPS.abiflags sections are consumed
+    // by the linker, and the linker produces a single output section. It is
+    // possible that input files contain section symbol points to the
+    // corresponding input section. Redirect it to the produced output section.
     if (Offset != 0)
       fatal(getName(this) + ": unsupported reference to the middle of '" +
             getSectionName() + "' section");
@@ -679,6 +680,24 @@ bool MipsOptionsInputSection<ELFT>::clas
 }
 
 template <class ELFT>
+MipsAbiFlagsInputSection<ELFT>::MipsAbiFlagsInputSection(
+    elf::ObjectFile<ELFT> *F, const Elf_Shdr *Hdr)
+    : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsAbiFlags) {
+  // Initialize this->Flags.
+  ArrayRef<uint8_t> D = this->getSectionData();
+  if (D.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
+    error("invalid size of .MIPS.abiflags section");
+    return;
+  }
+  Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(D.data());
+}
+
+template <class ELFT>
+bool MipsAbiFlagsInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
+  return S->SectionKind == InputSectionBase<ELFT>::MipsAbiFlags;
+}
+
+template <class ELFT>
 CommonInputSection<ELFT>::CommonInputSection(
     std::vector<DefinedCommon<ELFT> *> Syms)
     : InputSection<ELFT>(nullptr, &Hdr) {
@@ -733,6 +752,11 @@ template class elf::MipsOptionsInputSect
 template class elf::MipsOptionsInputSection<ELF64LE>;
 template class elf::MipsOptionsInputSection<ELF64BE>;
 
+template class elf::MipsAbiFlagsInputSection<ELF32LE>;
+template class elf::MipsAbiFlagsInputSection<ELF32BE>;
+template class elf::MipsAbiFlagsInputSection<ELF64LE>;
+template class elf::MipsAbiFlagsInputSection<ELF64BE>;
+
 template class elf::CommonInputSection<ELF32LE>;
 template class elf::CommonInputSection<ELF32BE>;
 template class elf::CommonInputSection<ELF64LE>;

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Fri Aug 12 01:28:49 2016
@@ -48,7 +48,15 @@ protected:
   SmallVector<char, 0> Uncompressed;
 
 public:
-  enum Kind { Regular, EHFrame, Merge, MipsReginfo, MipsOptions, Layout };
+  enum Kind {
+    Regular,
+    EHFrame,
+    Merge,
+    MipsReginfo,
+    MipsOptions,
+    MipsAbiFlags,
+    Layout
+  };
   Kind SectionKind;
 
   InputSectionBase() : Repl(this) {}
@@ -260,6 +268,17 @@ public:
   const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
 };
 
+template <class ELFT>
+class MipsAbiFlagsInputSection : public InputSectionBase<ELFT> {
+  typedef typename ELFT::Shdr Elf_Shdr;
+
+public:
+  MipsAbiFlagsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
+  static bool classof(const InputSectionBase<ELFT> *S);
+
+  const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
+};
+
 // Common symbols don't belong to any section. But it is easier for us
 // to handle them as if they belong to some input section. So we defined
 // this class. CommonInputSection is a virtual singleton class that

Modified: lld/trunk/ELF/Mips.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Mips.cpp?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/Mips.cpp (original)
+++ lld/trunk/ELF/Mips.cpp Fri Aug 12 01:28:49 2016
@@ -18,6 +18,7 @@
 
 #include "llvm/Object/ELF.h"
 #include "llvm/Support/ELF.h"
+#include "llvm/Support/MipsABIFlags.h"
 
 using namespace llvm;
 using namespace llvm::object;
@@ -290,6 +291,57 @@ template <class ELFT> uint32_t elf::getM
   return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
 }
 
+static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
+  if (FpA == FpB)
+    return 0;
+  if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
+    return 1;
+  if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
+      FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
+    return 1;
+  if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
+    return -1;
+  if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
+      FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
+      FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
+    return 1;
+  return -1;
+}
+
+static StringRef getMipsFpAbiName(uint8_t FpAbi) {
+  switch (FpAbi) {
+  case Mips::Val_GNU_MIPS_ABI_FP_ANY:
+    return "any";
+  case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
+    return "-mdouble-float";
+  case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
+    return "-msingle-float";
+  case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
+    return "-msoft-float";
+  case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
+    return "-mips32r2 -mfp64 (old)";
+  case Mips::Val_GNU_MIPS_ABI_FP_XX:
+    return "-mfpxx";
+  case Mips::Val_GNU_MIPS_ABI_FP_64:
+    return "-mgp32 -mfp64";
+  case Mips::Val_GNU_MIPS_ABI_FP_64A:
+    return "-mgp32 -mfp64 -mno-odd-spreg";
+  default:
+    return "unknown";
+  }
+}
+
+uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
+                              StringRef FileName) {
+  if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
+    return NewFlag;
+  if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
+    error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
+          "' is incompatible with '" + getMipsFpAbiName(NewFlag) + "': " +
+          FileName);
+  return OldFlag;
+}
+
 template uint32_t elf::getMipsEFlags<ELF32LE>();
 template uint32_t elf::getMipsEFlags<ELF32BE>();
 template uint32_t elf::getMipsEFlags<ELF64LE>();

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Aug 12 01:28:49 2016
@@ -1738,6 +1738,46 @@ void MipsOptionsOutputSection<ELFT>::add
 }
 
 template <class ELFT>
+MipsAbiFlagsOutputSection<ELFT>::MipsAbiFlagsOutputSection()
+    : OutputSectionBase<ELFT>(".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC) {
+  this->Header.sh_addralign = 8;
+  this->Header.sh_entsize = sizeof(Elf_Mips_ABIFlags);
+  this->Header.sh_size = sizeof(Elf_Mips_ABIFlags);
+  memset(&Flags, 0, sizeof(Flags));
+}
+
+template <class ELFT>
+void MipsAbiFlagsOutputSection<ELFT>::writeTo(uint8_t *Buf) {
+  memcpy(Buf, &Flags, sizeof(Flags));
+}
+
+template <class ELFT>
+void MipsAbiFlagsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
+  // Check compatibility and merge fields from input .MIPS.abiflags
+  // to the output one.
+  auto *S = cast<MipsAbiFlagsInputSection<ELFT>>(C);
+  S->OutSec = this;
+  if (S->Flags->version != 0) {
+    error(getFilename(S->getFile()) + ": unexpected .MIPS.abiflags version " +
+          Twine(S->Flags->version));
+    return;
+  }
+  // LLD checks ISA compatibility in getMipsEFlags(). Here we just
+  // select the highest number of ISA/Rev/Ext.
+  Flags.isa_level = std::max(Flags.isa_level, S->Flags->isa_level);
+  Flags.isa_rev = std::max(Flags.isa_rev, S->Flags->isa_rev);
+  Flags.isa_ext = std::max(Flags.isa_ext, S->Flags->isa_ext);
+  Flags.gpr_size = std::max(Flags.gpr_size, S->Flags->gpr_size);
+  Flags.cpr1_size = std::max(Flags.cpr1_size, S->Flags->cpr1_size);
+  Flags.cpr2_size = std::max(Flags.cpr2_size, S->Flags->cpr2_size);
+  Flags.ases |= S->Flags->ases;
+  Flags.flags1 |= S->Flags->flags1;
+  Flags.flags2 |= S->Flags->flags2;
+  Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->Flags->fp_abi,
+                                       getFilename(S->getFile()));
+}
+
+template <class ELFT>
 std::pair<OutputSectionBase<ELFT> *, bool>
 OutputSectionFactory<ELFT>::create(InputSectionBase<ELFT> *C,
                                    StringRef OutsecName) {
@@ -1762,6 +1802,9 @@ OutputSectionFactory<ELFT>::create(Input
   case InputSectionBase<ELFT>::MipsOptions:
     Sec = new MipsOptionsOutputSection<ELFT>();
     break;
+  case InputSectionBase<ELFT>::MipsAbiFlags:
+    Sec = new MipsAbiFlagsOutputSection<ELFT>();
+    break;
   case InputSectionBase<ELFT>::Layout:
     llvm_unreachable("Invalid section type");
   }
@@ -1891,6 +1934,11 @@ template class MipsOptionsOutputSection<
 template class MipsOptionsOutputSection<ELF64LE>;
 template class MipsOptionsOutputSection<ELF64BE>;
 
+template class MipsAbiFlagsOutputSection<ELF32LE>;
+template class MipsAbiFlagsOutputSection<ELF32BE>;
+template class MipsAbiFlagsOutputSection<ELF64LE>;
+template class MipsAbiFlagsOutputSection<ELF64BE>;
+
 template class MergeOutputSection<ELF32LE>;
 template class MergeOutputSection<ELF32BE>;
 template class MergeOutputSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Aug 12 01:28:49 2016
@@ -62,6 +62,7 @@ public:
     Merge,
     MipsReginfo,
     MipsOptions,
+    MipsAbiFlags,
     Plt,
     Regular,
     Reloc,
@@ -642,6 +643,24 @@ private:
   uint32_t GprMask = 0;
 };
 
+template <class ELFT>
+class MipsAbiFlagsOutputSection final : public OutputSectionBase<ELFT> {
+  typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
+  typedef OutputSectionBase<ELFT> Base;
+
+public:
+  MipsAbiFlagsOutputSection();
+  void writeTo(uint8_t *Buf) override;
+  void addSection(InputSectionBase<ELFT> *S) override;
+  typename Base::Kind getKind() const override { return Base::MipsAbiFlags; }
+  static bool classof(const Base *B) {
+    return B->getKind() == Base::MipsAbiFlags;
+  }
+
+private:
+  Elf_Mips_ABIFlags Flags;
+};
+
 // --eh-frame-hdr option tells linker to construct a header for all the
 // .eh_frame sections. This header is placed to a section named .eh_frame_hdr
 // and also to a PT_GNU_EH_FRAME segment.

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Fri Aug 12 01:28:49 2016
@@ -46,6 +46,9 @@ llvm::StringRef getOutputSectionName(Inp
 template <class ELFT> void reportDiscarded(InputSectionBase<ELFT> *IS);
 
 template <class ELFT> uint32_t getMipsEFlags();
+
+uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
+                         llvm::StringRef FileName);
 }
 }
 

Modified: lld/trunk/test/ELF/basic-mips.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/basic-mips.s?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/test/ELF/basic-mips.s (original)
+++ lld/trunk/test/ELF/basic-mips.s Fri Aug 12 01:28:49 2016
@@ -83,7 +83,7 @@ __start:
 # CHECK-NEXT:     Link: 0
 # CHECK-NEXT:     Info: 0
 # CHECK-NEXT:     AddressAlignment: 8
-# CHECK-NEXT:     EntrySize: 0
+# CHECK-NEXT:     EntrySize: 24
 # CHECK-NEXT:   }
 # CHECK-NEXT:   Section {
 # CHECK-NEXT:     Index: 3

Modified: lld/trunk/test/ELF/mips-elf-flags-err.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-elf-flags-err.s?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-elf-flags-err.s (original)
+++ lld/trunk/test/ELF/mips-elf-flags-err.s Fri Aug 12 01:28:49 2016
@@ -10,10 +10,10 @@
 # Check that lld does not allow to link incompatible ISAs.
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
-# RUN:         -mcpu=mips32 %S/Inputs/mips-dynamic.s -o %t1.o
+# RUN:         -mcpu=mips3 %S/Inputs/mips-dynamic.s -o %t1.o
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
-# RUN:         -mcpu=mips32r6 %s -o %t2.o
-# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=R1R6 %s
+# RUN:         -mcpu=mips32 -mattr=+fp64 %s -o %t2.o
+# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=R3R32 %s
 
 # Check that lld does not allow to link incompatible ISAs.
 
@@ -24,6 +24,14 @@
 # RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 \
 # RUN:   | FileCheck -check-prefix=R6OCTEON %s
 
+# Check that lld does not allow to link incompatible floating point ABI.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         -mcpu=mips32 %S/Inputs/mips-dynamic.s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         -mcpu=mips32 -mattr=+fp64 %s -o %t2.o
+# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=FPABI %s
+
 # Check that lld take in account EF_MIPS_MACH_XXX ISA flags
 
 # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
@@ -63,8 +71,9 @@ __start:
 # R1R2-NEXT:   EF_MIPS_CPIC
 # R1R2-NEXT: ]
 
-# R1R6: target ISA 'mips32' is incompatible with 'mips32r6': {{.*}}mips-elf-flags-err.s.tmp2.o
+# R3R32: target ISA 'mips3' is incompatible with 'mips32': {{.*}}mips-elf-flags-err.s.tmp2.o
 # R6OCTEON: target ISA 'mips64r6' is incompatible with 'octeon': {{.*}}mips-elf-flags-err.s.tmp2.o
+# FPABI: target floating point ABI '-mdouble-float' is incompatible with '-mgp32 -mfp64': {{.*}}mips-elf-flags-err.s.tmp2.o
 
 # OCTEON:      Flags [
 # OCTEON-NEXT:   EF_MIPS_ARCH_64R2

Modified: lld/trunk/test/ELF/mips-elf-flags.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-elf-flags.s?rev=278482&r1=278481&r2=278482&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-elf-flags.s (original)
+++ lld/trunk/test/ELF/mips-elf-flags.s Fri Aug 12 01:28:49 2016
@@ -3,33 +3,37 @@
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
 # RUN:         %S/Inputs/mips-dynamic.s -o %t-so.o
 # RUN: ld.lld %t-so.o -shared -o %t.so
-# RUN: llvm-readobj -h %t.so | FileCheck -check-prefix=SO %s
+# RUN: llvm-readobj -h -mips-abi-flags %t.so | FileCheck -check-prefix=SO %s
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
 # RUN: ld.lld %t.o -o %t.exe
-# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=EXE %s
+# RUN: llvm-readobj -h -mips-abi-flags %t.exe | FileCheck -check-prefix=EXE %s
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
 # RUN:         -mcpu=mips32r2 %s -o %t-r2.o
 # RUN: ld.lld %t-r2.o -o %t-r2.exe
-# RUN: llvm-readobj -h %t-r2.exe | FileCheck -check-prefix=EXE-R2 %s
+# RUN: llvm-readobj -h -mips-abi-flags %t-r2.exe \
+# RUN:   | FileCheck -check-prefix=EXE-R2 %s
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
 # RUN:         -mcpu=mips32r2 %s -o %t-r2.o
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
 # RUN:         -mcpu=mips32r5 %S/Inputs/mips-dynamic.s -o %t-r5.o
 # RUN: ld.lld %t-r2.o %t-r5.o -o %t-r5.exe
-# RUN: llvm-readobj -h %t-r5.exe | FileCheck -check-prefix=EXE-R5 %s
+# RUN: llvm-readobj -h -mips-abi-flags %t-r5.exe \
+# RUN:   | FileCheck -check-prefix=EXE-R5 %s
 
 # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
 # RUN:         -mcpu=mips32r6 %s -o %t-r6.o
 # RUN: ld.lld %t-r6.o -o %t-r6.exe
-# RUN: llvm-readobj -h %t-r6.exe | FileCheck -check-prefix=EXE-R6 %s
+# RUN: llvm-readobj -h -mips-abi-flags %t-r6.exe \
+# RUN:   | FileCheck -check-prefix=EXE-R6 %s
 
 # RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
 # RUN:         -mcpu=octeon %s -o %t.o
 # RUN: ld.lld %t.o -o %t.exe
-# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=OCTEON %s
+# RUN: llvm-readobj -h -mips-abi-flags %t.exe \
+# RUN:   | FileCheck -check-prefix=OCTEON %s
 
 # REQUIRES: mips
 
@@ -44,24 +48,84 @@ __start:
 # SO-NEXT:   EF_MIPS_CPIC
 # SO-NEXT:   EF_MIPS_PIC
 # SO-NEXT: ]
+# SO:      MIPS ABI Flags {
+# SO-NEXT:   Version: 0
+# SO-NEXT:   ISA: MIPS32
+# SO-NEXT:   ISA Extension: None
+# SO-NEXT:   ASEs [
+# SO-NEXT:   ]
+# SO-NEXT:   FP ABI: Hard float (double precision)
+# SO-NEXT:   GPR size: 32
+# SO-NEXT:   CPR1 size: 32
+# SO-NEXT:   CPR2 size: 0
+# SO-NEXT:   Flags 1 [
+# SO-NEXT:     ODDSPREG
+# SO-NEXT:   ]
+# SO-NEXT:   Flags 2: 0x0
+# SO-NEXT: }
 
 # EXE:      Flags [
 # EXE-NEXT:   EF_MIPS_ABI_O32
 # EXE-NEXT:   EF_MIPS_ARCH_32
 # EXE-NEXT:   EF_MIPS_CPIC
 # EXE-NEXT: ]
+# EXE:      MIPS ABI Flags {
+# EXE-NEXT:   Version: 0
+# EXE-NEXT:   ISA: MIPS32
+# EXE-NEXT:   ISA Extension: None
+# EXE-NEXT:   ASEs [
+# EXE-NEXT:   ]
+# EXE-NEXT:   FP ABI: Hard float (double precision)
+# EXE-NEXT:   GPR size: 32
+# EXE-NEXT:   CPR1 size: 32
+# EXE-NEXT:   CPR2 size: 0
+# EXE-NEXT:   Flags 1 [
+# EXE-NEXT:     ODDSPREG
+# EXE-NEXT:   ]
+# EXE-NEXT:   Flags 2: 0x0
+# EXE-NEXT: }
 
 # EXE-R2:      Flags [
 # EXE-R2-NEXT:   EF_MIPS_ABI_O32
 # EXE-R2-NEXT:   EF_MIPS_ARCH_32R2
 # EXE-R2-NEXT:   EF_MIPS_CPIC
 # EXE-R2-NEXT: ]
+# EXE-R2:      MIPS ABI Flags {
+# EXE-R2-NEXT:   Version: 0
+# EXE-R2-NEXT:   ISA: MIPS32r2
+# EXE-R2-NEXT:   ISA Extension: None
+# EXE-R2-NEXT:   ASEs [
+# EXE-R2-NEXT:   ]
+# EXE-R2-NEXT:   FP ABI: Hard float (double precision)
+# EXE-R2-NEXT:   GPR size: 32
+# EXE-R2-NEXT:   CPR1 size: 32
+# EXE-R2-NEXT:   CPR2 size: 0
+# EXE-R2-NEXT:   Flags 1 [
+# EXE-R2-NEXT:     ODDSPREG
+# EXE-R2-NEXT:   ]
+# EXE-R2-NEXT:   Flags 2: 0x0
+# EXE-R2-NEXT: }
 
 # EXE-R5:      Flags [
 # EXE-R5-NEXT:   EF_MIPS_ABI_O32
 # EXE-R5-NEXT:   EF_MIPS_ARCH_32R2
 # EXE-R5-NEXT:   EF_MIPS_CPIC
 # EXE-R5-NEXT: ]
+# EXE-R5:      MIPS ABI Flags {
+# EXE-R5-NEXT:   Version: 0
+# EXE-R5-NEXT:   ISA: MIPS32r5
+# EXE-R5-NEXT:   ISA Extension: None
+# EXE-R5-NEXT:   ASEs [
+# EXE-R5-NEXT:   ]
+# EXE-R5-NEXT:   FP ABI: Hard float (double precision)
+# EXE-R5-NEXT:   GPR size: 32
+# EXE-R5-NEXT:   CPR1 size: 32
+# EXE-R5-NEXT:   CPR2 size: 0
+# EXE-R5-NEXT:   Flags 1 [
+# EXE-R5-NEXT:     ODDSPREG
+# EXE-R5-NEXT:   ]
+# EXE-R5-NEXT:   Flags 2: 0x0
+# EXE-R5-NEXT: }
 
 # EXE-R6:      Flags [
 # EXE-R6-NEXT:   EF_MIPS_ABI_O32
@@ -69,6 +133,21 @@ __start:
 # EXE-R6-NEXT:   EF_MIPS_CPIC
 # EXE-R6-NEXT:   EF_MIPS_NAN2008
 # EXE-R6-NEXT: ]
+# EXE-R6:      MIPS ABI Flags {
+# EXE-R6-NEXT:   Version: 0
+# EXE-R6-NEXT:   ISA: MIPS32
+# EXE-R6-NEXT:   ISA Extension: None
+# EXE-R6-NEXT:   ASEs [
+# EXE-R6-NEXT:   ]
+# EXE-R6-NEXT:   FP ABI: Hard float (32-bit CPU, 64-bit FPU)
+# EXE-R6-NEXT:   GPR size: 32
+# EXE-R6-NEXT:   CPR1 size: 64
+# EXE-R6-NEXT:   CPR2 size: 0
+# EXE-R6-NEXT:   Flags 1 [
+# EXE-R6-NEXT:     ODDSPREG
+# EXE-R6-NEXT:   ]
+# EXE-R6-NEXT:   Flags 2: 0x0
+# EXE-R6-NEXT: }
 
 # OCTEON:      Flags [
 # OCTEON-NEXT:   EF_MIPS_ARCH_64R2
@@ -76,3 +155,18 @@ __start:
 # OCTEON-NEXT:   EF_MIPS_MACH_OCTEON
 # OCTEON-NEXT:   EF_MIPS_PIC
 # OCTEON-NEXT: ]
+# OCTEON:      MIPS ABI Flags {
+# OCTEON-NEXT:   Version: 0
+# OCTEON-NEXT:   ISA: MIPS64r2
+# OCTEON-NEXT:   ISA Extension: Cavium Networks Octeon
+# OCTEON-NEXT:   ASEs [
+# OCTEON-NEXT:   ]
+# OCTEON-NEXT:   FP ABI: Hard float (double precision)
+# OCTEON-NEXT:   GPR size: 64
+# OCTEON-NEXT:   CPR1 size: 64
+# OCTEON-NEXT:   CPR2 size: 0
+# OCTEON-NEXT:   Flags 1 [
+# OCTEON-NEXT:     ODDSPREG
+# OCTEON-NEXT:   ]
+# OCTEON-NEXT:   Flags 2: 0x0
+# OCTEON-NEXT: }




More information about the llvm-commits mailing list