Line data Source code
1 : //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements a target parser to recognise hardware features such as
11 : // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "llvm/Support/ARMBuildAttributes.h"
16 : #include "llvm/Support/TargetParser.h"
17 : #include "llvm/ADT/ArrayRef.h"
18 : #include "llvm/ADT/StringSwitch.h"
19 : #include "llvm/ADT/Twine.h"
20 : #include <cctype>
21 :
22 : using namespace llvm;
23 : using namespace ARM;
24 : using namespace AArch64;
25 : using namespace AMDGPU;
26 :
27 : namespace {
28 :
29 : // List of canonical FPU names (use getFPUSynonym) and which architectural
30 : // features they correspond to (use getFPUFeatures).
31 : // FIXME: TableGen this.
32 : // The entries must appear in the order listed in ARM::FPUKind for correct indexing
33 : static const struct {
34 : const char *NameCStr;
35 : size_t NameLength;
36 : ARM::FPUKind ID;
37 : ARM::FPUVersion FPUVersion;
38 : ARM::NeonSupportLevel NeonSupport;
39 : ARM::FPURestriction Restriction;
40 :
41 0 : StringRef getName() const { return StringRef(NameCStr, NameLength); }
42 : } FPUNames[] = {
43 : #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
44 : { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
45 : #include "llvm/Support/ARMTargetParser.def"
46 : };
47 :
48 : // List of canonical arch names (use getArchSynonym).
49 : // This table also provides the build attribute fields for CPU arch
50 : // and Arch ID, according to the Addenda to the ARM ABI, chapters
51 : // 2.4 and 2.3.5.2 respectively.
52 : // FIXME: SubArch values were simplified to fit into the expectations
53 : // of the triples and are not conforming with their official names.
54 : // Check to see if the expectation should be changed.
55 : // FIXME: TableGen this.
56 : template <typename T> struct ArchNames {
57 : const char *NameCStr;
58 : size_t NameLength;
59 : const char *CPUAttrCStr;
60 : size_t CPUAttrLength;
61 : const char *SubArchCStr;
62 : size_t SubArchLength;
63 : unsigned DefaultFPU;
64 : unsigned ArchBaseExtensions;
65 : T ID;
66 : ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
67 :
68 0 : StringRef getName() const { return StringRef(NameCStr, NameLength); }
69 :
70 : // CPU class in build attributes.
71 0 : StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
72 :
73 : // Sub-Arch name.
74 0 : StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
75 : };
76 : ArchNames<ARM::ArchKind> ARCHNames[] = {
77 : #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
78 : {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
79 : sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
80 : #include "llvm/Support/ARMTargetParser.def"
81 : };
82 :
83 : ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
84 : #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
85 : {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
86 : sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
87 : #include "llvm/Support/AArch64TargetParser.def"
88 : };
89 :
90 :
91 : // List of Arch Extension names.
92 : // FIXME: TableGen this.
93 : static const struct {
94 : const char *NameCStr;
95 : size_t NameLength;
96 : unsigned ID;
97 : const char *Feature;
98 : const char *NegFeature;
99 :
100 0 : StringRef getName() const { return StringRef(NameCStr, NameLength); }
101 : } ARCHExtNames[] = {
102 : #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
103 : { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
104 : #include "llvm/Support/ARMTargetParser.def"
105 : },AArch64ARCHExtNames[] = {
106 : #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
107 : { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
108 : #include "llvm/Support/AArch64TargetParser.def"
109 : };
110 :
111 : // List of HWDiv names (use getHWDivSynonym) and which architectural
112 : // features they correspond to (use getHWDivFeatures).
113 : // FIXME: TableGen this.
114 : static const struct {
115 : const char *NameCStr;
116 : size_t NameLength;
117 : unsigned ID;
118 :
119 0 : StringRef getName() const { return StringRef(NameCStr, NameLength); }
120 : } HWDivNames[] = {
121 : #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
122 : #include "llvm/Support/ARMTargetParser.def"
123 : };
124 :
125 : // List of CPU names and their arches.
126 : // The same CPU can have multiple arches and can be default on multiple arches.
127 : // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
128 : // When this becomes table-generated, we'd probably need two tables.
129 : // FIXME: TableGen this.
130 : template <typename T> struct CpuNames {
131 : const char *NameCStr;
132 : size_t NameLength;
133 : T ArchID;
134 : bool Default; // is $Name the default CPU for $ArchID ?
135 : unsigned DefaultExtensions;
136 :
137 0 : StringRef getName() const { return StringRef(NameCStr, NameLength); }
138 : };
139 : CpuNames<ARM::ArchKind> CPUNames[] = {
140 : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
141 : { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
142 : #include "llvm/Support/ARMTargetParser.def"
143 : };
144 :
145 : CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
146 : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
147 : { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
148 : #include "llvm/Support/AArch64TargetParser.def"
149 : };
150 :
151 : } // namespace
152 :
153 : // ======================================================= //
154 : // Information by ID
155 : // ======================================================= //
156 :
157 1336 : StringRef ARM::getFPUName(unsigned FPUKind) {
158 1336 : if (FPUKind >= ARM::FK_LAST)
159 0 : return StringRef();
160 1336 : return FPUNames[FPUKind].getName();
161 : }
162 :
163 23 : FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
164 23 : if (FPUKind >= ARM::FK_LAST)
165 : return FPUVersion::NONE;
166 22 : return FPUNames[FPUKind].FPUVersion;
167 : }
168 :
169 23 : ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
170 23 : if (FPUKind >= ARM::FK_LAST)
171 : return ARM::NeonSupportLevel::None;
172 22 : return FPUNames[FPUKind].NeonSupport;
173 : }
174 :
175 23 : ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
176 23 : if (FPUKind >= ARM::FK_LAST)
177 : return ARM::FPURestriction::None;
178 22 : return FPUNames[FPUKind].Restriction;
179 : }
180 :
181 737 : unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
182 : if (CPU == "generic")
183 35 : return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
184 :
185 702 : return StringSwitch<unsigned>(CPU)
186 : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
187 : .Case(NAME, DEFAULT_FPU)
188 : #include "llvm/Support/ARMTargetParser.def"
189 : .Default(ARM::FK_INVALID);
190 : }
191 :
192 861 : unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
193 : if (CPU == "generic")
194 70 : return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
195 :
196 791 : return StringSwitch<unsigned>(CPU)
197 : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
198 : .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
199 : .ArchBaseExtensions | DEFAULT_EXT)
200 : #include "llvm/Support/ARMTargetParser.def"
201 : .Default(ARM::AEK_INVALID);
202 : }
203 :
204 139377 : bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
205 : std::vector<StringRef> &Features) {
206 :
207 139377 : if (HWDivKind == ARM::AEK_INVALID)
208 : return false;
209 :
210 139377 : if (HWDivKind & ARM::AEK_HWDIVARM)
211 69635 : Features.push_back("+hwdiv-arm");
212 : else
213 69742 : Features.push_back("-hwdiv-arm");
214 :
215 139377 : if (HWDivKind & ARM::AEK_HWDIVTHUMB)
216 69672 : Features.push_back("+hwdiv");
217 : else
218 69705 : Features.push_back("-hwdiv");
219 :
220 : return true;
221 : }
222 :
223 139843 : bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
224 : std::vector<StringRef> &Features) {
225 :
226 139843 : if (Extensions == ARM::AEK_INVALID)
227 : return false;
228 :
229 139366 : if (Extensions & ARM::AEK_CRC)
230 69593 : Features.push_back("+crc");
231 : else
232 69773 : Features.push_back("-crc");
233 :
234 139366 : if (Extensions & ARM::AEK_DSP)
235 69678 : Features.push_back("+dsp");
236 : else
237 69688 : Features.push_back("-dsp");
238 :
239 139366 : if (Extensions & ARM::AEK_FP16FML)
240 8055 : Features.push_back("+fp16fml");
241 : else
242 131311 : Features.push_back("-fp16fml");
243 :
244 139366 : if (Extensions & ARM::AEK_RAS)
245 69498 : Features.push_back("+ras");
246 : else
247 69868 : Features.push_back("-ras");
248 :
249 139366 : if (Extensions & ARM::AEK_DOTPROD)
250 65539 : Features.push_back("+dotprod");
251 : else
252 73827 : Features.push_back("-dotprod");
253 :
254 139366 : return getHWDivFeatures(Extensions, Features);
255 : }
256 :
257 1397 : bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
258 : std::vector<StringRef> &Features) {
259 :
260 1397 : if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
261 : return false;
262 :
263 : // fp-only-sp and d16 subtarget features are independent of each other, so we
264 : // must enable/disable both.
265 926 : switch (FPUNames[FPUKind].Restriction) {
266 : case ARM::FPURestriction::SP_D16:
267 17 : Features.push_back("+fp-only-sp");
268 17 : Features.push_back("+d16");
269 17 : break;
270 : case ARM::FPURestriction::D16:
271 30 : Features.push_back("-fp-only-sp");
272 30 : Features.push_back("+d16");
273 30 : break;
274 : case ARM::FPURestriction::None:
275 879 : Features.push_back("-fp-only-sp");
276 879 : Features.push_back("-d16");
277 879 : break;
278 : }
279 :
280 : // FPU version subtarget features are inclusive of lower-numbered ones, so
281 : // enable the one corresponding to this version and disable all that are
282 : // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
283 : // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
284 926 : switch (FPUNames[FPUKind].FPUVersion) {
285 : case ARM::FPUVersion::VFPV5:
286 44 : Features.push_back("+fp-armv8");
287 44 : break;
288 : case ARM::FPUVersion::VFPV4:
289 45 : Features.push_back("+vfp4");
290 45 : Features.push_back("-fp-armv8");
291 45 : break;
292 : case ARM::FPUVersion::VFPV3_FP16:
293 17 : Features.push_back("+vfp3");
294 17 : Features.push_back("+fp16");
295 17 : Features.push_back("-vfp4");
296 17 : Features.push_back("-fp-armv8");
297 17 : break;
298 : case ARM::FPUVersion::VFPV3:
299 104 : Features.push_back("+vfp3");
300 104 : Features.push_back("-fp16");
301 104 : Features.push_back("-vfp4");
302 104 : Features.push_back("-fp-armv8");
303 104 : break;
304 : case ARM::FPUVersion::VFPV2:
305 14 : Features.push_back("+vfp2");
306 14 : Features.push_back("-vfp3");
307 14 : Features.push_back("-fp16");
308 14 : Features.push_back("-vfp4");
309 14 : Features.push_back("-fp-armv8");
310 14 : break;
311 : case ARM::FPUVersion::NONE:
312 702 : Features.push_back("-vfp2");
313 702 : Features.push_back("-vfp3");
314 702 : Features.push_back("-fp16");
315 702 : Features.push_back("-vfp4");
316 702 : Features.push_back("-fp-armv8");
317 702 : break;
318 : }
319 :
320 : // crypto includes neon, so we handle this similarly to FPU version.
321 926 : switch (FPUNames[FPUKind].NeonSupport) {
322 : case ARM::NeonSupportLevel::Crypto:
323 27 : Features.push_back("+neon");
324 27 : Features.push_back("+crypto");
325 27 : break;
326 : case ARM::NeonSupportLevel::Neon:
327 119 : Features.push_back("+neon");
328 119 : Features.push_back("-crypto");
329 119 : break;
330 : case ARM::NeonSupportLevel::None:
331 780 : Features.push_back("-neon");
332 780 : Features.push_back("-crypto");
333 780 : break;
334 : }
335 :
336 : return true;
337 : }
338 :
339 9232 : StringRef llvm::ARM::getArchName(ArchKind AK) {
340 9232 : return ARCHNames[static_cast<unsigned>(AK)].getName();
341 : }
342 :
343 377 : StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
344 377 : return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
345 : }
346 :
347 2373 : StringRef llvm::ARM::getSubArch(ArchKind AK) {
348 2373 : return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
349 : }
350 :
351 82 : unsigned llvm::ARM::getArchAttr(ArchKind AK) {
352 82 : return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
353 : }
354 :
355 3 : StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
356 30 : for (const auto AE : ARCHExtNames) {
357 30 : if (ArchExtKind == AE.ID)
358 : return AE.getName();
359 : }
360 0 : return StringRef();
361 : }
362 :
363 46 : StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
364 : if (ArchExt.startswith("no")) {
365 19 : StringRef ArchExtBase(ArchExt.substr(2));
366 337 : for (const auto AE : ARCHExtNames) {
367 327 : if (AE.NegFeature && ArchExtBase == AE.getName())
368 9 : return StringRef(AE.NegFeature);
369 : }
370 : }
371 653 : for (const auto AE : ARCHExtNames) {
372 631 : if (AE.Feature && ArchExt == AE.getName())
373 15 : return StringRef(AE.Feature);
374 : }
375 :
376 22 : return StringRef();
377 : }
378 :
379 0 : StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
380 0 : for (const auto D : HWDivNames) {
381 0 : if (HWDivKind == D.ID)
382 : return D.getName();
383 : }
384 0 : return StringRef();
385 : }
386 :
387 3326 : StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
388 3326 : ArchKind AK = parseArch(Arch);
389 3326 : if (AK == ARM::ArchKind::INVALID)
390 558 : return StringRef();
391 :
392 : // Look for multiple AKs to find the default for pair AK+Name.
393 173433 : for (const auto CPU : CPUNames) {
394 171816 : if (CPU.ArchID == AK && CPU.Default)
395 : return CPU.getName();
396 : }
397 :
398 : // If we can't find a default then target the architecture instead
399 1617 : return "generic";
400 : }
401 :
402 21 : StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
403 21 : return ARM::getFPUName(FPUKind);
404 : }
405 :
406 0 : ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
407 0 : return ARM::getFPUVersion(FPUKind);
408 : }
409 :
410 0 : ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
411 0 : return ARM::getFPUNeonSupportLevel( FPUKind);
412 : }
413 :
414 0 : ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
415 0 : return ARM::getFPURestriction(FPUKind);
416 : }
417 :
418 21 : unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
419 : if (CPU == "generic")
420 1 : return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
421 :
422 20 : return StringSwitch<unsigned>(CPU)
423 : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
424 : .Case(NAME, DEFAULT_FPU)
425 : #include "llvm/Support/AArch64TargetParser.def"
426 : .Default(ARM::FK_INVALID);
427 : }
428 :
429 675 : unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
430 : if (CPU == "generic")
431 21 : return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
432 :
433 654 : return StringSwitch<unsigned>(CPU)
434 : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
435 : .Case(NAME, \
436 : AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
437 : .ArchBaseExtensions | \
438 : DEFAULT_EXT)
439 : #include "llvm/Support/AArch64TargetParser.def"
440 : .Default(AArch64::AEK_INVALID);
441 : }
442 :
443 21 : AArch64::ArchKind llvm::AArch64::getCPUArchKind(StringRef CPU) {
444 : if (CPU == "generic")
445 : return AArch64::ArchKind::ARMV8A;
446 :
447 0 : return StringSwitch<AArch64::ArchKind>(CPU)
448 : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
449 : .Case(NAME, AArch64::ArchKind:: ID)
450 : #include "llvm/Support/AArch64TargetParser.def"
451 : .Default(AArch64::ArchKind::INVALID);
452 : }
453 :
454 139878 : bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
455 : std::vector<StringRef> &Features) {
456 :
457 139878 : if (Extensions == AArch64::AEK_INVALID)
458 : return false;
459 :
460 139877 : if (Extensions & AArch64::AEK_FP)
461 70246 : Features.push_back("+fp-armv8");
462 139877 : if (Extensions & AArch64::AEK_SIMD)
463 70246 : Features.push_back("+neon");
464 139877 : if (Extensions & AArch64::AEK_CRC)
465 70165 : Features.push_back("+crc");
466 139877 : if (Extensions & AArch64::AEK_CRYPTO)
467 70246 : Features.push_back("+crypto");
468 139877 : if (Extensions & AArch64::AEK_DOTPROD)
469 69706 : Features.push_back("+dotprod");
470 139877 : if (Extensions & AArch64::AEK_FP16FML)
471 8191 : Features.push_back("+fp16fml");
472 139877 : if (Extensions & AArch64::AEK_FP16)
473 69706 : Features.push_back("+fullfp16");
474 139877 : if (Extensions & AArch64::AEK_PROFILE)
475 69631 : Features.push_back("+spe");
476 139877 : if (Extensions & AArch64::AEK_RAS)
477 69706 : Features.push_back("+ras");
478 139877 : if (Extensions & AArch64::AEK_LSE)
479 69749 : Features.push_back("+lse");
480 139877 : if (Extensions & AArch64::AEK_RDM)
481 69768 : Features.push_back("+rdm");
482 139877 : if (Extensions & AArch64::AEK_SVE)
483 69631 : Features.push_back("+sve");
484 139877 : if (Extensions & AArch64::AEK_RCPC)
485 69706 : Features.push_back("+rcpc");
486 :
487 : return true;
488 : }
489 :
490 0 : bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
491 : std::vector<StringRef> &Features) {
492 0 : return ARM::getFPUFeatures(FPUKind, Features);
493 : }
494 :
495 883 : bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
496 : std::vector<StringRef> &Features) {
497 883 : if (AK == AArch64::ArchKind::ARMV8_1A)
498 79 : Features.push_back("+v8.1a");
499 883 : if (AK == AArch64::ArchKind::ARMV8_2A)
500 158 : Features.push_back("+v8.2a");
501 883 : if (AK == AArch64::ArchKind::ARMV8_3A)
502 35 : Features.push_back("+v8.3a");
503 883 : if (AK == AArch64::ArchKind::ARMV8_4A)
504 47 : Features.push_back("+v8.4a");
505 883 : if (AK == AArch64::ArchKind::ARMV8_5A)
506 20 : Features.push_back("+v8.5a");
507 :
508 883 : return AK != AArch64::ArchKind::INVALID;
509 : }
510 :
511 21 : StringRef llvm::AArch64::getArchName(ArchKind AK) {
512 21 : return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
513 : }
514 :
515 21 : StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
516 21 : return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
517 : }
518 :
519 6 : StringRef llvm::AArch64::getSubArch(ArchKind AK) {
520 6 : return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
521 : }
522 :
523 6 : unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
524 6 : return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
525 : }
526 :
527 0 : StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
528 0 : for (const auto &AE : AArch64ARCHExtNames)
529 0 : if (ArchExtKind == AE.ID)
530 0 : return AE.getName();
531 0 : return StringRef();
532 : }
533 :
534 304 : StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
535 : if (ArchExt.startswith("no")) {
536 128 : StringRef ArchExtBase(ArchExt.substr(2));
537 1497 : for (const auto &AE : AArch64ARCHExtNames) {
538 1494 : if (AE.NegFeature && ArchExtBase == AE.getName())
539 125 : return StringRef(AE.NegFeature);
540 : }
541 : }
542 :
543 2225 : for (const auto &AE : AArch64ARCHExtNames)
544 2219 : if (AE.Feature && ArchExt == AE.getName())
545 173 : return StringRef(AE.Feature);
546 6 : return StringRef();
547 : }
548 :
549 6 : StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
550 6 : AArch64::ArchKind AK = parseArch(Arch);
551 6 : if (AK == ArchKind::INVALID)
552 0 : return StringRef();
553 :
554 : // Look for multiple AKs to find the default for pair AK+Name.
555 112 : for (const auto &CPU : AArch64CPUNames)
556 107 : if (CPU.ArchID == AK && CPU.Default)
557 1 : return CPU.getName();
558 :
559 : // If we can't find a default then target the architecture instead
560 5 : return "generic";
561 : }
562 :
563 286 : unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
564 286 : if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
565 283 : return (Arch[1] - 48);
566 : return 0;
567 : }
568 :
569 : // ======================================================= //
570 : // Parsers
571 : // ======================================================= //
572 :
573 15 : static StringRef getHWDivSynonym(StringRef HWDiv) {
574 15 : return StringSwitch<StringRef>(HWDiv)
575 15 : .Case("thumb,arm", "arm,thumb")
576 15 : .Default(HWDiv);
577 : }
578 :
579 81 : static StringRef getFPUSynonym(StringRef FPU) {
580 81 : return StringSwitch<StringRef>(FPU)
581 : .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
582 81 : .Case("vfp2", "vfpv2")
583 81 : .Case("vfp3", "vfpv3")
584 81 : .Case("vfp4", "vfpv4")
585 81 : .Case("vfp3-d16", "vfpv3-d16")
586 81 : .Case("vfp4-d16", "vfpv4-d16")
587 : .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
588 : .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
589 81 : .Case("fp5-sp-d16", "fpv5-sp-d16")
590 : .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
591 : // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
592 81 : .Case("neon-vfpv3", "neon")
593 81 : .Default(FPU);
594 : }
595 :
596 1245133 : static StringRef getArchSynonym(StringRef Arch) {
597 1245133 : return StringSwitch<StringRef>(Arch)
598 1245133 : .Case("v5", "v5t")
599 1245133 : .Case("v5e", "v5te")
600 1245133 : .Case("v6j", "v6")
601 1245133 : .Case("v6hl", "v6k")
602 : .Cases("v6m", "v6sm", "v6s-m", "v6-m")
603 : .Cases("v6z", "v6zk", "v6kz")
604 : .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
605 1245133 : .Case("v7r", "v7-r")
606 1245133 : .Case("v7m", "v7-m")
607 1245133 : .Case("v7em", "v7e-m")
608 : .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
609 1245133 : .Case("v8.1a", "v8.1-a")
610 1245133 : .Case("v8.2a", "v8.2-a")
611 1245133 : .Case("v8.3a", "v8.3-a")
612 1245133 : .Case("v8.4a", "v8.4-a")
613 1245133 : .Case("v8.5a", "v8.5-a")
614 1245133 : .Case("v8r", "v8-r")
615 1245133 : .Case("v8m.base", "v8-m.base")
616 1245133 : .Case("v8m.main", "v8-m.main")
617 1245133 : .Default(Arch);
618 : }
619 :
620 : // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
621 : // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
622 : // "v.+", if the latter, return unmodified string, minus 'eb'.
623 : // If invalid, return empty string.
624 2560377 : StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
625 : size_t offset = StringRef::npos;
626 2560377 : StringRef A = Arch;
627 : StringRef Error = "";
628 :
629 : // Begins with "arm" / "thumb", move past it.
630 : if (A.startswith("arm64"))
631 : offset = 5;
632 : else if (A.startswith("arm"))
633 : offset = 3;
634 : else if (A.startswith("thumb"))
635 : offset = 5;
636 : else if (A.startswith("aarch64")) {
637 : offset = 7;
638 : // AArch64 uses "_be", not "eb" suffix.
639 62594 : if (A.find("eb") != StringRef::npos)
640 0 : return Error;
641 62594 : if (A.substr(offset, 3) == "_be")
642 : offset += 3;
643 : }
644 :
645 : // Ex. "armebv7", move past the "eb".
646 200156 : if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
647 3175 : offset += 2;
648 : // Or, if it ends with eb ("armv7eb"), chop it off.
649 : else if (A.endswith("eb"))
650 952 : A = A.substr(0, A.size() - 2);
651 : // Trim the head
652 2560377 : if (offset != StringRef::npos)
653 200156 : A = A.substr(offset);
654 :
655 : // Empty string means offset reached the end, which means it's valid.
656 2560377 : if (A.empty())
657 159695 : return Arch;
658 :
659 : // Only match non-marketing names
660 2400682 : if (offset != StringRef::npos) {
661 : // Must start with 'vN'.
662 89887 : if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
663 42 : return Error;
664 : // Can't have an extra 'eb'.
665 89845 : if (A.find("eb") != StringRef::npos)
666 3 : return Error;
667 : }
668 :
669 : // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
670 2400637 : return A;
671 : }
672 :
673 15 : unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
674 15 : StringRef Syn = getHWDivSynonym(HWDiv);
675 58 : for (const auto D : HWDivNames) {
676 : if (Syn == D.getName())
677 : return D.ID;
678 : }
679 : return ARM::AEK_INVALID;
680 : }
681 :
682 81 : unsigned llvm::ARM::parseFPU(StringRef FPU) {
683 81 : StringRef Syn = getFPUSynonym(FPU);
684 1054 : for (const auto F : FPUNames) {
685 : if (Syn == F.getName())
686 : return F.ID;
687 : }
688 : return ARM::FK_INVALID;
689 : }
690 :
691 : // Allows partial match, ex. "v7a" matches "armv7a".
692 1244850 : ARM::ArchKind ARM::parseArch(StringRef Arch) {
693 1244850 : Arch = getCanonicalArchName(Arch);
694 1244850 : StringRef Syn = getArchSynonym(Arch);
695 40647804 : for (const auto A : ARCHNames) {
696 : if (A.getName().endswith(Syn))
697 : return A.ID;
698 : }
699 : return ARM::ArchKind::INVALID;
700 : }
701 :
702 136 : unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
703 1467 : for (const auto A : ARCHExtNames) {
704 : if (ArchExt == A.getName())
705 : return A.ID;
706 : }
707 : return ARM::AEK_INVALID;
708 : }
709 :
710 4498 : ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
711 234862 : for (const auto C : CPUNames) {
712 : if (CPU == C.getName())
713 : return C.ArchID;
714 : }
715 : return ARM::ArchKind::INVALID;
716 : }
717 :
718 3 : void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
719 252 : for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
720 249 : if (Arch.ArchID != ARM::ArchKind::INVALID)
721 246 : Values.push_back(Arch.getName());
722 : }
723 3 : }
724 :
725 2 : void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
726 44 : for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
727 42 : if (Arch.ArchID != AArch64::ArchKind::INVALID)
728 40 : Values.push_back(Arch.getName());
729 : }
730 2 : }
731 :
732 : // ARM, Thumb, AArch64
733 38921 : ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
734 38921 : return StringSwitch<ARM::ISAKind>(Arch)
735 38921 : .StartsWith("aarch64", ARM::ISAKind::AARCH64)
736 38921 : .StartsWith("arm64", ARM::ISAKind::AARCH64)
737 38921 : .StartsWith("thumb", ARM::ISAKind::THUMB)
738 38921 : .StartsWith("arm", ARM::ISAKind::ARM)
739 38921 : .Default(ARM::ISAKind::INVALID);
740 : }
741 :
742 : // Little/Big endian
743 38287 : ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
744 : if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
745 : Arch.startswith("aarch64_be"))
746 : return ARM::EndianKind::BIG;
747 :
748 : if (Arch.startswith("arm") || Arch.startswith("thumb")) {
749 : if (Arch.endswith("eb"))
750 : return ARM::EndianKind::BIG;
751 : else
752 37193 : return ARM::EndianKind::LITTLE;
753 : }
754 :
755 : if (Arch.startswith("aarch64"))
756 5 : return ARM::EndianKind::LITTLE;
757 :
758 : return ARM::EndianKind::INVALID;
759 : }
760 :
761 : // Profile A/R/M
762 42108 : ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
763 42108 : Arch = getCanonicalArchName(Arch);
764 42108 : switch (parseArch(Arch)) {
765 : case ARM::ArchKind::ARMV6M:
766 : case ARM::ArchKind::ARMV7M:
767 : case ARM::ArchKind::ARMV7EM:
768 : case ARM::ArchKind::ARMV8MMainline:
769 : case ARM::ArchKind::ARMV8MBaseline:
770 : return ARM::ProfileKind::M;
771 : case ARM::ArchKind::ARMV7R:
772 : case ARM::ArchKind::ARMV8R:
773 : return ARM::ProfileKind::R;
774 : case ARM::ArchKind::ARMV7A:
775 : case ARM::ArchKind::ARMV7VE:
776 : case ARM::ArchKind::ARMV7K:
777 : case ARM::ArchKind::ARMV8A:
778 : case ARM::ArchKind::ARMV8_1A:
779 : case ARM::ArchKind::ARMV8_2A:
780 : case ARM::ArchKind::ARMV8_3A:
781 : case ARM::ArchKind::ARMV8_4A:
782 : case ARM::ArchKind::ARMV8_5A:
783 : return ARM::ProfileKind::A;
784 : case ARM::ArchKind::ARMV2:
785 : case ARM::ArchKind::ARMV2A:
786 : case ARM::ArchKind::ARMV3:
787 : case ARM::ArchKind::ARMV3M:
788 : case ARM::ArchKind::ARMV4:
789 : case ARM::ArchKind::ARMV4T:
790 : case ARM::ArchKind::ARMV5T:
791 : case ARM::ArchKind::ARMV5TE:
792 : case ARM::ArchKind::ARMV5TEJ:
793 : case ARM::ArchKind::ARMV6:
794 : case ARM::ArchKind::ARMV6K:
795 : case ARM::ArchKind::ARMV6T2:
796 : case ARM::ArchKind::ARMV6KZ:
797 : case ARM::ArchKind::ARMV7S:
798 : case ARM::ArchKind::IWMMXT:
799 : case ARM::ArchKind::IWMMXT2:
800 : case ARM::ArchKind::XSCALE:
801 : case ARM::ArchKind::INVALID:
802 : return ARM::ProfileKind::INVALID;
803 : }
804 0 : llvm_unreachable("Unhandled architecture");
805 : }
806 :
807 : // Version number (ex. v7 = 7).
808 43025 : unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
809 43025 : Arch = getCanonicalArchName(Arch);
810 43025 : switch (parseArch(Arch)) {
811 : case ARM::ArchKind::ARMV2:
812 : case ARM::ArchKind::ARMV2A:
813 : return 2;
814 : case ARM::ArchKind::ARMV3:
815 : case ARM::ArchKind::ARMV3M:
816 : return 3;
817 : case ARM::ArchKind::ARMV4:
818 : case ARM::ArchKind::ARMV4T:
819 : return 4;
820 : case ARM::ArchKind::ARMV5T:
821 : case ARM::ArchKind::ARMV5TE:
822 : case ARM::ArchKind::IWMMXT:
823 : case ARM::ArchKind::IWMMXT2:
824 : case ARM::ArchKind::XSCALE:
825 : case ARM::ArchKind::ARMV5TEJ:
826 : return 5;
827 : case ARM::ArchKind::ARMV6:
828 : case ARM::ArchKind::ARMV6K:
829 : case ARM::ArchKind::ARMV6T2:
830 : case ARM::ArchKind::ARMV6KZ:
831 : case ARM::ArchKind::ARMV6M:
832 : return 6;
833 : case ARM::ArchKind::ARMV7A:
834 : case ARM::ArchKind::ARMV7VE:
835 : case ARM::ArchKind::ARMV7R:
836 : case ARM::ArchKind::ARMV7M:
837 : case ARM::ArchKind::ARMV7S:
838 : case ARM::ArchKind::ARMV7EM:
839 : case ARM::ArchKind::ARMV7K:
840 : return 7;
841 : case ARM::ArchKind::ARMV8A:
842 : case ARM::ArchKind::ARMV8_1A:
843 : case ARM::ArchKind::ARMV8_2A:
844 : case ARM::ArchKind::ARMV8_3A:
845 : case ARM::ArchKind::ARMV8_4A:
846 : case ARM::ArchKind::ARMV8_5A:
847 : case ARM::ArchKind::ARMV8R:
848 : case ARM::ArchKind::ARMV8MBaseline:
849 : case ARM::ArchKind::ARMV8MMainline:
850 : return 8;
851 : case ARM::ArchKind::INVALID:
852 : return 0;
853 : }
854 0 : llvm_unreachable("Unhandled architecture");
855 : }
856 :
857 7527 : StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
858 : StringRef ArchName =
859 7527 : CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
860 :
861 7527 : if (TT.isOSBinFormatMachO()) {
862 3870 : if (TT.getEnvironment() == Triple::EABI ||
863 3758 : TT.getOS() == Triple::UnknownOS ||
864 1821 : llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
865 170 : return "aapcs";
866 1767 : if (TT.isWatchABI())
867 77 : return "aapcs16";
868 1690 : return "apcs-gnu";
869 5590 : } else if (TT.isOSWindows())
870 : // FIXME: this is invalid for WindowsCE.
871 313 : return "aapcs";
872 :
873 : // Select the default based on the platform.
874 5277 : switch (TT.getEnvironment()) {
875 : case Triple::Android:
876 : case Triple::GNUEABI:
877 : case Triple::GNUEABIHF:
878 : case Triple::MuslEABI:
879 : case Triple::MuslEABIHF:
880 1894 : return "aapcs-linux";
881 : case Triple::EABIHF:
882 : case Triple::EABI:
883 2173 : return "aapcs";
884 : default:
885 1210 : if (TT.isOSNetBSD())
886 10 : return "apcs-gnu";
887 1200 : if (TT.isOSOpenBSD())
888 15 : return "aapcs-linux";
889 1185 : return "aapcs";
890 : }
891 : }
892 :
893 286 : StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
894 286 : return ARM::getCanonicalArchName(Arch);
895 : }
896 :
897 0 : unsigned llvm::AArch64::parseFPU(StringRef FPU) {
898 0 : return ARM::parseFPU(FPU);
899 : }
900 :
901 : // Allows partial match, ex. "v8a" matches "armv8a".
902 286 : AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
903 286 : Arch = getCanonicalArchName(Arch);
904 286 : if (checkArchVersion(Arch) < 8)
905 : return ArchKind::INVALID;
906 :
907 283 : StringRef Syn = getArchSynonym(Arch);
908 1179 : for (const auto A : AArch64ARCHNames) {
909 : if (A.getName().endswith(Syn))
910 : return A.ID;
911 : }
912 : return ArchKind::INVALID;
913 : }
914 :
915 39 : AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) {
916 538 : for (const auto A : AArch64ARCHExtNames) {
917 : if (ArchExt == A.getName())
918 : return static_cast<ArchExtKind>(A.ID);
919 : }
920 : return AArch64::AEK_INVALID;
921 : }
922 :
923 668 : AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
924 5045 : for (const auto C : AArch64CPUNames) {
925 : if (CPU == C.getName())
926 : return C.ArchID;
927 : }
928 : return ArchKind::INVALID;
929 : }
930 :
931 : // ARM, Thumb, AArch64
932 0 : ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
933 0 : return ARM::parseArchISA(Arch);
934 : }
935 :
936 : // Little/Big endian
937 0 : ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
938 0 : return ARM::parseArchEndian(Arch);
939 : }
940 :
941 : // Profile A/R/M
942 0 : ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
943 0 : return ARM::parseArchProfile(Arch);
944 : }
945 :
946 : // Version number (ex. v8 = 8).
947 0 : unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
948 0 : return ARM::parseArchVersion(Arch);
949 : }
950 :
951 1574 : bool llvm::AArch64::isX18ReservedByDefault(const Triple &TT) {
952 2762 : return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() ||
953 1574 : TT.isOSWindows();
954 : }
955 :
956 : namespace {
957 :
958 : struct GPUInfo {
959 : StringLiteral Name;
960 : StringLiteral CanonicalName;
961 : AMDGPU::GPUKind Kind;
962 : unsigned Features;
963 : };
964 :
965 : constexpr GPUInfo R600GPUs[26] = {
966 : // Name Canonical Kind Features
967 : // Name
968 : {{"r600"}, {"r600"}, GK_R600, FEATURE_NONE },
969 : {{"rv630"}, {"r600"}, GK_R600, FEATURE_NONE },
970 : {{"rv635"}, {"r600"}, GK_R600, FEATURE_NONE },
971 : {{"r630"}, {"r630"}, GK_R630, FEATURE_NONE },
972 : {{"rs780"}, {"rs880"}, GK_RS880, FEATURE_NONE },
973 : {{"rs880"}, {"rs880"}, GK_RS880, FEATURE_NONE },
974 : {{"rv610"}, {"rs880"}, GK_RS880, FEATURE_NONE },
975 : {{"rv620"}, {"rs880"}, GK_RS880, FEATURE_NONE },
976 : {{"rv670"}, {"rv670"}, GK_RV670, FEATURE_NONE },
977 : {{"rv710"}, {"rv710"}, GK_RV710, FEATURE_NONE },
978 : {{"rv730"}, {"rv730"}, GK_RV730, FEATURE_NONE },
979 : {{"rv740"}, {"rv770"}, GK_RV770, FEATURE_NONE },
980 : {{"rv770"}, {"rv770"}, GK_RV770, FEATURE_NONE },
981 : {{"cedar"}, {"cedar"}, GK_CEDAR, FEATURE_NONE },
982 : {{"palm"}, {"cedar"}, GK_CEDAR, FEATURE_NONE },
983 : {{"cypress"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA },
984 : {{"hemlock"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA },
985 : {{"juniper"}, {"juniper"}, GK_JUNIPER, FEATURE_NONE },
986 : {{"redwood"}, {"redwood"}, GK_REDWOOD, FEATURE_NONE },
987 : {{"sumo"}, {"sumo"}, GK_SUMO, FEATURE_NONE },
988 : {{"sumo2"}, {"sumo"}, GK_SUMO, FEATURE_NONE },
989 : {{"barts"}, {"barts"}, GK_BARTS, FEATURE_NONE },
990 : {{"caicos"}, {"caicos"}, GK_CAICOS, FEATURE_NONE },
991 : {{"aruba"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA },
992 : {{"cayman"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA },
993 : {{"turks"}, {"turks"}, GK_TURKS, FEATURE_NONE }
994 : };
995 :
996 : // This table should be sorted by the value of GPUKind
997 : // Don't bother listing the implicitly true features
998 : constexpr GPUInfo AMDGCNGPUs[32] = {
999 : // Name Canonical Kind Features
1000 : // Name
1001 : {{"gfx600"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32},
1002 : {{"tahiti"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32},
1003 : {{"gfx601"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
1004 : {{"hainan"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
1005 : {{"oland"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
1006 : {{"pitcairn"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
1007 : {{"verde"}, {"gfx601"}, GK_GFX601, FEATURE_NONE},
1008 : {{"gfx700"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
1009 : {{"kaveri"}, {"gfx700"}, GK_GFX700, FEATURE_NONE},
1010 : {{"gfx701"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32},
1011 : {{"hawaii"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32},
1012 : {{"gfx702"}, {"gfx702"}, GK_GFX702, FEATURE_FAST_FMA_F32},
1013 : {{"gfx703"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
1014 : {{"kabini"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
1015 : {{"mullins"}, {"gfx703"}, GK_GFX703, FEATURE_NONE},
1016 : {{"gfx704"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
1017 : {{"bonaire"}, {"gfx704"}, GK_GFX704, FEATURE_NONE},
1018 : {{"gfx801"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1019 : {{"carrizo"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1020 : {{"gfx802"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
1021 : {{"iceland"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
1022 : {{"tonga"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32},
1023 : {{"gfx803"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
1024 : {{"fiji"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
1025 : {{"polaris10"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
1026 : {{"polaris11"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32},
1027 : {{"gfx810"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32},
1028 : {{"stoney"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32},
1029 : {{"gfx900"}, {"gfx900"}, GK_GFX900, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1030 : {{"gfx902"}, {"gfx902"}, GK_GFX902, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1031 : {{"gfx904"}, {"gfx904"}, GK_GFX904, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1032 : {{"gfx906"}, {"gfx906"}, GK_GFX906, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1033 : };
1034 :
1035 514 : const GPUInfo *getArchEntry(AMDGPU::GPUKind AK, ArrayRef<GPUInfo> Table) {
1036 : GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE };
1037 :
1038 : auto I = std::lower_bound(Table.begin(), Table.end(), Search,
1039 : [](const GPUInfo &A, const GPUInfo &B) {
1040 0 : return A.Kind < B.Kind;
1041 : });
1042 :
1043 514 : if (I == Table.end())
1044 0 : return nullptr;
1045 : return I;
1046 : }
1047 :
1048 : } // namespace
1049 :
1050 77 : StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) {
1051 77 : if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
1052 77 : return Entry->CanonicalName;
1053 0 : return "";
1054 : }
1055 :
1056 60 : StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
1057 60 : if (const auto *Entry = getArchEntry(AK, R600GPUs))
1058 60 : return Entry->CanonicalName;
1059 0 : return "";
1060 : }
1061 :
1062 1139922 : AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) {
1063 22412584 : for (const auto C : AMDGCNGPUs) {
1064 : if (CPU == C.Name)
1065 : return C.Kind;
1066 : }
1067 :
1068 : return AMDGPU::GPUKind::GK_NONE;
1069 : }
1070 :
1071 226 : AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) {
1072 3736 : for (const auto C : R600GPUs) {
1073 : if (CPU == C.Name)
1074 : return C.Kind;
1075 : }
1076 :
1077 : return AMDGPU::GPUKind::GK_NONE;
1078 : }
1079 :
1080 249 : unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) {
1081 249 : if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
1082 249 : return Entry->Features;
1083 : return FEATURE_NONE;
1084 : }
1085 :
1086 128 : unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
1087 128 : if (const auto *Entry = getArchEntry(AK, R600GPUs))
1088 128 : return Entry->Features;
1089 : return FEATURE_NONE;
1090 : }
1091 :
1092 1 : void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) {
1093 : // XXX: Should this only report unique canonical names?
1094 33 : for (const auto C : AMDGCNGPUs)
1095 32 : Values.push_back(C.Name);
1096 1 : }
1097 :
1098 1 : void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) {
1099 27 : for (const auto C : R600GPUs)
1100 26 : Values.push_back(C.Name);
1101 1 : }
1102 :
1103 1433157 : AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
1104 : if (GPU == "generic")
1105 293883 : return {7, 0, 0};
1106 :
1107 1139274 : AMDGPU::GPUKind AK = parseArchAMDGCN(GPU);
1108 1139274 : if (AK == AMDGPU::GPUKind::GK_NONE)
1109 487 : return {0, 0, 0};
1110 :
1111 1138787 : switch (AK) {
1112 94749 : case GK_GFX600: return {6, 0, 0};
1113 86755 : case GK_GFX601: return {6, 0, 1};
1114 68994 : case GK_GFX700: return {7, 0, 0};
1115 45259 : case GK_GFX701: return {7, 0, 1};
1116 128 : case GK_GFX702: return {7, 0, 2};
1117 763 : case GK_GFX703: return {7, 0, 3};
1118 77787 : case GK_GFX704: return {7, 0, 4};
1119 21374 : case GK_GFX801: return {8, 0, 1};
1120 269241 : case GK_GFX802: return {8, 0, 2};
1121 178894 : case GK_GFX803: return {8, 0, 3};
1122 6624 : case GK_GFX810: return {8, 1, 0};
1123 270479 : case GK_GFX900: return {9, 0, 0};
1124 2110 : case GK_GFX902: return {9, 0, 2};
1125 130 : case GK_GFX904: return {9, 0, 4};
1126 15500 : case GK_GFX906: return {9, 0, 6};
1127 0 : default: return {0, 0, 0};
1128 : }
1129 : }
|