AMDGPU: Add and set AMDGPU-specific e_flags
authorKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Thu, 5 Oct 2017 16:19:18 +0000 (16:19 +0000)
committerKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Thu, 5 Oct 2017 16:19:18 +0000 (16:19 +0000)
Differential Revision: https://reviews.llvm.org/D38556

llvm-svn: 314987

13 files changed:
llvm/include/llvm/BinaryFormat/ELF.h
llvm/include/llvm/Object/ELFObjectFile.h
llvm/lib/ObjectYAML/ELFYAML.cpp
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
llvm/test/CodeGen/AMDGPU/elf-header.ll
llvm/test/Object/AMDGPU/elf32-r600-definitions.yaml [new file with mode: 0644]
llvm/test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml
llvm/test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml
llvm/test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml
llvm/test/tools/llvm-readobj/amdgpu-elf-definitions.test
llvm/tools/llvm-readobj/ELFDumper.cpp

index 712e67ef52a8460708c9474110c1616f8468b6be..5a0cf2cee20041302a84cd33448998a00e2515ba 100644 (file)
@@ -647,6 +647,15 @@ enum {
 #include "ELFRelocs/WebAssembly.def"
 };
 
+// AMDGPU specific e_flags.
+enum : unsigned {
+  // AMDGPU machine architectures.
+  EF_AMDGPU_ARCH_NONE = 0x00000000, // None/unknown.
+  EF_AMDGPU_ARCH_R600 = 0x00000001, // AMD HD2XXX-HD6XXX GPUs.
+  EF_AMDGPU_ARCH_GCN = 0x00000002,  // AMD GCN GFX6+ GPUs.
+  EF_AMDGPU_ARCH = 0x0000000f       // EF_AMDGPU_ARCH_XXX selection mask.
+};
+
 // ELF Relocation types for AMDGPU
 enum {
 #include "ELFRelocs/AMDGPU.def"
index b4411ce984ea4f196637f32162b2812e5b962934..6d4a3808392276836fb6fdcac3de664c76485bda 100644 (file)
@@ -1063,14 +1063,20 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
     default: return Triple::UnknownArch;
     }
 
-  case ELF::EM_AMDGPU:
-    if (EF.getHeader()->e_ident[ELF::EI_CLASS] != ELF::ELFCLASS64)
-      return Triple::UnknownArch;
+  case ELF::EM_AMDGPU: {
     if (!IsLittleEndian)
       return Triple::UnknownArch;
 
-    // TODO: Determine r600/amdgcn architecture based e_flags.
-    return Triple::amdgcn;
+    unsigned EFlags = EF.getHeader()->e_flags;
+    switch (EFlags & ELF::EF_AMDGPU_ARCH) {
+    case ELF::EF_AMDGPU_ARCH_R600:
+      return Triple::r600;
+    case ELF::EF_AMDGPU_ARCH_GCN:
+      return Triple::amdgcn;
+    default:
+      return Triple::UnknownArch;
+    }
+  }
 
   case ELF::EM_BPF:
     return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
index 36db8eae5ba6b176a468aaa9910bc08aae10d50d..dee820c21cb6bc96772bd71a1d6756b215ce3384 100644 (file)
@@ -246,7 +246,6 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
   ECase(ELFOSABI_HPUX);
   ECase(ELFOSABI_NETBSD);
   ECase(ELFOSABI_GNU);
-  ECase(ELFOSABI_GNU);
   ECase(ELFOSABI_HURD);
   ECase(ELFOSABI_SOLARIS);
   ECase(ELFOSABI_AIX);
@@ -370,6 +369,9 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
     BCase(EF_RISCV_RVE);
     break;
   case ELF::EM_AMDGPU:
+    BCaseMask(EF_AMDGPU_ARCH_R600, EF_AMDGPU_ARCH);
+    BCaseMask(EF_AMDGPU_ARCH_GCN, EF_AMDGPU_ARCH);
+    break;
   case ELF::EM_X86_64:
     break;
   default:
index 43338a5bebd26825120c9394ec621339d93a342c..bfdb7d7cff7659aa24860800f5e189971069f001 100644 (file)
@@ -9,13 +9,37 @@
 
 #include "AMDGPUELFStreamer.h"
 #include "Utils/AMDGPUBaseInfo.h"
+#include "llvm/BinaryFormat/ELF.h"
 
 using namespace llvm;
 
