AMDGPU: Add and set AMDGPU-specific e_flags

Differential Revision: https://reviews.llvm.org/D38556

llvm-svn: 314987
This commit is contained in:
Konstantin Zhuravlyov 2017-10-05 16:19:18 +00:00
parent c9e0f886e5
commit aa0835a7ab
13 changed files with 187 additions and 63 deletions

View 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"

View 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;

View 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:

View 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);
}

View 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

View 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() {

View File

@ -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
}
}

View File

@ -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 ]
...

View 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 ]
...

View 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 ]
...

View 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 ]
...

View 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)

View 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