1 //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements a target parser to recognise hardware features such as
10 // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/TargetParser.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/Support/ARMBuildAttributes.h"
22 using namespace AMDGPU
;
28 StringLiteral CanonicalName
;
33 constexpr GPUInfo R600GPUs
[] = {
34 // Name Canonical Kind Features
36 {{"r600"}, {"r600"}, GK_R600
, FEATURE_NONE
},
37 {{"rv630"}, {"r600"}, GK_R600
, FEATURE_NONE
},
38 {{"rv635"}, {"r600"}, GK_R600
, FEATURE_NONE
},
39 {{"r630"}, {"r630"}, GK_R630
, FEATURE_NONE
},
40 {{"rs780"}, {"rs880"}, GK_RS880
, FEATURE_NONE
},
41 {{"rs880"}, {"rs880"}, GK_RS880
, FEATURE_NONE
},
42 {{"rv610"}, {"rs880"}, GK_RS880
, FEATURE_NONE
},
43 {{"rv620"}, {"rs880"}, GK_RS880
, FEATURE_NONE
},
44 {{"rv670"}, {"rv670"}, GK_RV670
, FEATURE_NONE
},
45 {{"rv710"}, {"rv710"}, GK_RV710
, FEATURE_NONE
},
46 {{"rv730"}, {"rv730"}, GK_RV730
, FEATURE_NONE
},
47 {{"rv740"}, {"rv770"}, GK_RV770
, FEATURE_NONE
},
48 {{"rv770"}, {"rv770"}, GK_RV770
, FEATURE_NONE
},
49 {{"cedar"}, {"cedar"}, GK_CEDAR
, FEATURE_NONE
},
50 {{"palm"}, {"cedar"}, GK_CEDAR
, FEATURE_NONE
},
51 {{"cypress"}, {"cypress"}, GK_CYPRESS
, FEATURE_FMA
},
52 {{"hemlock"}, {"cypress"}, GK_CYPRESS
, FEATURE_FMA
},
53 {{"juniper"}, {"juniper"}, GK_JUNIPER
, FEATURE_NONE
},
54 {{"redwood"}, {"redwood"}, GK_REDWOOD
, FEATURE_NONE
},
55 {{"sumo"}, {"sumo"}, GK_SUMO
, FEATURE_NONE
},
56 {{"sumo2"}, {"sumo"}, GK_SUMO
, FEATURE_NONE
},
57 {{"barts"}, {"barts"}, GK_BARTS
, FEATURE_NONE
},
58 {{"caicos"}, {"caicos"}, GK_CAICOS
, FEATURE_NONE
},
59 {{"aruba"}, {"cayman"}, GK_CAYMAN
, FEATURE_FMA
},
60 {{"cayman"}, {"cayman"}, GK_CAYMAN
, FEATURE_FMA
},
61 {{"turks"}, {"turks"}, GK_TURKS
, FEATURE_NONE
}
64 // This table should be sorted by the value of GPUKind
65 // Don't bother listing the implicitly true features
66 constexpr GPUInfo AMDGCNGPUs
[] = {
67 // Name Canonical Kind Features
69 {{"gfx600"}, {"gfx600"}, GK_GFX600
, FEATURE_FAST_FMA_F32
},
70 {{"tahiti"}, {"gfx600"}, GK_GFX600
, FEATURE_FAST_FMA_F32
},
71 {{"gfx601"}, {"gfx601"}, GK_GFX601
, FEATURE_NONE
},
72 {{"pitcairn"}, {"gfx601"}, GK_GFX601
, FEATURE_NONE
},
73 {{"verde"}, {"gfx601"}, GK_GFX601
, FEATURE_NONE
},
74 {{"gfx602"}, {"gfx602"}, GK_GFX602
, FEATURE_NONE
},
75 {{"hainan"}, {"gfx602"}, GK_GFX602
, FEATURE_NONE
},
76 {{"oland"}, {"gfx602"}, GK_GFX602
, FEATURE_NONE
},
77 {{"gfx700"}, {"gfx700"}, GK_GFX700
, FEATURE_NONE
},
78 {{"kaveri"}, {"gfx700"}, GK_GFX700
, FEATURE_NONE
},
79 {{"gfx701"}, {"gfx701"}, GK_GFX701
, FEATURE_FAST_FMA_F32
},
80 {{"hawaii"}, {"gfx701"}, GK_GFX701
, FEATURE_FAST_FMA_F32
},
81 {{"gfx702"}, {"gfx702"}, GK_GFX702
, FEATURE_FAST_FMA_F32
},
82 {{"gfx703"}, {"gfx703"}, GK_GFX703
, FEATURE_NONE
},
83 {{"kabini"}, {"gfx703"}, GK_GFX703
, FEATURE_NONE
},
84 {{"mullins"}, {"gfx703"}, GK_GFX703
, FEATURE_NONE
},
85 {{"gfx704"}, {"gfx704"}, GK_GFX704
, FEATURE_NONE
},
86 {{"bonaire"}, {"gfx704"}, GK_GFX704
, FEATURE_NONE
},
87 {{"gfx705"}, {"gfx705"}, GK_GFX705
, FEATURE_NONE
},
88 {{"gfx801"}, {"gfx801"}, GK_GFX801
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
89 {{"carrizo"}, {"gfx801"}, GK_GFX801
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
90 {{"gfx802"}, {"gfx802"}, GK_GFX802
, FEATURE_FAST_DENORMAL_F32
},
91 {{"iceland"}, {"gfx802"}, GK_GFX802
, FEATURE_FAST_DENORMAL_F32
},
92 {{"tonga"}, {"gfx802"}, GK_GFX802
, FEATURE_FAST_DENORMAL_F32
},
93 {{"gfx803"}, {"gfx803"}, GK_GFX803
, FEATURE_FAST_DENORMAL_F32
},
94 {{"fiji"}, {"gfx803"}, GK_GFX803
, FEATURE_FAST_DENORMAL_F32
},
95 {{"polaris10"}, {"gfx803"}, GK_GFX803
, FEATURE_FAST_DENORMAL_F32
},
96 {{"polaris11"}, {"gfx803"}, GK_GFX803
, FEATURE_FAST_DENORMAL_F32
},
97 {{"gfx805"}, {"gfx805"}, GK_GFX805
, FEATURE_FAST_DENORMAL_F32
},
98 {{"tongapro"}, {"gfx805"}, GK_GFX805
, FEATURE_FAST_DENORMAL_F32
},
99 {{"gfx810"}, {"gfx810"}, GK_GFX810
, FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
100 {{"stoney"}, {"gfx810"}, GK_GFX810
, FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
101 {{"gfx900"}, {"gfx900"}, GK_GFX900
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
102 {{"gfx902"}, {"gfx902"}, GK_GFX902
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
103 {{"gfx904"}, {"gfx904"}, GK_GFX904
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
104 {{"gfx906"}, {"gfx906"}, GK_GFX906
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
|FEATURE_SRAMECC
},
105 {{"gfx908"}, {"gfx908"}, GK_GFX908
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
|FEATURE_SRAMECC
},
106 {{"gfx909"}, {"gfx909"}, GK_GFX909
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
107 {{"gfx90a"}, {"gfx90a"}, GK_GFX90A
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
|FEATURE_SRAMECC
},
108 {{"gfx90c"}, {"gfx90c"}, GK_GFX90C
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_XNACK
},
109 {{"gfx1010"}, {"gfx1010"}, GK_GFX1010
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
|FEATURE_XNACK
},
110 {{"gfx1011"}, {"gfx1011"}, GK_GFX1011
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
|FEATURE_XNACK
},
111 {{"gfx1012"}, {"gfx1012"}, GK_GFX1012
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
|FEATURE_XNACK
},
112 {{"gfx1013"}, {"gfx1013"}, GK_GFX1013
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
|FEATURE_XNACK
},
113 {{"gfx1030"}, {"gfx1030"}, GK_GFX1030
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
114 {{"gfx1031"}, {"gfx1031"}, GK_GFX1031
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
115 {{"gfx1032"}, {"gfx1032"}, GK_GFX1032
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
116 {{"gfx1033"}, {"gfx1033"}, GK_GFX1033
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
117 {{"gfx1034"}, {"gfx1034"}, GK_GFX1034
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
118 {{"gfx1035"}, {"gfx1035"}, GK_GFX1035
, FEATURE_FAST_FMA_F32
|FEATURE_FAST_DENORMAL_F32
|FEATURE_WAVE32
},
121 const GPUInfo
*getArchEntry(AMDGPU::GPUKind AK
, ArrayRef
<GPUInfo
> Table
) {
122 GPUInfo Search
= { {""}, {""}, AK
, AMDGPU::FEATURE_NONE
};
125 llvm::lower_bound(Table
, Search
, [](const GPUInfo
&A
, const GPUInfo
&B
) {
126 return A
.Kind
< B
.Kind
;
129 if (I
== Table
.end())
136 StringRef
llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK
) {
137 if (const auto *Entry
= getArchEntry(AK
, AMDGCNGPUs
))
138 return Entry
->CanonicalName
;
142 StringRef
llvm::AMDGPU::getArchNameR600(GPUKind AK
) {
143 if (const auto *Entry
= getArchEntry(AK
, R600GPUs
))
144 return Entry
->CanonicalName
;
148 AMDGPU::GPUKind
llvm::AMDGPU::parseArchAMDGCN(StringRef CPU
) {
149 for (const auto &C
: AMDGCNGPUs
) {
154 return AMDGPU::GPUKind::GK_NONE
;
157 AMDGPU::GPUKind
llvm::AMDGPU::parseArchR600(StringRef CPU
) {
158 for (const auto &C
: R600GPUs
) {
163 return AMDGPU::GPUKind::GK_NONE
;
166 unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK
) {
167 if (const auto *Entry
= getArchEntry(AK
, AMDGCNGPUs
))
168 return Entry
->Features
;
172 unsigned AMDGPU::getArchAttrR600(GPUKind AK
) {
173 if (const auto *Entry
= getArchEntry(AK
, R600GPUs
))
174 return Entry
->Features
;
178 void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl
<StringRef
> &Values
) {
179 // XXX: Should this only report unique canonical names?
180 for (const auto &C
: AMDGCNGPUs
)
181 Values
.push_back(C
.Name
);
184 void AMDGPU::fillValidArchListR600(SmallVectorImpl
<StringRef
> &Values
) {
185 for (const auto &C
: R600GPUs
)
186 Values
.push_back(C
.Name
);
189 AMDGPU::IsaVersion
AMDGPU::getIsaVersion(StringRef GPU
) {
190 AMDGPU::GPUKind AK
= parseArchAMDGCN(GPU
);
191 if (AK
== AMDGPU::GPUKind::GK_NONE
) {
192 if (GPU
== "generic-hsa")
194 if (GPU
== "generic")
200 case GK_GFX600
: return {6, 0, 0};
201 case GK_GFX601
: return {6, 0, 1};
202 case GK_GFX602
: return {6, 0, 2};
203 case GK_GFX700
: return {7, 0, 0};
204 case GK_GFX701
: return {7, 0, 1};
205 case GK_GFX702
: return {7, 0, 2};
206 case GK_GFX703
: return {7, 0, 3};
207 case GK_GFX704
: return {7, 0, 4};
208 case GK_GFX705
: return {7, 0, 5};
209 case GK_GFX801
: return {8, 0, 1};
210 case GK_GFX802
: return {8, 0, 2};
211 case GK_GFX803
: return {8, 0, 3};
212 case GK_GFX805
: return {8, 0, 5};
213 case GK_GFX810
: return {8, 1, 0};
214 case GK_GFX900
: return {9, 0, 0};
215 case GK_GFX902
: return {9, 0, 2};
216 case GK_GFX904
: return {9, 0, 4};
217 case GK_GFX906
: return {9, 0, 6};
218 case GK_GFX908
: return {9, 0, 8};
219 case GK_GFX909
: return {9, 0, 9};
220 case GK_GFX90A
: return {9, 0, 10};
221 case GK_GFX90C
: return {9, 0, 12};
222 case GK_GFX1010
: return {10, 1, 0};
223 case GK_GFX1011
: return {10, 1, 1};
224 case GK_GFX1012
: return {10, 1, 2};
225 case GK_GFX1013
: return {10, 1, 3};
226 case GK_GFX1030
: return {10, 3, 0};
227 case GK_GFX1031
: return {10, 3, 1};
228 case GK_GFX1032
: return {10, 3, 2};
229 case GK_GFX1033
: return {10, 3, 3};
230 case GK_GFX1034
: return {10, 3, 4};
231 case GK_GFX1035
: return {10, 3, 5};
232 default: return {0, 0, 0};
236 StringRef
AMDGPU::getCanonicalArchName(const Triple
&T
, StringRef Arch
) {
237 assert(T
.isAMDGPU());
238 auto ProcKind
= T
.isAMDGCN() ? parseArchAMDGCN(Arch
) : parseArchR600(Arch
);
239 if (ProcKind
== GK_NONE
)
242 return T
.isAMDGCN() ? getArchNameAMDGCN(ProcKind
) : getArchNameR600(ProcKind
);
252 StringLiteral DefaultMarch
;
253 bool is64Bit() const { return (Features
& FK_64BIT
); }
256 constexpr CPUInfo RISCVCPUInfo
[] = {
257 #define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) \
258 {NAME, CK_##ENUM, FEATURES, DEFAULT_MARCH},
259 #include "llvm/Support/RISCVTargetParser.def"
262 bool checkCPUKind(CPUKind Kind
, bool IsRV64
) {
263 if (Kind
== CK_INVALID
)
265 return RISCVCPUInfo
[static_cast<unsigned>(Kind
)].is64Bit() == IsRV64
;
268 bool checkTuneCPUKind(CPUKind Kind
, bool IsRV64
) {
269 if (Kind
== CK_INVALID
)
271 return RISCVCPUInfo
[static_cast<unsigned>(Kind
)].is64Bit() == IsRV64
;
274 CPUKind
parseCPUKind(StringRef CPU
) {
275 return llvm::StringSwitch
<CPUKind
>(CPU
)
276 #define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
277 #include "llvm/Support/RISCVTargetParser.def"
278 .Default(CK_INVALID
);
281 StringRef
resolveTuneCPUAlias(StringRef TuneCPU
, bool IsRV64
) {
282 return llvm::StringSwitch
<StringRef
>(TuneCPU
)
283 #define PROC_ALIAS(NAME, RV32, RV64) .Case(NAME, IsRV64 ? StringRef(RV64) : StringRef(RV32))
284 #include "llvm/Support/RISCVTargetParser.def"
288 CPUKind
parseTuneCPUKind(StringRef TuneCPU
, bool IsRV64
) {
289 TuneCPU
= resolveTuneCPUAlias(TuneCPU
, IsRV64
);
291 return llvm::StringSwitch
<CPUKind
>(TuneCPU
)
292 #define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
293 #include "llvm/Support/RISCVTargetParser.def"
294 .Default(CK_INVALID
);
297 StringRef
getMArchFromMcpu(StringRef CPU
) {
298 CPUKind Kind
= parseCPUKind(CPU
);
299 return RISCVCPUInfo
[static_cast<unsigned>(Kind
)].DefaultMarch
;
302 void fillValidCPUArchList(SmallVectorImpl
<StringRef
> &Values
, bool IsRV64
) {
303 for (const auto &C
: RISCVCPUInfo
) {
304 if (C
.Kind
!= CK_INVALID
&& IsRV64
== C
.is64Bit())
305 Values
.emplace_back(C
.Name
);
309 void fillValidTuneCPUArchList(SmallVectorImpl
<StringRef
> &Values
, bool IsRV64
) {
310 for (const auto &C
: RISCVCPUInfo
) {
311 if (C
.Kind
!= CK_INVALID
&& IsRV64
== C
.is64Bit())
312 Values
.emplace_back(C
.Name
);
314 #define PROC_ALIAS(NAME, RV32, RV64) Values.emplace_back(StringRef(NAME));
315 #include "llvm/Support/RISCVTargetParser.def"
318 // Get all features except standard extension feature
319 bool getCPUFeaturesExceptStdExt(CPUKind Kind
,
320 std::vector
<StringRef
> &Features
) {
321 unsigned CPUFeatures
= RISCVCPUInfo
[static_cast<unsigned>(Kind
)].Features
;
323 if (CPUFeatures
== FK_INVALID
)
326 if (CPUFeatures
& FK_64BIT
)
327 Features
.push_back("+64bit");
329 Features
.push_back("-64bit");