Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/TargetParser.cpp
Line
Count
Source (jump to first uncovered line)
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/StringExtras.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
26
namespace {
27
28
// List of canonical FPU names (use getFPUSynonym) and which architectural
29
// features they correspond to (use getFPUFeatures).
30
// FIXME: TableGen this.
31
// The entries must appear in the order listed in ARM::FPUKind for correct indexing
32
static const struct {
33
  const char *NameCStr;
34
  size_t NameLength;
35
  ARM::FPUKind ID;
36
  ARM::FPUVersion FPUVersion;
37
  ARM::NeonSupportLevel NeonSupport;
38
  ARM::FPURestriction Restriction;
39
40
3.04k
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
41
} FPUNames[] = {
42
#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
43
  { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
44
#include "llvm/Support/ARMTargetParser.def"
45
};
46
47
// List of canonical arch names (use getArchSynonym).
48
// This table also provides the build attribute fields for CPU arch
49
// and Arch ID, according to the Addenda to the ARM ABI, chapters
50
// 2.4 and 2.3.5.2 respectively.
51
// FIXME: SubArch values were simplified to fit into the expectations
52
// of the triples and are not conforming with their official names.
53
// Check to see if the expectation should be changed.
54
// FIXME: TableGen this.
55
template <typename T> struct ArchNames {
56
  const char *NameCStr;
57
  size_t NameLength;
58
  const char *CPUAttrCStr;
59
  size_t CPUAttrLength;
60
  const char *SubArchCStr;
61
  size_t SubArchLength;
62
  unsigned DefaultFPU;
63
  unsigned ArchBaseExtensions;
64
  T ID;
65
  ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
66
67
42.1M
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::AArch64::ArchKind>::getName() const
Line
Count
Source
67
282
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::ARM::ArchKind>::getName() const
Line
Count
Source
67
42.1M
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
68
69
  // CPU class in build attributes.
70
991
  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::ARM::ArchKind>::getCPUAttr() const
Line
Count
Source
70
971
  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::AArch64::ArchKind>::getCPUAttr() const
Line
Count
Source
70
20
  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
71
72
  // Sub-Arch name.
73
13.9k
  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::AArch64::ArchKind>::getSubArch() const
Line
Count
Source
73
4
  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
TargetParser.cpp:(anonymous namespace)::ArchNames<llvm::ARM::ArchKind>::getSubArch() const
Line
Count
Source
73
13.9k
  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
74
};
75
ArchNames<ARM::ArchKind> ARCHNames[] = {
76
#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
77
  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
78
   sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
79
#include "llvm/Support/ARMTargetParser.def"
80
};
81
82
ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
83
 #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
84
   {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
85
    sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
86
 #include "llvm/Support/AArch64TargetParser.def"
87
 };
88
89
90
// List of Arch Extension names.
91
// FIXME: TableGen this.
92
static const struct {
93
  const char *NameCStr;
94
  size_t NameLength;
95
  unsigned ID;
96
  const char *Feature;
97
  const char *NegFeature;
98
99
2.37k
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
100
} ARCHExtNames[] = {
101
#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
102
  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
103
#include "llvm/Support/ARMTargetParser.def"
104
},AArch64ARCHExtNames[] = {
105
#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
106
  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
107
#include "llvm/Support/AArch64TargetParser.def"
108
};
109
110
// List of HWDiv names (use getHWDivSynonym) and which architectural
111
// features they correspond to (use getHWDivFeatures).
112
// FIXME: TableGen this.
113
static const struct {
114
  const char *NameCStr;
115
  size_t NameLength;
116
  unsigned ID;
117
118
102
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
119
} HWDivNames[] = {
120
#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
121
#include "llvm/Support/ARMTargetParser.def"
122
};
123
124
// List of CPU names and their arches.
125
// The same CPU can have multiple arches and can be default on multiple arches.
126
// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
127
// When this becomes table-generated, we'd probably need two tables.
128
// FIXME: TableGen this.
129
template <typename T> struct CpuNames {
130
  const char *NameCStr;
131
  size_t NameLength;
132
  T ArchID;
133
  bool Default; // is $Name the default CPU for $ArchID ?
134
  unsigned DefaultExtensions;
135
136
998k
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
TargetParser.cpp:(anonymous namespace)::CpuNames<llvm::AArch64::ArchKind>::getName() const
Line
Count
Source
136
324k
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
TargetParser.cpp:(anonymous namespace)::CpuNames<llvm::ARM::ArchKind>::getName() const
Line
Count
Source
136
673k
  StringRef getName() const { return StringRef(NameCStr, NameLength); }
137
};
138
CpuNames<ARM::ArchKind> CPUNames[] = {
139
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
140
  { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
141
#include "llvm/Support/ARMTargetParser.def"
142
};
143
144
CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
145
 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
146
   { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
147
 #include "llvm/Support/AArch64TargetParser.def"
148
 };
149
150
} // namespace
151
152
// ======================================================= //
153
// Information by ID
154
// ======================================================= //
155
156
1.21k
StringRef ARM::getFPUName(unsigned FPUKind) {
157
1.21k
  if (FPUKind >= ARM::FK_LAST)
158
0
    return StringRef();
159
1.21k
  return FPUNames[FPUKind].getName();
160
1.21k
}
161
162
23
FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
163
23
  if (FPUKind >= ARM::FK_LAST)
164
1
    return FPUVersion::NONE;
165
22
  return FPUNames[FPUKind].FPUVersion;
166
22
}
167
168
23
ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
169
23
  if (FPUKind >= ARM::FK_LAST)
170
1
    return ARM::NeonSupportLevel::None;
171
22
  return FPUNames[FPUKind].NeonSupport;
172
22
}
173
174
23
ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
175
23
  if (FPUKind >= ARM::FK_LAST)
