From 9b90153e769d59f67cefc485065e28b04c5b6e7e Mon Sep 17 00:00:00 2001 From: Konstantin Zhuravlyov Date: Thu, 5 Oct 2017 16:19:18 +0000 Subject: [PATCH] AMDGPU: Add and set AMDGPU-specific e_flags Differential Revision: https://reviews.llvm.org/D38556 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314987 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/BinaryFormat/ELF.h | 9 +++++ include/llvm/Object/ELFObjectFile.h | 16 ++++++--- lib/ObjectYAML/ELFYAML.cpp | 4 ++- .../AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp | 36 +++++++++++++++---- .../AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h | 12 +++---- .../MCTargetDesc/AMDGPUMCTargetDesc.cpp | 5 +-- test/CodeGen/AMDGPU/elf-header.ll | 18 ++++++---- .../Object/AMDGPU/elf32-r600-definitions.yaml | 34 ++++++++++++++++++ .../elf64-amdgcn-amdhsa-definitions.yaml | 35 ++++++++++++------ .../elf64-amdgcn-amdpal-definitions.yaml | 35 ++++++++++++------ .../elf64-amdgcn-mesa3d-definitions.yaml | 35 ++++++++++++------ .../llvm-readobj/amdgpu-elf-definitions.test | 2 +- tools/llvm-readobj/ELFDumper.cpp | 9 +++++ 13 files changed, 187 insertions(+), 63 deletions(-) create mode 100644 test/Object/AMDGPU/elf32-r600-definitions.yaml diff --git a/include/llvm/BinaryFormat/ELF.h b/include/llvm/BinaryFormat/ELF.h index 712e67ef52a..5a0cf2cee20 100644 --- a/include/llvm/BinaryFormat/ELF.h +++ b/include/llvm/BinaryFormat/ELF.h @@ -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" diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index b4411ce984e..6d4a3808392 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -1063,14 +1063,20 @@ unsigned ELFObjectFile::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; diff --git a/lib/ObjectYAML/ELFYAML.cpp b/lib/ObjectYAML/ELFYAML.cpp index 36db8eae5ba..dee820c21cb 100644 --- a/lib/ObjectYAML/ELFYAML.cpp +++ b/lib/ObjectYAML/ELFYAML.cpp @@ -246,7 +246,6 @@ void ScalarEnumerationTraits::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::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: diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp index 43338a5bebd..bfdb7d7cff7 100644 --- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp +++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp @@ -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); } diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h index 5319b65d65f..386aa56c807 100644 --- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h +++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h @@ -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 diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp index 2968d834a5e..1682fc5e49b 100644 --- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -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() { diff --git a/test/CodeGen/AMDGPU/elf-header.ll b/test/CodeGen/AMDGPU/elf-header.ll index de9714cef97..192eb780f70 100644 --- a/test/CodeGen/AMDGPU/elf-header.ll +++ b/test/CodeGen/AMDGPU/elf-header.ll @@ -23,11 +23,11 @@ ; 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) @@ -36,8 +36,14 @@ ; 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/test/Object/AMDGPU/elf32-r600-definitions.yaml b/test/Object/AMDGPU/elf32-r600-definitions.yaml new file mode 100644 index 00000000000..56c5f29b79f --- /dev/null +++ b/test/Object/AMDGPU/elf32-r600-definitions.yaml @@ -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 ] +... diff --git a/test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml b/test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml index 53639e00158..1ffea244d3f 100644 --- a/test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml +++ b/test/Object/AMDGPU/elf64-amdgcn-amdhsa-definitions.yaml @@ -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 ] ... diff --git a/test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml b/test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml index 8e39f6d32eb..3ec5fe51083 100644 --- a/test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml +++ b/test/Object/AMDGPU/elf64-amdgcn-amdpal-definitions.yaml @@ -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 ] ... diff --git a/test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml b/test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml index 7fa413f64a1..258bb122ca9 100644 --- a/test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml +++ b/test/Object/AMDGPU/elf64-amdgcn-mesa3d-definitions.yaml @@ -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 ] ... diff --git a/test/tools/llvm-readobj/amdgpu-elf-definitions.test b/test/tools/llvm-readobj/amdgpu-elf-definitions.test index e52f9879456..9b077ff5231 100644 --- a/test/tools/llvm-readobj/amdgpu-elf-definitions.test +++ b/test/tools/llvm-readobj/amdgpu-elf-definitions.test @@ -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) diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 387ad364eba..2619121262d 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -1244,6 +1244,12 @@ static const EnumEntry ElfHeaderMipsFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6) }; +static const EnumEntry 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 ElfHeaderRISCVFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_RVC), LLVM_READOBJ_ENUM_ENT(ELF, EF_RISCV_FLOAT_ABI_SINGLE), @@ -3562,6 +3568,9 @@ template void LLVMStyle::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 -- 2.40.0