Initial 64 bit direct object support.
authorAkira Hatanaka <ahatanaka@mips.com>
Mon, 2 Apr 2012 19:25:22 +0000 (19:25 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Mon, 2 Apr 2012 19:25:22 +0000 (19:25 +0000)
This patch allows llvm to recognize that a 64 bit object file is being produced
and that the subsequently generated ELF header has the correct information.

The test case checks for both big and little endian flavors.

Patch by Jack Carter.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153889 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/ELF.h
lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
test/MC/Mips/elf_basic.s

index 052fc5135ff9e5630eb2731d05b158f9ae9a2208..04953b6e5657b9bb7040dba3986a1b25d01613a4 100644 (file)
@@ -609,8 +609,10 @@ enum {
   EF_MIPS_ARCH_3    = 0x20000000, // MIPS3 instruction set
   EF_MIPS_ARCH_4    = 0x30000000, // MIPS4 instruction set
   EF_MIPS_ARCH_5    = 0x40000000, // MIPS5 instruction set
-  EF_MIPS_ARCH_32   = 0x60000000, // MIPS32 instruction set
+  EF_MIPS_ARCH_32   = 0x50000000, // MIPS32 instruction set per linux not elf.h
+  EF_MIPS_ARCH_64   = 0x60000000, // MIPS64 instruction set per linux not elf.h
   EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
+  EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2
   EF_MIPS_ARCH      = 0xf0000000  // Mask for applying EF_MIPS_ARCH_ variant
 };
 
index ea86f48f09af5f08fd660a0763c91116b35f9f57..e79be3363623b60cbb0f9f5df0d9f0cf55406523 100644 (file)
@@ -67,13 +67,15 @@ namespace {
 class MipsAsmBackend : public MCAsmBackend {
   Triple::OSType OSType;
   bool IsLittle; // Big or little endian
+  bool Is64Bit;  // 32 or 64 bit words
 
 public:
-  MipsAsmBackend(const Target &T,  Triple::OSType _OSType, bool _isLittle) :
-    MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle) {}
+  MipsAsmBackend(const Target &T,  Triple::OSType _OSType,
+                 bool _isLittle, bool _is64Bit)
+    :MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle), Is64Bit(_is64Bit) {}
 
   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
-    return createMipsELFObjectWriter(OS, OSType, IsLittle);
+    return createMipsELFObjectWriter(OS, OSType, IsLittle, Is64Bit);
   }
 
   /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
@@ -208,17 +210,28 @@ public:
   bool writeNopData(uint64_t Count, MCObjectWriter *OW) const {
     return true;
   }
-};
+}; // class MipsAsmBackend
 
 } // namespace
 
 // MCAsmBackend
-MCAsmBackend *llvm::createMipsAsmBackendEL(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, StringRef TT) {
   return new MipsAsmBackend(T, Triple(TT).getOS(),
-                            /*IsLittle*/true);
+                            /*IsLittle*/true, /*Is64Bit*/false);
 }
 
-MCAsmBackend *llvm::createMipsAsmBackendEB(const Target &T, StringRef TT) {
+MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, StringRef TT) {
   return new MipsAsmBackend(T, Triple(TT).getOS(),
-                            /*IsLittle*/false);
+                            /*IsLittle*/false, /*Is64Bit*/false);
 }
+
+MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, StringRef TT) {
+  return new MipsAsmBackend(T, Triple(TT).getOS(),
+                            /*IsLittle*/true, /*Is64Bit*/true);
+}
+
+MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT) {
+  return new MipsAsmBackend(T, Triple(TT).getOS(),
+                            /*IsLittle*/false, /*Is64Bit*/true);
+}
+
index f12f9af7471a837f78c4aa8ed69811ad87da70df..2091bec500824b2d636a019d4a3e7317d0463f74 100644 (file)
@@ -34,7 +34,7 @@ namespace {
 
   class MipsELFObjectWriter : public MCELFObjectTargetWriter {
   public:
-    MipsELFObjectWriter(uint8_t OSABI);
+    MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI);
 
     virtual ~MipsELFObjectWriter();
 
@@ -52,15 +52,23 @@ namespace {
   };
 }
 
-MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI)
-  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MIPS,
+MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI)
+  : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS,
                             /*HasRelocationAddend*/ false) {}
 
 MipsELFObjectWriter::~MipsELFObjectWriter() {}
 
-// FIXME: get the real EABI Version from the Triple.
+// FIXME: get the real EABI Version from the Subtarget class.
 unsigned MipsELFObjectWriter::getEFlags() const {
-  return ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_ARCH_32R2;
+
+  // FIXME: We can't tell if we are PIC (dynamic) or CPIC (static)
+  unsigned Flag = ELF::EF_MIPS_NOREORDER;
+
+  if (is64Bit())
+    Flag |= ELF::EF_MIPS_ARCH_64R2;
+  else
+    Flag |= ELF::EF_MIPS_ARCH_32R2;
+  return Flag;
 }
 
 const MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