176
1
    return ARM::FPURestriction::None;
177
22
  return FPUNames[FPUKind].Restriction;
178
22
}
179
180
3.27k
unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
181
3.27k
  if (CPU == "generic")
182
852
    return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
183
2.41k
184
2.41k
  return StringSwitch<unsigned>(CPU)
185
2.41k
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
186
200k
    .Case(NAME, DEFAULT_FPU)
187
2.41k
#include "llvm/Support/ARMTargetParser.def"
188
3.27k
    .Default(ARM::FK_INVALID);
189
3.27k
}
190
191
3.68k
unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
192
3.68k
  if (CPU == "generic")
193
881
    return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
194
2.80k
195
2.80k
  return StringSwitch<unsigned>(CPU)
196
2.80k
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
197
232k
    .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
198
232k
            .ArchBaseExtensions | DEFAULT_EXT)
199
2.80k
#include "llvm/Support/ARMTargetParser.def"
200
3.68k
    .Default(ARM::AEK_INVALID);
201
3.68k
}
202
203
bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
204
9.17k
                                 std::vector<StringRef> &Features) {
205
9.17k
206
9.17k
  if (HWDivKind == ARM::AEK_INVALID)
207
1
    return false;
208
9.17k
209
9.17k
  
if (9.17k
HWDivKind & ARM::AEK_HWDIVARM9.17k
)
210
4.26k
    Features.push_back("+hwdiv-arm");
211
9.17k
  else
212
4.90k
    Features.push_back("-hwdiv-arm");
213
9.17k
214
9.17k
  if (HWDivKind & ARM::AEK_HWDIVTHUMB)
215
4.95k
    Features.push_back("+hwdiv");
216
9.17k
  else
217
4.21k
    Features.push_back("-hwdiv");
218
9.17k
219
9.17k
  return true;
220
9.17k
}
221
222
bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
223
9.55k
                                     std::vector<StringRef> &Features) {
224
9.55k
225
9.55k
  if (Extensions == ARM::AEK_INVALID)
226
410
    return false;
227
9.14k
228
9.14k
  
if (9.14k
Extensions & ARM::AEK_CRC9.14k
)
229
3.17k
    Features.push_back("+crc");
230
9.14k
  else
231
5.97k
    Features.push_back("-crc");
232
9.14k
233
9.14k
  if (Extensions & ARM::AEK_DSP)
234
5.58k
    Features.push_back("+dsp");
235
9.14k
  else
236
3.56k
    Features.push_back("-dsp");
237
9.14k
238
9.14k
  if (Extensions & ARM::AEK_RAS)
239
1.93k
    Features.push_back("+ras");
240
9.14k
  else
241
7.21k
    Features.push_back("-ras");
242
9.14k
243
9.14k
  if (Extensions & ARM::AEK_DOTPROD)
244
23
    Features.push_back("+dotprod");
245
9.14k
  else
246
9.12k
    Features.push_back("-dotprod");
247
9.55k
248
9.55k
  return getHWDivFeatures(Extensions, Features);
249
9.55k
}
250
251
bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
252
3.35k
                               std::vector<StringRef> &Features) {
253
3.35k
254
3.35k
  if (
FPUKind >= ARM::FK_LAST || 3.35k
FPUKind == ARM::FK_INVALID3.35k
)
255
396
    return false;
256
2.96k
257
2.96k
  // fp-only-sp and d16 subtarget features are independent of each other, so we
258
2.96k
  // must enable/disable both.
259
2.96k
  switch (FPUNames[FPUKind].Restriction) {
260
430
  case ARM::FPURestriction::SP_D16:
261
430
    Features.push_back("+fp-only-sp");
262
430
    Features.push_back("+d16");
263
430
    break;
264
43
  case ARM::FPURestriction::D16:
265
43
    Features.push_back("-fp-only-sp");
266
43
    Features.push_back("+d16");
267
43
    break;
268
2.48k
  case ARM::FPURestriction::None:
269
2.48k
    Features.push_back("-fp-only-sp");
270
2.48k
    Features.push_back("-d16");
271
2.48k
    break;
272
2.96k
  }
273
2.96k
274
2.96k
  // FPU version subtarget features are inclusive of lower-numbered ones, so
275
2.96k
  // enable the one corresponding to this version and disable all that are
276
2.96k
  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
277
2.96k
  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
278
2.96k
  switch (FPUNames[FPUKind].FPUVersion) {
279
97
  case ARM::FPUVersion::VFPV5:
280
97
    Features.push_back("+fp-armv8");
281
97
    break;
282
1.41k
  case ARM::FPUVersion::VFPV4:
283
1.41k
    Features.push_back("+vfp4");
284
1.41k
    Features.push_back("-fp-armv8");
285
1.41k
    break;
286
33
  case ARM::FPUVersion::VFPV3_FP16:
287
33
    Features.push_back("+vfp3");
288
33
    Features.push_back("+fp16");
289
33
    Features.push_back("-vfp4");
290
33
    Features.push_back("-fp-armv8");
291
33
    break;
292
904
  case ARM::FPUVersion::VFPV3:
293
904
    Features.push_back("+vfp3");
294
904
    Features.push_back("-fp16");
295
904
    Features.push_back("-vfp4");
296
904
    Features.push_back("-fp-armv8");
297
904
    break;
298
20
  case ARM::FPUVersion::VFPV2:
299
20
    Features.push_back("+vfp2");
300
20
    Features.push_back("-vfp3");
301
20
    Features.push_back("-fp16");
302
20
    Features.push_back("-vfp4");
303
20
    Features.push_back("-fp-armv8");
304
20
    break;
305
493
  case ARM::FPUVersion::NONE:
306
493
    Features.push_back("-vfp2");
307
493
    Features.push_back("-vfp3");
308
493
    Features.push_back("-fp16");
309
493
    Features.push_back("-vfp4");
310
493
    Features.push_back("-fp-armv8");
311
493
    break;
312
2.96k
  }
313
2.96k
314
2.96k
  // crypto includes neon, so we handle this similarly to FPU version.
315
2.96k
  switch (FPUNames[FPUKind].NeonSupport) {
316
65
  case ARM::NeonSupportLevel::Crypto:
317
65
    Features.push_back("+neon");
318
65
    Features.push_back("+crypto");
319
65
    break;
320
1.87k
  case ARM::NeonSupportLevel::Neon:
321
1.87k
    Features.push_back("+neon");
322
1.87k
    Features.push_back("-crypto");
323
1.87k
    break;
324
1.02k
  case ARM::NeonSupportLevel::None:
325
1.02k
    Features.push_back("-neon");
326
1.02k
    Features.push_back("-crypto");
327
1.02k
    break;
328
2.96k
  }
329
2.96k
330
2.96k
  return true;
331
2.96k
}
332
333
16.3k
StringRef llvm::ARM::getArchName(ArchKind AK) {
334
16.3k
  return ARCHNames[static_cast<unsigned>(AK)].getName();
335
16.3k
}
336
337
971
StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
338
971
  return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
