1ff0cc061SDimitry Andric //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2ff0cc061SDimitry Andric //
3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure
4ff0cc061SDimitry Andric //
5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source
6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details.
7ff0cc061SDimitry Andric //
8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
9ff0cc061SDimitry Andric //
10ff0cc061SDimitry Andric // This file implements a target parser to recognise hardware features such as
11ff0cc061SDimitry Andric // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
12ff0cc061SDimitry Andric //
13ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
14ff0cc061SDimitry Andric
15ff0cc061SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h"
16ff0cc061SDimitry Andric #include "llvm/Support/TargetParser.h"
17*b5893f02SDimitry Andric #include "llvm/ADT/ArrayRef.h"
18ff0cc061SDimitry Andric #include "llvm/ADT/StringSwitch.h"
197d523365SDimitry Andric #include "llvm/ADT/Twine.h"
20ff0cc061SDimitry Andric
21ff0cc061SDimitry Andric using namespace llvm;
22*b5893f02SDimitry Andric using namespace AMDGPU;
23ff0cc061SDimitry Andric
24ff0cc061SDimitry Andric namespace {
25ff0cc061SDimitry Andric
26*b5893f02SDimitry Andric struct GPUInfo {
27*b5893f02SDimitry Andric StringLiteral Name;
28*b5893f02SDimitry Andric StringLiteral CanonicalName;
29*b5893f02SDimitry Andric AMDGPU::GPUKind Kind;
30*b5893f02SDimitry Andric unsigned Features;
31ff0cc061SDimitry Andric };
3297bc6c73SDimitry Andric
33*b5893f02SDimitry Andric constexpr GPUInfo R600GPUs[26] = {
34*b5893f02SDimitry Andric // Name Canonical Kind Features
35*b5893f02SDimitry Andric // Name
36*b5893f02SDimitry Andric {{"r600"}, {"r600"}, GK_R600, FEATURE_NONE },
37*b5893f02SDimitry Andric {{"rv630"}, {"r600"}, GK_R600, FEATURE_NONE },
38*b5893f02SDimitry Andric {{"rv635"}, {"r600"}, GK_R600, FEATURE_NONE },
39*b5893f02SDimitry Andric {{"r630"}, {"r630"}, GK_R630, FEATURE_NONE },
40*b5893f02SDimitry Andric {{"rs780"}, {"rs880"}, GK_RS880, FEATURE_NONE },
41*b5893f02SDimitry Andric {{"rs880"}, {"rs880"}, GK_RS880, FEATURE_NONE },
42*b5893f02SDimitry Andric {{"rv610"}, {"rs880"}, GK_RS880, FEATURE_NONE },
43*b5893f02SDimitry Andric {{"rv620"}, {"rs880"}, GK_RS880, FEATURE_NONE },
44*b5893f02SDimitry Andric {{"rv670"}, {"rv670"}, GK_RV670, FEATURE_NONE },
45*b5893f02SDimitry Andric {{"rv710"}, {"rv710"}, GK_RV710, FEATURE_NONE },
46*b5893f02SDimitry Andric {{"rv730"}, {"rv730"}, GK_RV730, FEATURE_NONE },
47*b5893f02SDimitry Andric {{"rv740"}, {"rv770"}, GK_RV770, FEATURE_NONE },
48*b5893f02SDimitry Andric {{"rv770"}, {"rv770"}, GK_RV770, FEATURE_NONE },
49*b5893f02SDimitry Andric {{"cedar"}, {"cedar"}, GK_CEDAR, FEATURE_NONE },
50*b5893f02SDimitry Andric {{"palm"}, {"cedar"}, GK_CEDAR, FEATURE_NONE },
51*b5893f02SDimitry Andric {{"cypress"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA },
52*b5893f02SDimitry Andric {{"hemlock"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA },
53*b5893f02SDimitry Andric {{"juniper"}, {"juniper"}, GK_JUNIPER, FEATURE_NONE },
54*b5893f02SDimitry Andric {{"redwood"}, {"redwood"}, GK_REDWOOD, FEATURE_NONE },
55*b5893f02SDimitry Andric {{"sumo"}, {"sumo"}, GK_SUMO, FEATURE_NONE },
56*b5893f02SDimitry Andric {{"sumo2"}, {"sumo"}, GK_SUMO, FEATURE_NONE },
57*b5893f02SDimitry Andric {{"barts"}, {"barts"}, GK_BARTS, FEATURE_NONE },
58*b5893f02SDimitry Andric {{"caicos"}, {"caicos"}, GK_CAICOS, FEATURE_NONE },
59*b5893f02SDimitry Andric {{"aruba"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA },
60*b5893f02SDimitry Andric {{"cayman"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA },
61*b5893f02SDimitry Andric {{"turks"}, {"turks"}, GK_TURKS, FEATURE_NONE }
62d88c1a5aSDimitry Andric };
63d88c1a5aSDimitry Andric
64*b5893f02SDimitry Andric // This table should be sorted by the value of GPUKind
65*b5893f02SDimitry Andric // Don't bother listing the implicitly true features
66*b5893f02SDimitry Andric constexpr GPUInfo AMDGCNGPUs[33] = {
67*b5893f02SDimitry Andric // Name Canonical Kind Features
68*b5893f02SDimitry Andric // Name
69*b5893f02SDimitry Andric {{"gfx600"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32},
70*b5893f02SDimitry Andric {{"tahiti"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32},
71*b5893f02SDimitry Andric {{"gfx601"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
72*b5893f02SDimitry Andric {{"hainan"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
73*b5893f02SDimitry Andric {{"oland"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
74*b5893f02SDimitry Andric {{"pitcairn"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
75*b5893f02SDimitry Andric {{"verde"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
76*b5893f02SDimitry Andric {{"gfx700"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
77*b5893f02SDimitry Andric {{"kaveri"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
78*b5893f02SDimitry Andric {{"gfx701"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32},
79*b5893f02SDimitry Andric {{"hawaii"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32},
80*b5893f02SDimitry Andric {{"gfx702"}, {"gfx702"}, GK_GFX702, FEATURE_FAST_FMA_F32},
81*b5893f02SDimitry Andric {{"gfx703"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
82*b5893f02SDimitry Andric {{"kabini"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
83*b5893f02SDimitry Andric {{"mullins"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
84*b5893f02SDimitry Andric {{"gfx704"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
85*b5893f02SDimitry Andric {{"bonaire"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
86*b5893f02SDimitry Andric {{"gfx801"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
87*b5893f02SDimitry Andric {{"carrizo"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
88*b5893f02SDimitry Andric {{"gfx802"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
89*b5893f02SDimitry Andric {{"iceland"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
90*b5893f02SDimitry Andric {{"tonga"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
91*b5893f02SDimitry Andric {{"gfx803"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
92*b5893f02SDimitry Andric {{"fiji"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
93*b5893f02SDimitry Andric {{"polaris10"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
94*b5893f02SDimitry Andric {{"polaris11"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
95*b5893f02SDimitry Andric {{"gfx810"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32},
96*b5893f02SDimitry Andric {{"stoney"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32},
97*b5893f02SDimitry Andric {{"gfx900"}, {"gfx900"}, GK_GFX900, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
98*b5893f02SDimitry Andric {{"gfx902"}, {"gfx902"}, GK_GFX902, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
99*b5893f02SDimitry Andric {{"gfx904"}, {"gfx904"}, GK_GFX904, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
100*b5893f02SDimitry Andric {{"gfx906"}, {"gfx906"}, GK_GFX906, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
101*b5893f02SDimitry Andric {{"gfx909"}, {"gfx909"}, GK_GFX909, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
102ff0cc061SDimitry Andric };
1037d523365SDimitry Andric
getArchEntry(AMDGPU::GPUKind AK,ArrayRef<GPUInfo> Table)104*b5893f02SDimitry Andric const GPUInfo *getArchEntry(AMDGPU::GPUKind AK, ArrayRef<GPUInfo> Table) {
105*b5893f02SDimitry Andric GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE };
106d88c1a5aSDimitry Andric
107*b5893f02SDimitry Andric auto I = std::lower_bound(Table.begin(), Table.end(), Search,
108*b5893f02SDimitry Andric [](const GPUInfo &A, const GPUInfo &B) {
109*b5893f02SDimitry Andric return A.Kind < B.Kind;
110*b5893f02SDimitry Andric });
1117d523365SDimitry Andric
112*b5893f02SDimitry Andric if (I == Table.end())
113*b5893f02SDimitry Andric return nullptr;
114*b5893f02SDimitry Andric return I;
115*b5893f02SDimitry Andric }
116ff0cc061SDimitry Andric
117ff0cc061SDimitry Andric } // namespace
118ff0cc061SDimitry Andric
getArchNameAMDGCN(GPUKind AK)119*b5893f02SDimitry Andric StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) {
120*b5893f02SDimitry Andric if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
121*b5893f02SDimitry Andric return Entry->CanonicalName;
122*b5893f02SDimitry Andric return "";
123ff0cc061SDimitry Andric }
124ff0cc061SDimitry Andric
getArchNameR600(GPUKind AK)125*b5893f02SDimitry Andric StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
126*b5893f02SDimitry Andric if (const auto *Entry = getArchEntry(AK, R600GPUs))
127*b5893f02SDimitry Andric return Entry->CanonicalName;
128*b5893f02SDimitry Andric return "";
12997bc6c73SDimitry Andric }
13097bc6c73SDimitry Andric
parseArchAMDGCN(StringRef CPU)131*b5893f02SDimitry Andric AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) {
132*b5893f02SDimitry Andric for (const auto C : AMDGCNGPUs) {
133*b5893f02SDimitry Andric if (CPU == C.Name)
134*b5893f02SDimitry Andric return C.Kind;
13597bc6c73SDimitry Andric }
13697bc6c73SDimitry Andric
137*b5893f02SDimitry Andric return AMDGPU::GPUKind::GK_NONE;
13897bc6c73SDimitry Andric }
13997bc6c73SDimitry Andric
parseArchR600(StringRef CPU)140*b5893f02SDimitry Andric AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) {
141*b5893f02SDimitry Andric for (const auto C : R600GPUs) {
142*b5893f02SDimitry Andric if (CPU == C.Name)
143*b5893f02SDimitry Andric return C.Kind;
1447d523365SDimitry Andric }
1457d523365SDimitry Andric
146*b5893f02SDimitry Andric return AMDGPU::GPUKind::GK_NONE;
1477d523365SDimitry Andric }
1487d523365SDimitry Andric
getArchAttrAMDGCN(GPUKind AK)149*b5893f02SDimitry Andric unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) {
150*b5893f02SDimitry Andric if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
151*b5893f02SDimitry Andric return Entry->Features;
152*b5893f02SDimitry Andric return FEATURE_NONE;
1537d523365SDimitry Andric }
1547d523365SDimitry Andric
getArchAttrR600(GPUKind AK)155*b5893f02SDimitry Andric unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
156*b5893f02SDimitry Andric if (const auto *Entry = getArchEntry(AK, R600GPUs))
157*b5893f02SDimitry Andric return Entry->Features;
158*b5893f02SDimitry Andric return FEATURE_NONE;
1597d523365SDimitry Andric }
1607d523365SDimitry Andric
fillValidArchListAMDGCN(SmallVectorImpl<StringRef> & Values)161*b5893f02SDimitry Andric void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) {
162*b5893f02SDimitry Andric // XXX: Should this only report unique canonical names?
163*b5893f02SDimitry Andric for (const auto C : AMDGCNGPUs)
164*b5893f02SDimitry Andric Values.push_back(C.Name);
16597bc6c73SDimitry Andric }
16697bc6c73SDimitry Andric
fillValidArchListR600(SmallVectorImpl<StringRef> & Values)167*b5893f02SDimitry Andric void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) {
168*b5893f02SDimitry Andric for (const auto C : R600GPUs)
169*b5893f02SDimitry Andric Values.push_back(C.Name);
17097bc6c73SDimitry Andric }
17197bc6c73SDimitry Andric
getIsaVersion(StringRef GPU)172*b5893f02SDimitry Andric AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
173*b5893f02SDimitry Andric if (GPU == "generic")
174*b5893f02SDimitry Andric return {7, 0, 0};
17597bc6c73SDimitry Andric
176*b5893f02SDimitry Andric AMDGPU::GPUKind AK = parseArchAMDGCN(GPU);
177*b5893f02SDimitry Andric if (AK == AMDGPU::GPUKind::GK_NONE)
178*b5893f02SDimitry Andric return {0, 0, 0};
17997bc6c73SDimitry Andric
180*b5893f02SDimitry Andric switch (AK) {
181*b5893f02SDimitry Andric case GK_GFX600: return {6, 0, 0};
182*b5893f02SDimitry Andric case GK_GFX601: return {6, 0, 1};
183*b5893f02SDimitry Andric case GK_GFX700: return {7, 0, 0};
184*b5893f02SDimitry Andric case GK_GFX701: return {7, 0, 1};
185*b5893f02SDimitry Andric case GK_GFX702: return {7, 0, 2};
186*b5893f02SDimitry Andric case GK_GFX703: return {7, 0, 3};
187*b5893f02SDimitry Andric case GK_GFX704: return {7, 0, 4};
188*b5893f02SDimitry Andric case GK_GFX801: return {8, 0, 1};
189*b5893f02SDimitry Andric case GK_GFX802: return {8, 0, 2};
190*b5893f02SDimitry Andric case GK_GFX803: return {8, 0, 3};
191*b5893f02SDimitry Andric case GK_GFX810: return {8, 1, 0};
192*b5893f02SDimitry Andric case GK_GFX900: return {9, 0, 0};
193*b5893f02SDimitry Andric case GK_GFX902: return {9, 0, 2};
194*b5893f02SDimitry Andric case GK_GFX904: return {9, 0, 4};
195*b5893f02SDimitry Andric case GK_GFX906: return {9, 0, 6};
196*b5893f02SDimitry Andric case GK_GFX909: return {9, 0, 9};
197*b5893f02SDimitry Andric default: return {0, 0, 0};
1983ca95b02SDimitry Andric }
1994ba319b5SDimitry Andric }
200