@@ -232,8 +240,10 @@ void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
     Relocs[--I] = R->Reloc;
 }
 
-MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, uint8_t OSABI,
-                                                bool IsLittleEndian) {
-  MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(OSABI);
+MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS,
+                                                uint8_t OSABI,
+                                                bool IsLittleEndian,
+                                                bool Is64Bit) {
+  MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI);
   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
 }
index 7be6f81ac88c617605734d5488dcd279c2888272..3c544f6aec9017283a9720424c5f8879542b3f8f 100644 (file)
@@ -145,13 +145,13 @@ extern "C" void LLVMInitializeMipsTargetMC() {
 
   // Register the asm backend.
   TargetRegistry::RegisterMCAsmBackend(TheMipsTarget,
-                                       createMipsAsmBackendEB);
+                                       createMipsAsmBackendEB32);
   TargetRegistry::RegisterMCAsmBackend(TheMipselTarget,
-                                       createMipsAsmBackendEL);
+                                       createMipsAsmBackendEL32);
   TargetRegistry::RegisterMCAsmBackend(TheMips64Target,
-                                       createMipsAsmBackendEB);
+                                       createMipsAsmBackendEB64);
   TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget,
-                                       createMipsAsmBackendEL);
+                                       createMipsAsmBackendEL64);
 
   // Register the MC subtarget info.
   TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget,
index 2e58f9d1cf6ee95a827964c37653736d6da03d2e..547ccddd78eab8ffe32566a8200effd1cb820f9d 100644 (file)
@@ -39,12 +39,15 @@ MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
                                          const MCSubtargetInfo &STI,
                                          MCContext &Ctx);
 
-MCAsmBackend *createMipsAsmBackendEB(const Target &T, StringRef TT);
-MCAsmBackend *createMipsAsmBackendEL(const Target &T, StringRef TT);
+MCAsmBackend *createMipsAsmBackendEB32(const Target &T, StringRef TT);
+MCAsmBackend *createMipsAsmBackendEL32(const Target &T, StringRef TT);
+MCAsmBackend *createMipsAsmBackendEB64(const Target &T, StringRef TT);
+MCAsmBackend *createMipsAsmBackendEL64(const Target &T, StringRef TT);
 
 MCObjectWriter *createMipsELFObjectWriter(raw_ostream &OS,
                                           uint8_t OSABI,
-                                          bool IsLittleEndian);
+                                          bool IsLittleEndian,
+                                          bool Is64Bit);
 } // End llvm namespace
 
 // Defines symbolic names for Mips registers.  This defines a mapping from
index f7ed348b1bdb0538eba3a04a80147b8755a2157b..7a79fa066be48770e6b783f8b41e2c456409b7f7 100644 (file)
@@ -1,7 +1,32 @@
-// RUN: llvm-mc -filetype=obj -triple mips-unknown-linux %s -o - | elf-dump --dump-section-data  | FileCheck -check-prefix=CHECK-BE %s
-// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o - | elf-dump --dump-section-data  | FileCheck -check-prefix=CHECK-LE %s
+// 32 bit big endian
+// RUN: llvm-mc -filetype=obj -triple mips-unknown-linux %s -o - | elf-dump --dump-section-data  | FileCheck -check-prefix=CHECK-BE32 %s
+// 32 bit little endian
+// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o - | elf-dump --dump-section-data  | FileCheck -check-prefix=CHECK-LE32 %s
+// 64 bit big endian
+// RUN: llvm-mc -filetype=obj -arch=mips64 -triple mips64-unknown-linux %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-BE64 %s
+// 64 bit little endian
+// RUN: llvm-mc -filetype=obj -arch=mips64el -triple mips64el-unknown-linux %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=CHECK-LE64 %s
 
-// Check that we produce the correct endian.
+// Check that we produce 32 bit with each endian.
 
-// CHECK-BE: ('e_indent[EI_DATA]', 0x02)
-// CHECK-LE: ('e_indent[EI_DATA]', 0x01)
+// This is 32 bit.
+// CHECK-BE32: ('e_indent[EI_CLASS]', 0x01)
+// This is big endian.
+// CHECK-BE32: ('e_indent[EI_DATA]', 0x02)
+
+// This is 32 bit.
+// CHECK-LE32: ('e_indent[EI_CLASS]', 0x01)
+// This is little endian.
+// CHECK-LE32: ('e_indent[EI_DATA]', 0x01)
+
+// Check that we produce 64 bit with each endian.
+
+// This is 64 bit.
+// CHECK-BE64: ('e_indent[EI_CLASS]', 0x02)
+// This is big endian.
+// CHECK-BE64: ('e_indent[EI_DATA]', 0x02)
+
+// This is 64 bit.
+// CHECK-LE64: ('e_indent[EI_CLASS]', 0x02)
+// This is little endian.
+// CHECK-LE64: ('e_indent[EI_DATA]', 0x01)