339
971
}
340
341
13.9k
StringRef llvm::ARM::getSubArch(ArchKind AK) {
342
13.9k
  return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
343
13.9k
}
344
345
66
unsigned llvm::ARM::getArchAttr(ArchKind AK) {
346
66
  return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
347
66
}
348
349
3
StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
350
24
  for (const auto AE : ARCHExtNames) {
351
24
    if (ArchExtKind == AE.ID)
352
3
      return AE.getName();
353
0
  }
354
0
  return StringRef();
355
0
}
356
357
56
StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
358
56
  if (
ArchExt.startswith("no")56
) {
359
25
    StringRef ArchExtBase(ArchExt.substr(2));
360
302
    for (const auto AE : ARCHExtNames) {
361
302
      if (
AE.NegFeature && 302
ArchExtBase == AE.getName()112
)
362
15
        return StringRef(AE.NegFeature);
363
41
    }
364
25
  }
365
41
  
for (const auto AE : ARCHExtNames) 41
{
366
559
    if (
AE.Feature && 559
ArchExt == AE.getName()199
)
367
19
      return StringRef(AE.Feature);
368
22
  }
369
22
370
22
  return StringRef();
371
22
}
372
373
0
StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
374
0
  for (const auto D : HWDivNames) {
375
0
    if (HWDivKind == D.ID)
376
0
      return D.getName();
377
0
  }
378
0
  return StringRef();
379
0
}
380
381
16.8k
StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
382
16.8k
  ArchKind AK = parseArch(Arch);