-MCELFStreamer *llvm::createAMDGPUELFStreamer(MCContext &Context,
-                                           MCAsmBackend &MAB,
-                                           raw_pwrite_stream &OS,
-                                           MCCodeEmitter *Emitter,
-                                           bool RelaxAll) {
-  return new AMDGPUELFStreamer(Context, MAB, OS, Emitter);
+AMDGPUELFStreamer::AMDGPUELFStreamer(const Triple &T, MCContext &Context,
+                                     MCAsmBackend &MAB, raw_pwrite_stream &OS,
+                                     MCCodeEmitter *Emitter)
+    : MCELFStreamer(Context, MAB, OS, Emitter) {
+  unsigned Arch = ELF::EF_AMDGPU_ARCH_NONE;
+  switch (T.getArch()) {
+  case Triple::r600:
+    Arch = ELF::EF_AMDGPU_ARCH_R600;
+    break;
+  case Triple::amdgcn:
+    Arch = ELF::EF_AMDGPU_ARCH_GCN;
+    break;
+  default:
+    break;
+  }
+
+  MCAssembler &MCA = getAssembler();
+  unsigned EFlags = MCA.getELFHeaderEFlags();
+  EFlags &= ~ELF::EF_AMDGPU_ARCH;
+  EFlags |= Arch;
+  MCA.setELFHeaderEFlags(EFlags);
+}
+
+MCELFStreamer *llvm::createAMDGPUELFStreamer(const Triple &T, MCContext &Context,
+                                             MCAsmBackend &MAB,
+                                             raw_pwrite_stream &OS,
+                                             MCCodeEmitter *Emitter,
+                                             bool RelaxAll) {
+  return new AMDGPUELFStreamer(T, Context, MAB, OS, Emitter);
 }
index 5319b65d65f92036c05572fe247a6590937b995a..386aa56c807c6c0abe43fb9056bdcae705e380f4 100644 (file)
@@ -25,15 +25,13 @@ class MCSubtargetInfo;
 
 class AMDGPUELFStreamer : public MCELFStreamer {
 public:
-  AMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS,
-                  MCCodeEmitter *Emitter)
-      : MCELFStreamer(Context, MAB, OS, Emitter) { }
-
+  AMDGPUELFStreamer(const Triple &T, MCContext &Context, MCAsmBackend &MAB,
+                    raw_pwrite_stream &OS, MCCodeEmitter *Emitter);
 };
 
-MCELFStreamer *createAMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB,
-                                     raw_pwrite_stream &OS,
-                                     MCCodeEmitter *Emitter, bool RelaxAll);
+MCELFStreamer *createAMDGPUELFStreamer(const Triple &T, MCContext &Context,
+                                       MCAsmBackend &MAB, raw_pwrite_stream &OS,
+                                       MCCodeEmitter *Emitter, bool RelaxAll);
 } // namespace llvm.
 
 #endif
index 2968d834a5eb31f2500bf47701ef4bba7d3ea2bf..1682fc5e49bfaca7b67c9f446371a61f7360735a 100644 (file)
@@ -80,10 +80,7 @@ static MCTargetStreamer * createAMDGPUObjectTargetStreamer(
 static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
                                     MCAsmBackend &MAB, raw_pwrite_stream &OS,
                                     MCCodeEmitter *Emitter, bool RelaxAll) {
-  if (T.getOS() == Triple::AMDHSA)
-    return createAMDGPUELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
-
-  return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+  return createAMDGPUELFStreamer(T, Context, MAB, OS, Emitter, RelaxAll);
 }
 
 extern "C" void LLVMInitializeAMDGPUTargetMC() {
index de9714cef97e4e0ae916af425071ddb26d33e080..192eb780f70e8cc9f410909fd090b418f5a1ef37 100644 (file)
 ; RUN: llc -mtriple=amdgcn-unknown-mesa3d -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck --check-prefix=GCN --check-prefix=GCN-OSABI-MESA3D %s
 
 ; R600: Format: ELF32-amdgpu
-; R600: Arch: unknown
+; R600: Arch: r600
 ; R600: AddressSize: 32bit
-; GCN: Format: ELF64-amdgpu
-; GCN: Arch: amdgcn
-; GCN: AddressSize: 64bit
+; GCN:  Format: ELF64-amdgpu
+; GCN:  Arch: amdgcn
+; GCN:  AddressSize: 64bit
 
 ; R600-OSABI-NONE:  OS/ABI: SystemV (0x0)
 ; GCN-OSABI-NONE:   OS/ABI: SystemV (0x0)
 ; GCN-OSABI-MESA3D: OS/ABI: AMDGPU_MESA3D (0x42)
 
 ; R600: Machine: EM_AMDGPU (0xE0)
-; GCN: Machine: EM_AMDGPU (0xE0)
+; R600: Flags [ (0x1)
+; R600:   EF_AMDGPU_ARCH_R600 (0x1)
+; R600: ]
+; GCN:  Machine: EM_AMDGPU (0xE0)
+; GCN:  Flags [ (0x2)
+; GCN:    EF_AMDGPU_ARCH_GCN (0x2)
+; GCN:  ]
 
 define amdgpu_kernel void @elf_header() {
   ret void
-}
\ No newline at end of file
+}
diff --git a/llvm/test/Object/AMDGPU/elf32-r600-definitions.yaml b/llvm/test/Object/AMDGPU/elf32-r600-definitions.yaml
new file mode 100644 (file)
index 0000000..56c5f29
--- /dev/null
@@ -0,0 +1,34 @@
+# RUN: yaml2obj %s > %t.o
+# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s
+# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s
+
+# ELF: Format: ELF32-amdgpu
+# ELF: Arch: r600
+# ELF: ElfHeader {
+# ELF:   Ident {
+# ELF:     OS/ABI: AMDGPU_HSA (0x40)
+# ELF:     ABIVersion: 0
+# ELF:   }
+# ELF:   Machine: EM_AMDGPU (0xE0)
+# ELF:   Flags [ (0x1)
+# ELF:     EF_AMDGPU_ARCH_R600 (0x1)
+# ELF:   ]
+# ELF: }
+
+# YAML: FileHeader
+# YAML:   Class:   ELFCLASS32
+# YAML:   Data:    ELFDATA2LSB
+# YAML:   OSABI:   ELFOSABI_AMDGPU_HSA
+# YAML:   Type:    ET_REL
+# YAML:   Machine: EM_AMDGPU
+# YAML:   Flags:   [ EF_AMDGPU_ARCH_R600 ]
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  OSABI:   ELFOSABI_AMDGPU_HSA
+  Type:    ET_REL
+  Machine: EM_AMDGPU
+  Flags:   [ EF_AMDGPU_ARCH_R600 ]
+...
index 53639e001584f62cf556748306f8efe4058858bf..1ffea244d3f02286a13743b8328db5c79b14b72f 100644 (file)
@@ -1,21 +1,34 @@
 # RUN: yaml2obj %s > %t.o
-# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s
+# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s
+# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s
 
-# CHECK: Format: ELF64-amdgpu
-# CHECK: Arch: amdgcn
-# CHECK: ElfHeader {
-# CHECK:   Ident {
-# CHECK:     OS/ABI: AMDGPU_HSA (0x40)
-# CHECK:     ABIVersion: 0
-# CHECK:   }
-# CHECK:   Machine: EM_AMDGPU (0xE0)
-# CHECK: }
+# ELF: Format: ELF64-amdgpu
+# ELF: Arch: amdgcn
+# ELF: ElfHeader {
+# ELF:   Ident {
+# ELF:     OS/ABI: AMDGPU_HSA (0x40)
+# ELF:     ABIVersion: 0
+# ELF:   }
+# ELF:   Machine: EM_AMDGPU (0xE0)
+# ELF:   Flags [ (0x2)
+# ELF:     EF_AMDGPU_ARCH_GCN (0x2)
+# ELF:   ]
+# ELF: }
+
+# YAML: FileHeader
+# YAML:   Class:   ELFCLASS64
+# YAML:   Data:    ELFDATA2LSB
+# YAML:   OSABI:   ELFOSABI_AMDGPU_HSA
+# YAML:   Type:    ET_REL
+# YAML:   Machine: EM_AMDGPU
+# YAML:   Flags:   [ EF_AMDGPU_ARCH_GCN ]
 
 --- !ELF
 FileHeader:
   Class:   ELFCLASS64
   Data:    ELFDATA2LSB
+  OSABI:   ELFOSABI_AMDGPU_HSA
   Type:    ET_REL
   Machine: EM_AMDGPU
-  OSABI:   ELFOSABI_AMDGPU_HSA
+  Flags:   [ EF_AMDGPU_ARCH_GCN ]
 ...
index 8e39f6d32eb34ef07e490f8c7aaae56a9e7bd65e..3ec5fe51083163ba9bb80050b66e60c16d9db01e 100644 (file)
@@ -1,21 +1,34 @@
 # RUN: yaml2obj %s > %t.o
-# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s
+# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s
+# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s
 
-# CHECK: Format: ELF64-amdgpu
-# CHECK: Arch: amdgcn
-# CHECK: ElfHeader {
-# CHECK:   Ident {
-# CHECK:     OS/ABI: AMDGPU_PAL (0x41)
-# CHECK:     ABIVersion: 0
-# CHECK:   }
-# CHECK:   Machine: EM_AMDGPU (0xE0)
-# CHECK: }
+# ELF: Format: ELF64-amdgpu
+# ELF: Arch: amdgcn
+# ELF: ElfHeader {
+# ELF:   Ident {
+# ELF:     OS/ABI: AMDGPU_PAL (0x41)
+# ELF:     ABIVersion: 0
+# ELF:   }
+# ELF:   Machine: EM_AMDGPU (0xE0)
+# ELF:   Flags [ (0x2)
+# ELF:     EF_AMDGPU_ARCH_GCN (0x2)
+# ELF:   ]
+# ELF: }
+
+# YAML: FileHeader
+# YAML:   Class:   ELFCLASS64
+# YAML:   Data:    ELFDATA2LSB
+# YAML:   OSABI:   ELFOSABI_AMDGPU_PAL
+# YAML:   Type:    ET_REL
+# YAML:   Machine: EM_AMDGPU
+# YAML:   Flags:   [ EF_AMDGPU_ARCH_GCN ]
 
 --- !ELF
 FileHeader:
   Class:   ELFCLASS64
   Data:    ELFDATA2LSB
