diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -86,6 +86,10 @@ SubtargetFeatures getRISCVFeatures() const; + StringRef getTargetCPUName() const override; + + StringRef getAMDGPUCPUName() const; + void setARMSubArch(Triple &TheTriple) const override; virtual uint16_t getEType() const = 0; diff --git a/llvm/include/llvm/Object/ObjectFile.h b/llvm/include/llvm/Object/ObjectFile.h --- a/llvm/include/llvm/Object/ObjectFile.h +++ b/llvm/include/llvm/Object/ObjectFile.h @@ -327,6 +327,7 @@ virtual StringRef getFileFormatName() const = 0; virtual Triple::ArchType getArch() const = 0; virtual SubtargetFeatures getFeatures() const = 0; + virtual StringRef getTargetCPUName() const { return StringRef(""); }; virtual void setARMSubArch(Triple &TheTriple) const { } virtual Expected getStartAddress() const { return errorCodeToError(object_error::parse_failed); diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -355,6 +355,116 @@ } } +StringRef ELFObjectFileBase::getTargetCPUName() const { + switch (getEMachine()) { + case ELF::EM_AMDGPU: + return getAMDGPUCPUName(); + default: + return StringRef(""); + } +} + +StringRef ELFObjectFileBase::getAMDGPUCPUName() const { + using namespace ELF; + unsigned EF_CPU = getPlatformFlags() & EF_AMDGPU_MACH; + switch (EF_CPU) { + // Radeon HD 2000/3000 Series (R600). + case EF_AMDGPU_MACH_R600_R600: + return StringRef("r600"); + case EF_AMDGPU_MACH_R600_R630: + return StringRef("r630"); + case EF_AMDGPU_MACH_R600_RS880: + return StringRef("rs880"); + case EF_AMDGPU_MACH_R600_RV670: + return StringRef("rv670"); + + // Radeon HD 4000 Series (R700). + case EF_AMDGPU_MACH_R600_RV710: + return StringRef("rv710"); + case EF_AMDGPU_MACH_R600_RV730: + return StringRef("rv730"); + case EF_AMDGPU_MACH_R600_RV770: + return StringRef("rv770"); + + // Radeon HD 5000 Series (Evergreen). + case EF_AMDGPU_MACH_R600_CEDAR: + return StringRef("cedar"); + case EF_AMDGPU_MACH_R600_CYPRESS: + return StringRef("cypress"); + case EF_AMDGPU_MACH_R600_JUNIPER: + return StringRef("juniper"); + case EF_AMDGPU_MACH_R600_REDWOOD: + return StringRef("redwood"); + case EF_AMDGPU_MACH_R600_SUMO: + return StringRef("sumo"); + + // Radeon HD 6000 Series (Northern Islands). + case EF_AMDGPU_MACH_R600_BARTS: + return StringRef("barts"); + case EF_AMDGPU_MACH_R600_CAICOS: + return StringRef("caicos"); + case EF_AMDGPU_MACH_R600_CAYMAN: + return StringRef("cayman"); + case EF_AMDGPU_MACH_R600_TURKS: + return StringRef("turks"); + + // AMDGCN GFX6. + case EF_AMDGPU_MACH_AMDGCN_GFX600: + return StringRef("gfx600"); + case EF_AMDGPU_MACH_AMDGCN_GFX601: + return StringRef("gfx601"); + + // AMDGCN GFX7. + case EF_AMDGPU_MACH_AMDGCN_GFX700: + return StringRef("gfx700"); + case EF_AMDGPU_MACH_AMDGCN_GFX701: + return StringRef("gfx701"); + case EF_AMDGPU_MACH_AMDGCN_GFX702: + return StringRef("gfx702"); + case EF_AMDGPU_MACH_AMDGCN_GFX703: + return StringRef("gfx703"); + case EF_AMDGPU_MACH_AMDGCN_GFX704: + return StringRef("gfx704"); + + // AMDGCN GFX8. + case EF_AMDGPU_MACH_AMDGCN_GFX801: + return StringRef("gfx801"); + case EF_AMDGPU_MACH_AMDGCN_GFX802: + return StringRef("gfx802"); + case EF_AMDGPU_MACH_AMDGCN_GFX803: + return StringRef("gfx803"); + case EF_AMDGPU_MACH_AMDGCN_GFX810: + return StringRef("gfx810"); + + // AMDGCN GFX9. + case EF_AMDGPU_MACH_AMDGCN_GFX900: + return StringRef("gfx900"); + case EF_AMDGPU_MACH_AMDGCN_GFX902: + return StringRef("gfx902"); + case EF_AMDGPU_MACH_AMDGCN_GFX904: + return StringRef("gfx904"); + case EF_AMDGPU_MACH_AMDGCN_GFX906: + return StringRef("gfx906"); + case EF_AMDGPU_MACH_AMDGCN_GFX908: + return StringRef("gfx908"); + case EF_AMDGPU_MACH_AMDGCN_GFX909: + return StringRef("gfx909"); + + // AMDGCN GFX10. + case EF_AMDGPU_MACH_AMDGCN_GFX1010: + return StringRef("gfx1010"); + case EF_AMDGPU_MACH_AMDGCN_GFX1011: + return StringRef("gfx1011"); + case EF_AMDGPU_MACH_AMDGCN_GFX1012: + return StringRef("gfx1012"); + case EF_AMDGPU_MACH_AMDGCN_GFX1030: + return StringRef("gfx1030"); + + default: + return StringRef(""); + } +} + // FIXME Encode from a tablegen description or target parser. void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { if (TheTriple.getSubArch() != Triple::NoSubArch) diff --git a/llvm/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll @@ -0,0 +1,83 @@ +define amdgpu_kernel void @test_kernel() { + ret void +} + +; Test subtarget detection. Disassembly is only supported for GFX8 and beyond. +; +; ----------------------------------GFX10-------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1030 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1030 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1012 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1012 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1011 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1011 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1010 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + + +; ----------------------------------GFX9--------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx909 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx909 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx908 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx906 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx904 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx904 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx902 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx902 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx900 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + + +; ----------------------------------GFX8--------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx810 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx810 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx803 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx802 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx802 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx801 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx801 %t.o > specify.txt +; RUN: llvm-objdump -D %t.o > detect.txt +; RUN: diff specify.txt detect.txt diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -2089,6 +2089,11 @@ if (!AsmInfo) reportError(Obj->getFileName(), "no assembly info for target " + TripleName); + + // If MCPU isn't specified, detect it. Right now only AMDGPU implements the + // detection. In other cases, an empty string is returned. + MCPU = MCPU.empty() ? Obj->getTargetCPUName().str() : MCPU; + std::unique_ptr STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString())); if (!STI)