383
16.8k
  if (AK == ARM::ArchKind::INVALID)
384
683
    return StringRef();
385
16.2k
386
16.2k
  // Look for multiple AKs to find the default for pair AK+Name.
387
16.2k
  
for (const auto CPU : CPUNames) 16.2k
{
388
1.19M
    if (
CPU.ArchID == AK && 1.19M
CPU.Default60.9k
)
389
7.03k
      return CPU.getName();
390
9.17k
  }
391
9.17k
392
9.17k
  // If we can't find a default then target the architecture instead
393
9.17k
  return "generic";
394
9.17k
}
395
396
20
StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
397
20
  return ARM::getFPUName(FPUKind);
398
20
}
399
400
0
ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
401
0
  return ARM::getFPUVersion(FPUKind);
402
0
}
403
404
0
ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
405
0
  return ARM::getFPUNeonSupportLevel( FPUKind);
406
0
}
407
408
0
ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
409
0
  return ARM::getFPURestriction(FPUKind);
410
0
}
411
412
20
unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
413
20
  if (CPU == "generic")
414
1
    return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
415
19
416
19
  return StringSwitch<unsigned>(CPU)
417
19
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
418
380
    .Case(NAME, DEFAULT_FPU)
419
19
#include "llvm/Support/AArch64TargetParser.def"
420
20
    .Default(ARM::FK_INVALID);
421
20
}
422
423
27.2k
unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
424
27.2k
  if (CPU == "generic")
425
13
    return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
426
27.1k
427
27.1k
  return StringSwitch<unsigned>(CPU)
428
27.1k
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
429
543k
  .Case(NAME,                                                                  \
430
543k
        AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
431
543k
            .ArchBaseExtensions | \
432
543k
            DEFAULT_EXT)
433
27.1k
#include "llvm/Support/AArch64TargetParser.def"
434
27.2k
    .Default(AArch64::AEK_INVALID);
435
27.2k
}
436
437
bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
438
35.3k
                                     std::vector<StringRef> &Features) {
439
35.3k
440
35.3k
  if (Extensions == AArch64::AEK_INVALID)
441
1
    return false;
442
35.3k
443
35.3k
  
if (35.3k
Extensions & AArch64::AEK_FP35.3k
)
444
31.2k
    Features.push_back("+fp-armv8");
445
35.3k
  if (Extensions & AArch64::AEK_SIMD)
446
31.2k
    Features.push_back("+neon");
447
35.3k
  if (Extensions & AArch64::AEK_CRC)
448
4.35k
    Features.push_back("+crc");
449
35.3k
  if (Extensions & AArch64::AEK_CRYPTO)
450
31.2k
    Features.push_back("+crypto");
451
35.3k
  if (Extensions & AArch64::AEK_DOTPROD)
452
4.13k
    Features.push_back("+dotprod");
453
35.3k
  if (Extensions & AArch64::AEK_FP16)
454
4.13k
    Features.push_back("+fullfp16");
455
35.3k
  if (Extensions & AArch64::AEK_PROFILE)
456
4.09k
    Features.push_back("+spe");
457
35.3k
  if (Extensions & AArch64::AEK_RAS)
458
4.13k
    Features.push_back("+ras");
459
35.3k
  if (Extensions & AArch64::AEK_LSE)
460
4.16k
    Features.push_back("+lse");
461
35.3k
  if (Extensions & AArch64::AEK_RDM)
462
4.17k
    Features.push_back("+rdm");
463
35.3k
  if (Extensions & AArch64::AEK_SVE)
464
4.09k
    Features.push_back("+sve");
465
35.3k
  if (Extensions & AArch64::AEK_RCPC)
466
4.13k
    Features.push_back("+rcpc");
467
35.3k
468
35.3k
  return true;
469
35.3k
}
470
471
bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
472
0
                               std::vector<StringRef> &Features) {
473
0
  return ARM::getFPUFeatures(FPUKind, Features);
474
0
}
475
476
bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
477
27.2k
                                    std::vector<StringRef> &Features) {
478
27.2k
  if (AK == AArch64::ArchKind::ARMV8_1A)
479
56
    Features.push_back("+v8.1a");
480
27.2k
  if (AK == AArch64::ArchKind::ARMV8_2A)
481
57
    Features.push_back("+v8.2a");
482
27.2k
  if (AK == AArch64::ArchKind::ARMV8_3A)
483
4
    Features.push_back("+v8.3a");
484
27.2k
485
27.2k
  return AK != AArch64::ArchKind::INVALID;
486
27.2k
}
487
488
20
StringRef llvm::AArch64::getArchName(ArchKind AK) {
489
20
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
490
20
}
491
492
20
StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
493
20
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
494
20
}
495
496
4
StringRef llvm::AArch64::getSubArch(ArchKind AK) {
497
4
  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
498
4
}
499
500
4
unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
501
4
  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