+  OSABI:   ELFOSABI_AMDGPU_PAL
   Type:    ET_REL
   Machine: EM_AMDGPU
-  OSABI:   ELFOSABI_AMDGPU_PAL
+  Flags:   [ EF_AMDGPU_ARCH_GCN ]
 ...
index 7fa413f64a1a5f9ad9f42d8801cd855a79d2f434..258bb122ca945c1861631e3f1527148944e2c201 100644 (file)
@@ -1,21 +1,34 @@
 # RUN: yaml2obj %s > %t.o
-# RUN: llvm-readobj -s -file-headers %t.o | FileCheck %s
+# RUN: llvm-readobj -s -file-headers %t.o | FileCheck --check-prefix=ELF %s
+# RUN: obj2yaml %t.o | FileCheck --check-prefix=YAML %s
 
-# CHECK: Format: ELF64-amdgpu
-# CHECK: Arch: amdgcn
-# CHECK: ElfHeader {
-# CHECK:   Ident {
-# CHECK:     OS/ABI: AMDGPU_MESA3D (0x42)
-# CHECK:     ABIVersion: 0
-# CHECK:   }
-# CHECK:   Machine: EM_AMDGPU (0xE0)
-# CHECK: }
+# ELF: Format: ELF64-amdgpu
+# ELF: Arch: amdgcn
+# ELF: ElfHeader {
+# ELF:   Ident {
+# ELF:     OS/ABI: AMDGPU_MESA3D (0x42)
+# ELF:     ABIVersion: 0
+# ELF:   }
+# ELF:   Machine: EM_AMDGPU (0xE0)
+# ELF:   Flags [ (0x2)
+# ELF:     EF_AMDGPU_ARCH_GCN (0x2)
+# ELF:   ]
+# ELF: }
+
+# YAML: FileHeader
+# YAML:   Class:   ELFCLASS64
+# YAML:   Data:    ELFDATA2LSB
+# YAML:   OSABI:   ELFOSABI_AMDGPU_MESA3D
+# YAML:   Type:    ET_REL
+# YAML:   Machine: EM_AMDGPU
+# YAML:   Flags:   [ EF_AMDGPU_ARCH_GCN ]
 
 --- !ELF
 FileHeader:
   Class:   ELFCLASS64
   Data:    ELFDATA2LSB
+  OSABI:   ELFOSABI_AMDGPU_MESA3D
   Type:    ET_REL
   Machine: EM_AMDGPU
-  OSABI:   ELFOSABI_AMDGPU_MESA3D
+  Flags:   [ EF_AMDGPU_ARCH_GCN ]
 ...
index e52f98794566ddc9c72faf0864695a5d67d2f475..9b077ff5231415635a39eb8c559b03d904111581 100644 (file)
@@ -1,7 +1,7 @@
 RUN: llvm-readobj -file-headers -program-headers -sections -symbols %p/Inputs/trivial.obj.elf-amdhsa-gfx803 | FileCheck %s
 
 CHECK: Format: ELF64-amdgpu
-CHECK: Arch: amdgcn
+CHECK: Arch: unknown
 CHECK: ElfHeader {
 CHECK:   Ident {
 CHECK:     OS/ABI: AMDGPU_HSA (0x40)
index 387ad364ebadf65e02dd8cc3fd2dbeb5e8c3ba95..2619121262de14ca71625f9ae2c469238098ef27 100644 (file)
@@ -1244,6 +1244,12 @@ static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
   LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
 };
 
+static const EnumEntry<unsigned> ElfHeaderAMDGPUFlags[] = {
+  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_NONE),
+  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_R600),
+  LLVM_READOBJ_ENUM_ENT(ELF, EF_AMDGPU_ARCH_GCN)
+};
+
 static const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = {
   LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_RVC),
   LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_SINGLE),
@@ -3562,6 +3568,9 @@ template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders(const ELFO *Obj) {
       W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderMipsFlags),
                    unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI),
                    unsigned(ELF::EF_MIPS_MACH));
+    else if (e->e_machine == EM_AMDGPU)
+      W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderAMDGPUFlags),
+                   unsigned(ELF::EF_AMDGPU_ARCH));
     else if (e->e_machine == EM_RISCV)
       W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderRISCVFlags));
     else