502
4
}
503
504
0
StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
505
0
  for (const auto &AE : AArch64ARCHExtNames)
506
0
    
if (0
ArchExtKind == AE.ID0
)
507
0
      return AE.getName();
508
0
  return StringRef();
509
0
}
510
511
124
StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
512
124
  if (
ArchExt.startswith("no")124
) {
513
62
    StringRef ArchExtBase(ArchExt.substr(2));
514
482
    for (const auto &AE : AArch64ARCHExtNames) {
515
482
      if (
AE.NegFeature && 482
ArchExtBase == AE.getName()358
)
516
59
        return StringRef(AE.NegFeature);
517
65
    }
518
62
  }
519
65
520
65
  for (const auto &AE : AArch64ARCHExtNames)
521
508
    
if (508
AE.Feature && 508
ArchExt == AE.getName()378
)
522
59
      return StringRef(AE.Feature);
523
6
  return StringRef();
524
6
}
525
526
4
StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
527
4
  AArch64::ArchKind AK = parseArch(Arch);
528
4
  if (AK == ArchKind::INVALID)
529
0
    return StringRef();
530
4
531
4
  // Look for multiple AKs to find the default for pair AK+Name.
532
4
  for (const auto &CPU : AArch64CPUNames)
533
62
    
if (62
CPU.ArchID == AK && 62
CPU.Default6
)
534
1
      return CPU.getName();
535
3
536
3
  // If we can't find a default then target the architecture instead
537
3
  return "generic";
538
3
}
539
540
93
unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
541
93
  if (
Arch[0] == 'v' && 93
std::isdigit(Arch[1])90
)
542
90
    return (Arch[1] - 48);
543
3
  return 0;
544
3
}
545
546
// ======================================================= //
547
// Parsers
548
// ======================================================= //
549
550
29
static StringRef getHWDivSynonym(StringRef HWDiv) {
551
29
  return StringSwitch<StringRef>(HWDiv)
552
29
      .Case("thumb,arm", "arm,thumb")
553
29
      .Default(HWDiv);
554
29
}
555
556
147
static StringRef getFPUSynonym(StringRef FPU) {
557
147
  return StringSwitch<StringRef>(FPU)
558
147
      .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
559
147
      .Case("vfp2", "vfpv2")
560
147
      .Case("vfp3", "vfpv3")
561
147
      .Case("vfp4", "vfpv4")
562
147
      .Case("vfp3-d16", "vfpv3-d16")
563
147
      .Case("vfp4-d16", "vfpv4-d16")
564
147
      .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
565
147
      .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
566
147
      .Case("fp5-sp-d16", "fpv5-sp-d16")
567
147
      .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
568
147
      // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
569
147
      .Case("neon-vfpv3", "neon")
570
147
      .Default(FPU);
571
147
}
572
573
1.78M
static StringRef getArchSynonym(StringRef Arch) {
574
1.78M
  return StringSwitch<StringRef>(Arch)
575
1.78M
      .Case("v5", "v5t")
576
1.78M
      .Case("v5e", "v5te")
577
1.78M
      .Case("v6j", "v6")
578
1.78M
      .Case("v6hl", "v6k")
579
1.78M
      .Cases("v6m", "v6sm", "v6s-m", "v6-m")
580
1.78M
      .Cases("v6z", "v6zk", "v6kz")
581
1.78M
      .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
582
1.78M
      .Case("v7r", "v7-r")
583
1.78M
      .Case("v7m", "v7-m")
584
1.78M
      .Case("v7em", "v7e-m")
585
1.78M
      .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
586
1.78M
      .Case("v8.1a", "v8.1-a")
587
1.78M
      .Case("v8.2a", "v8.2-a")
588
1.78M
      .Case("v8.3a", "v8.3-a")
589
1.78M
      .Case("v8r", "v8-r")
590
1.78M
      .Case("v8m.base", "v8-m.base")
591
1.78M
      .Case("v8m.main", "v8-m.main")
592
1.78M
      .Default(Arch);
593
1.78M
}
594
595
// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
596
// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
597
// "v.+", if the latter, return unmodified string, minus 'eb'.
598
// If invalid, return empty string.
599
3.63M
StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
600
3.63M
  size_t offset = StringRef::npos;
601
3.63M
  StringRef A = Arch;
602
3.63M
  StringRef Error = "";
603
3.63M
604
3.63M
  // Begins with "arm" / "thumb", move past it.
605
3.63M
  if (A.startswith("arm64"))
606
535k
    offset = 5;
607
3.09M
  else 
if (3.09M
A.startswith("arm")3.09M
)
608
132k
    offset = 3;
609
2.96M
  else 
if (2.96M
A.startswith("thumb")2.96M
)
610
166k
    offset = 5;
611
2.79M
  else 
if (2.79M
A.startswith("aarch64")2.79M
) {
612
1.36M
    offset = 7;
613
1.36M
    // AArch64 uses "_be", not "eb" suffix.
614
1.36M
    if (A.find("eb") != StringRef::npos)
615
0
      return Error;
616
1.36M
    
if (1.36M
A.substr(offset, 3) == "_be"1.36M
)
617
1.20k
      offset += 3;
618
3.09M
  }
619
3.63M
620
3.63M
  // Ex. "armebv7", move past the "eb".
621
3.63M
  
if (3.63M
offset != StringRef::npos && 3.63M
A.substr(offset, 2) == "eb"2.20M
)
622
3.51k
    offset += 2;
623
3.63M
  // Or, if it ends with eb ("armv7eb"), chop it off.
624
3.62M
  else 
if (3.62M
A.endswith("eb")3.62M
)
625
328
    A = A.substr(0, A.size() - 2);
626
3.63M
  // Trim the head
627
3.63M
  if (offset != StringRef::npos)
628
2.20M
    A = A.substr(offset);
629
3.63M
630
3.63M
  // Empty string means offset reached the end, which means it's valid.
631
3.63M
  if (A.empty())
632
2.01M
    return Arch;
633
1.62M
634
1.62M
  // Only match non-marketing names
635
1.62M
  
if (1.62M
offset != StringRef::npos1.62M
) {
636
250k
    // Must start with 'vN'.
637
250k
    if (
A[0] != 'v' || 250k
!std::isdigit(A[1])250k
)
638
72
      return Error;
639
250k
    // Can't have an extra 'eb'.
640
250k
    
if (250k
A.find("eb") != StringRef::npos250k
)
641
3
      return Error;
642
1.62M
  }
643
1.62M
644
1.62M
  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
645
1.62M
  return A;
646
1.62M
}
647
648
29
unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
649
29
  StringRef Syn = getHWDivSynonym(HWDiv);
650
102
  for (const auto D : HWDivNames) {
651
102
    if (Syn == D.getName())
652
28
      return D.ID;
653
1
  }
654
1
  return ARM::AEK_INVALID;
655
1
}
656
657
147
unsigned llvm::ARM::parseFPU(StringRef FPU) {
658
147
  StringRef Syn = getFPUSynonym(FPU);
659
1.83k
  for (const auto F : FPUNames) {
660
1.83k
    if (Syn == F.getName())
661
146
      return F.ID;
662
1
  }
663
1
  return ARM::FK_INVALID;
664
1
}
665
666
// Allows partial match, ex. "v7a" matches "armv7a".
667
1.78M
ARM::ArchKind ARM::parseArch(StringRef Arch) {
668
1.78M
  Arch = getCanonicalArchName(Arch);
669
1.78M
  StringRef Syn = getArchSynonym(Arch);
670
42.1M
  for (const auto A : ARCHNames) {
671
42.1M
    if (A.getName().endswith(Syn))
672
1.33M
      return A.ID;
673
445k
  }
674
445k
  return ARM::ArchKind::INVALID;
675
445k
}
676
677
125
unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
678
1.07k
  for (const auto A : ARCHExtNames) {
679
1.07k
    if (ArchExt == A.getName())
680
115
      return A.ID;
681
10
  }
682
10
  return ARM::AEK_INVALID;
683
10
}
684
685
11.3k
ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
686
666k
  for (const auto C : CPUNames) {
687
666k
    if (CPU == C.getName())
688
10.1k
      return C.ArchID;
689
1.15k
  }
690
1.15k
  return ARM::ArchKind::INVALID;
691
1.15k
}
692
693
// ARM, Thumb, AArch64
694
98.2k
ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
695
98.2k
  return StringSwitch<ARM::ISAKind>(Arch)
696
98.2k
      .StartsWith("aarch64", ARM::ISAKind::AARCH64)
697
98.2k
      .StartsWith("arm64", ARM::ISAKind::AARCH64)
698
98.2k
      .StartsWith("thumb", ARM::ISAKind::THUMB)
699
98.2k
      .StartsWith("arm", ARM::ISAKind::ARM)
700
98.2k
      .Default(ARM::ISAKind::INVALID);
701
98.2k
}
702
703
// Little/Big endian
704
95.0k
ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
705
95.0k
  if (
Arch.startswith("armeb") || 95.0k
Arch.startswith("thumbeb")94.5k
||
706
94.1k
      Arch.startswith("aarch64_be"))
707
876
    return ARM::EndianKind::BIG;
708
94.1k
709
94.1k
  
if (94.1k
Arch.startswith("arm") || 94.1k
Arch.startswith("thumb")67.2k
) {
710
94.1k
    if (Arch.endswith("eb"))
711
212
      return ARM::EndianKind::BIG;
712
94.1k
    else
713
93.9k
      return ARM::EndianKind::LITTLE;
714
5
  }
715
5
716
5
  
if (5
Arch.startswith("aarch64")5
)
717
5
    return ARM::EndianKind::LITTLE;
718
0
719
0
  return ARM::EndianKind::INVALID;
720
0
}
721
722
// Profile A/R/M
723
111k
ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
724
111k
  Arch = getCanonicalArchName(Arch);
725
111k
  switch (parseArch(Arch)) {
726
20.7k
  case ARM::ArchKind::ARMV6M:
727
20.7k
  case ARM::ArchKind::ARMV7M:
728
20.7k
  case ARM::ArchKind::ARMV7EM:
729
20.7k
  case ARM::ArchKind::ARMV8MMainline:
730
20.7k
  case ARM::ArchKind::ARMV8MBaseline:
731
20.7k
    return ARM::ProfileKind::M;
732
629
  case ARM::ArchKind::ARMV7R:
733
629
  case ARM::ArchKind::ARMV8R:
734
629
    return ARM::ProfileKind::R;
735
71.2k
  case ARM::ArchKind::ARMV7A:
736
71.2k
  case ARM::ArchKind::ARMV7VE:
737
71.2k
  case ARM::ArchKind::ARMV7K:
738
71.2k
  case ARM::ArchKind::ARMV8A:
739
71.2k
  case ARM::ArchKind::ARMV8_1A:
740
71.2k
  case ARM::ArchKind::ARMV8_2A:
741
71.2k
  case ARM::ArchKind::ARMV8_3A:
742
71.2k
    return ARM::ProfileKind::A;
743
0
    
LLVM_FALLTHROUGH0
;
744
18.7k
  case ARM::ArchKind::ARMV2:
745
18.7k
  case ARM::ArchKind::ARMV2A:
746
18.7k
  case ARM::ArchKind::ARMV3:
747
18.7k
  case ARM::ArchKind::ARMV3M:
748
18.7k
  case ARM::ArchKind::ARMV4:
749
18.7k
  case ARM::ArchKind::ARMV4T:
750
18.7k
  case ARM::ArchKind::ARMV5T:
751
18.7k
  case ARM::ArchKind::ARMV5TE:
752
18.7k
  case ARM::ArchKind::ARMV5TEJ:
753
18.7k
  case ARM::ArchKind::ARMV6:
754
18.7k
  case ARM::ArchKind::ARMV6K:
755
18.7k
  case ARM::ArchKind::ARMV6T2:
756
18.7k
  case ARM::ArchKind::ARMV6KZ:
757
18.7k
  case ARM::ArchKind::ARMV7S:
758
18.7k
  case ARM::ArchKind::IWMMXT:
759
18.7k
  case ARM::ArchKind::IWMMXT2:
760
18.7k
  case ARM::ArchKind::XSCALE:
761
18.7k
  case ARM::ArchKind::INVALID:
762
18.7k
    return ARM::ProfileKind::INVALID;
763
0
  }
764
0
  
llvm_unreachable0
("Unhandled architecture");
765
0
}
766
767
// Version number (ex. v7 = 7).
768
118k
unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
769
118k
  Arch = getCanonicalArchName(Arch);
770
118k
  switch (parseArch(Arch)) {
771
2
  case ARM::ArchKind::ARMV2:
772
2
  case ARM::ArchKind::ARMV2A:
773
2
    return 2;
774
2
  case ARM::ArchKind::ARMV3:
775
2
  case ARM::ArchKind::ARMV3M:
776
2
    return 3;
777
3.56k
  case ARM::ArchKind::ARMV4:
778
3.56k
  case ARM::ArchKind::ARMV4T:
779
3.56k
    return 4;
780
1.13k
  case ARM::ArchKind::ARMV5T:
781
1.13k
  case ARM::ArchKind::ARMV5TE:
782
1.13k
  case ARM::ArchKind::IWMMXT:
783
1.13k
  case ARM::ArchKind::IWMMXT2:
784
1.13k
  case ARM::ArchKind::XSCALE:
785
1.13k
  case ARM::ArchKind::ARMV5TEJ:
786
1.13k
    return 5;
787
8.46k
  case ARM::ArchKind::ARMV6:
788
8.46k
  case ARM::ArchKind::ARMV6K:
789
8.46k
  case ARM::ArchKind::ARMV6T2:
790
8.46k
  case ARM::ArchKind::ARMV6KZ:
791
8.46k
  case ARM::ArchKind::ARMV6M:
792
8.46k
    return 6;
793
99.5k
  case ARM::ArchKind::ARMV7A:
794
99.5k
  case ARM::ArchKind::ARMV7VE:
795
99.5k
  case ARM::ArchKind::ARMV7R:
796
99.5k
  case ARM::ArchKind::ARMV7M:
797
99.5k
  case ARM::ArchKind::ARMV7S:
798
99.5k
  case ARM::ArchKind::ARMV7EM:
799
99.5k
  case ARM::ArchKind::ARMV7K:
800
99.5k
    return 7;
801
6.21k
  case ARM::ArchKind::ARMV8A:
802
6.21k
  case ARM::ArchKind::ARMV8_1A:
803
6.21k
  case ARM::ArchKind::ARMV8_2A:
804
6.21k
  case ARM::ArchKind::ARMV8_3A:
805
6.21k
  case ARM::ArchKind::ARMV8R:
806
6.21k
  case ARM::ArchKind::ARMV8MBaseline:
807
6.21k
  case ARM::ArchKind::ARMV8MMainline:
808
6.21k
    return 8;
809
42
  case ARM::ArchKind::INVALID:
810
42
    return 0;
811
0
  }
812
0
  
llvm_unreachable0
("Unhandled architecture");
813
0
}
814
815
9.60k
StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
816
9.60k
  StringRef ArchName =
817
9.60k
      CPU.empty() ? 
TT.getArchName()4.39k
:
ARM::getArchName(ARM::parseCPUArch(CPU))5.20k
;
818
9.60k
819
9.60k
  if (
TT.isOSBinFormatMachO()9.60k
) {
820
4.36k
    if (TT.getEnvironment() == Triple::EABI ||
821
3.91k
        TT.getOS() == Triple::UnknownOS ||
822
3.03k
        llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
823
1.37k
      return "aapcs";
824
2.98k
    
if (2.98k
TT.isWatchABI()2.98k
)
825
629
      return "aapcs16";
826
2.35k
    return "apcs-gnu";
827
5.24k
  } else 
if (5.24k
TT.isOSWindows()5.24k
)
828
5.24k
    // FIXME: this is invalid for WindowsCE.
829
279
    return "aapcs";
830
4.96k
831
4.96k
  // Select the default based on the platform.
832
4.96k
  switch (TT.getEnvironment()) {
833
1.82k
  case Triple::Android:
834
1.82k
  case Triple::GNUEABI:
835
1.82k
  case Triple::GNUEABIHF:
836
1.82k
  case Triple::MuslEABI:
837
1.82k
  case Triple::MuslEABIHF:
838
1.82k
    return "aapcs-linux";
839
1.98k
  case Triple::EABIHF:
840
1.98k
  case Triple::EABI:
841
1.98k
    return "aapcs";
842
1.15k
  default:
843
1.15k
    if (TT.isOSNetBSD())
844
2
      return "apcs-gnu";
845
1.15k
    
if (1.15k
TT.isOSOpenBSD()1.15k
)
846
5
      return "aapcs-linux";
847
1.14k
    return "aapcs";
848
9.60k
  }
849
9.60k
}
850
851
93
StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
852
93
  return ARM::getCanonicalArchName(Arch);
853
93
}
854
855
0
unsigned llvm::AArch64::parseFPU(StringRef FPU) {
856
0
  return ARM::parseFPU(FPU);
857
0
}
858
859
// Allows partial match, ex. "v8a" matches "armv8a".
860
93
AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
861
93
  Arch = getCanonicalArchName(Arch);
862
93
  if (checkArchVersion(Arch) < 8)
863
3
    return ArchKind::INVALID;
864
90
865
90
  StringRef Syn = getArchSynonym(Arch);
866
262
  for (const auto A : AArch64ARCHNames) {
867
262
    if (A.getName().endswith(Syn))
868
90
      return A.ID;
869
0
  }
870
0
  return ArchKind::INVALID;
871
0
}
872
873
26
unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
874
254
  for (const auto A : AArch64ARCHExtNames) {
875
254
    if (ArchExt == A.getName())
876
24
      return A.ID;
877
2
  }
878
2
  return AArch64::AEK_INVALID;
879
2
}
880
881
40.6k
AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
882
324k
  for (const auto C : AArch64CPUNames) {
883
324k
    if (CPU == C.getName())
884
40.6k
      return C.ArchID;
885
3
  }
886
3
  return ArchKind::INVALID;
887
3
}
888
889
// ARM, Thumb, AArch64
890
0
ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
891
0
  return ARM::parseArchISA(Arch);
892
0
}
893
894
// Little/Big endian
895
0
ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
896
0
  return ARM::parseArchEndian(Arch);
897
0
}
898
899
// Profile A/R/M
900
0
ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
901
0
  return ARM::parseArchProfile(Arch);
902
0
}
903
904
// Version number (ex. v8 = 8).
905
0
unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
906
0
  return ARM::parseArchVersion(Arch);
907
0
}