Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/TargetParser/ARMTargetParser.cpp
35233 views
1
//===-- ARMTargetParser - Parser for ARM target features --------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements a target parser to recognise ARM hardware features
10
// such as FPU/CPU/ARCH/extensions and specific support such as HWDIV.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/TargetParser/ARMTargetParser.h"
15
#include "llvm/ADT/StringSwitch.h"
16
#include "llvm/Support/Format.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include "llvm/TargetParser/ARMTargetParserCommon.h"
19
#include "llvm/TargetParser/Triple.h"
20
#include <cctype>
21
22
using namespace llvm;
23
24
static StringRef getHWDivSynonym(StringRef HWDiv) {
25
return StringSwitch<StringRef>(HWDiv)
26
.Case("thumb,arm", "arm,thumb")
27
.Default(HWDiv);
28
}
29
30
// Allows partial match, ex. "v7a" matches "armv7a".
31
ARM::ArchKind ARM::parseArch(StringRef Arch) {
32
Arch = getCanonicalArchName(Arch);
33
StringRef Syn = getArchSynonym(Arch);
34
for (const auto &A : ARMArchNames) {
35
if (A.Name.ends_with(Syn))
36
return A.ID;
37
}
38
return ArchKind::INVALID;
39
}
40
41
// Version number (ex. v7 = 7).
42
unsigned ARM::parseArchVersion(StringRef Arch) {
43
Arch = getCanonicalArchName(Arch);
44
switch (parseArch(Arch)) {
45
case ArchKind::ARMV4:
46
case ArchKind::ARMV4T:
47
return 4;
48
case ArchKind::ARMV5T:
49
case ArchKind::ARMV5TE:
50
case ArchKind::IWMMXT:
51
case ArchKind::IWMMXT2:
52
case ArchKind::XSCALE:
53
case ArchKind::ARMV5TEJ:
54
return 5;
55
case ArchKind::ARMV6:
56
case ArchKind::ARMV6K:
57
case ArchKind::ARMV6T2:
58
case ArchKind::ARMV6KZ:
59
case ArchKind::ARMV6M:
60
return 6;
61
case ArchKind::ARMV7A:
62
case ArchKind::ARMV7VE:
63
case ArchKind::ARMV7R:
64
case ArchKind::ARMV7M:
65
case ArchKind::ARMV7S:
66
case ArchKind::ARMV7EM:
67
case ArchKind::ARMV7K:
68
return 7;
69
case ArchKind::ARMV8A:
70
case ArchKind::ARMV8_1A:
71
case ArchKind::ARMV8_2A:
72
case ArchKind::ARMV8_3A:
73
case ArchKind::ARMV8_4A:
74
case ArchKind::ARMV8_5A:
75
case ArchKind::ARMV8_6A:
76
case ArchKind::ARMV8_7A:
77
case ArchKind::ARMV8_8A:
78
case ArchKind::ARMV8_9A:
79
case ArchKind::ARMV8R:
80
case ArchKind::ARMV8MBaseline:
81
case ArchKind::ARMV8MMainline:
82
case ArchKind::ARMV8_1MMainline:
83
return 8;
84
case ArchKind::ARMV9A:
85
case ArchKind::ARMV9_1A:
86
case ArchKind::ARMV9_2A:
87
case ArchKind::ARMV9_3A:
88
case ArchKind::ARMV9_4A:
89
case ArchKind::ARMV9_5A:
90
return 9;
91
case ArchKind::INVALID:
92
return 0;
93
}
94
llvm_unreachable("Unhandled architecture");
95
}
96
97
static ARM::ProfileKind getProfileKind(ARM::ArchKind AK) {
98
switch (AK) {
99
case ARM::ArchKind::ARMV6M:
100
case ARM::ArchKind::ARMV7M:
101
case ARM::ArchKind::ARMV7EM:
102
case ARM::ArchKind::ARMV8MMainline:
103
case ARM::ArchKind::ARMV8MBaseline:
104
case ARM::ArchKind::ARMV8_1MMainline:
105
return ARM::ProfileKind::M;
106
case ARM::ArchKind::ARMV7R:
107
case ARM::ArchKind::ARMV8R:
108
return ARM::ProfileKind::R;
109
case ARM::ArchKind::ARMV7A:
110
case ARM::ArchKind::ARMV7VE:
111
case ARM::ArchKind::ARMV7K:
112
case ARM::ArchKind::ARMV8A:
113
case ARM::ArchKind::ARMV8_1A:
114
case ARM::ArchKind::ARMV8_2A:
115
case ARM::ArchKind::ARMV8_3A:
116
case ARM::ArchKind::ARMV8_4A:
117
case ARM::ArchKind::ARMV8_5A:
118
case ARM::ArchKind::ARMV8_6A:
119
case ARM::ArchKind::ARMV8_7A:
120
case ARM::ArchKind::ARMV8_8A:
121
case ARM::ArchKind::ARMV8_9A:
122
case ARM::ArchKind::ARMV9A:
123
case ARM::ArchKind::ARMV9_1A:
124
case ARM::ArchKind::ARMV9_2A:
125
case ARM::ArchKind::ARMV9_3A:
126
case ARM::ArchKind::ARMV9_4A:
127
case ARM::ArchKind::ARMV9_5A:
128
return ARM::ProfileKind::A;
129
case ARM::ArchKind::ARMV4:
130
case ARM::ArchKind::ARMV4T:
131
case ARM::ArchKind::ARMV5T:
132
case ARM::ArchKind::ARMV5TE:
133
case ARM::ArchKind::ARMV5TEJ:
134
case ARM::ArchKind::ARMV6:
135
case ARM::ArchKind::ARMV6K:
136
case ARM::ArchKind::ARMV6T2:
137
case ARM::ArchKind::ARMV6KZ:
138
case ARM::ArchKind::ARMV7S:
139
case ARM::ArchKind::IWMMXT:
140
case ARM::ArchKind::IWMMXT2:
141
case ARM::ArchKind::XSCALE:
142
case ARM::ArchKind::INVALID:
143
return ARM::ProfileKind::INVALID;
144
}
145
llvm_unreachable("Unhandled architecture");
146
}
147
148
// Profile A/R/M
149
ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
150
Arch = getCanonicalArchName(Arch);
151
return getProfileKind(parseArch(Arch));
152
}
153
154
bool ARM::getFPUFeatures(ARM::FPUKind FPUKind,
155
std::vector<StringRef> &Features) {
156
157
if (FPUKind >= FK_LAST || FPUKind == FK_INVALID)
158
return false;
159
160
static const struct FPUFeatureNameInfo {
161
const char *PlusName, *MinusName;
162
FPUVersion MinVersion;
163
FPURestriction MaxRestriction;
164
} FPUFeatureInfoList[] = {
165
// We have to specify the + and - versions of the name in full so
166
// that we can return them as static StringRefs.
167
//
168
// Also, the SubtargetFeatures ending in just "sp" are listed here
169
// under FPURestriction::None, which is the only FPURestriction in
170
// which they would be valid (since FPURestriction::SP doesn't
171
// exist).
172
{"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16},
173
{"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16},
174
{"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None},
175
{"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16},
176
{"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16},
177
{"+vfp3sp", "-vfp3sp", FPUVersion::VFPV3, FPURestriction::None},
178
{"+fp16", "-fp16", FPUVersion::VFPV3_FP16, FPURestriction::SP_D16},
179
{"+vfp4", "-vfp4", FPUVersion::VFPV4, FPURestriction::None},
180
{"+vfp4d16", "-vfp4d16", FPUVersion::VFPV4, FPURestriction::D16},
181
{"+vfp4d16sp", "-vfp4d16sp", FPUVersion::VFPV4, FPURestriction::SP_D16},
182
{"+vfp4sp", "-vfp4sp", FPUVersion::VFPV4, FPURestriction::None},
183
{"+fp-armv8", "-fp-armv8", FPUVersion::VFPV5, FPURestriction::None},
184
{"+fp-armv8d16", "-fp-armv8d16", FPUVersion::VFPV5, FPURestriction::D16},
185
{"+fp-armv8d16sp", "-fp-armv8d16sp", FPUVersion::VFPV5, FPURestriction::SP_D16},
186
{"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None},
187
{"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16},
188
{"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16},
189
{"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None},
190
};
191
192
for (const auto &Info: FPUFeatureInfoList) {
193
if (FPUNames[FPUKind].FPUVer >= Info.MinVersion &&
194
FPUNames[FPUKind].Restriction <= Info.MaxRestriction)
195
Features.push_back(Info.PlusName);
196
else
197
Features.push_back(Info.MinusName);
198
}
199
200
static const struct NeonFeatureNameInfo {
201
const char *PlusName, *MinusName;
202
NeonSupportLevel MinSupportLevel;
203
} NeonFeatureInfoList[] = {
204
{"+neon", "-neon", NeonSupportLevel::Neon},
205
{"+sha2", "-sha2", NeonSupportLevel::Crypto},
206
{"+aes", "-aes", NeonSupportLevel::Crypto},
207
};
208
209
for (const auto &Info: NeonFeatureInfoList) {
210
if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)
211
Features.push_back(Info.PlusName);
212
else
213
Features.push_back(Info.MinusName);
214
}
215
216
return true;
217
}
218
219
ARM::FPUKind ARM::parseFPU(StringRef FPU) {
220
StringRef Syn = getFPUSynonym(FPU);
221
for (const auto &F : FPUNames) {
222
if (Syn == F.Name)
223
return F.ID;
224
}
225
return FK_INVALID;
226
}
227
228
ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(ARM::FPUKind FPUKind) {
229
if (FPUKind >= FK_LAST)
230
return NeonSupportLevel::None;
231
return FPUNames[FPUKind].NeonSupport;
232
}
233
234
StringRef ARM::getFPUSynonym(StringRef FPU) {
235
return StringSwitch<StringRef>(FPU)
236
.Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
237
.Case("vfp2", "vfpv2")
238
.Case("vfp3", "vfpv3")
239
.Case("vfp4", "vfpv4")
240
.Case("vfp3-d16", "vfpv3-d16")
241
.Case("vfp4-d16", "vfpv4-d16")
242
.Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
243
.Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
244
.Case("fp5-sp-d16", "fpv5-sp-d16")
245
.Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
246
// FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
247
.Case("neon-vfpv3", "neon")
248
.Default(FPU);
249
}
250
251
StringRef ARM::getFPUName(ARM::FPUKind FPUKind) {
252
if (FPUKind >= FK_LAST)
253
return StringRef();
254
return FPUNames[FPUKind].Name;
255
}
256
257
ARM::FPUVersion ARM::getFPUVersion(ARM::FPUKind FPUKind) {
258
if (FPUKind >= FK_LAST)
259
return FPUVersion::NONE;
260
return FPUNames[FPUKind].FPUVer;
261
}
262
263
ARM::FPURestriction ARM::getFPURestriction(ARM::FPUKind FPUKind) {
264
if (FPUKind >= FK_LAST)
265
return FPURestriction::None;
266
return FPUNames[FPUKind].Restriction;
267
}
268
269
ARM::FPUKind ARM::getDefaultFPU(StringRef CPU, ARM::ArchKind AK) {
270
if (CPU == "generic")
271
return ARM::ARMArchNames[static_cast<unsigned>(AK)].DefaultFPU;
272
273
return StringSwitch<ARM::FPUKind>(CPU)
274
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
275
.Case(NAME, DEFAULT_FPU)
276
#include "llvm/TargetParser/ARMTargetParser.def"
277
.Default(ARM::FK_INVALID);
278
}
279
280
uint64_t ARM::getDefaultExtensions(StringRef CPU, ARM::ArchKind AK) {
281
if (CPU == "generic")
282
return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
283
284
return StringSwitch<uint64_t>(CPU)
285
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
286
.Case(NAME, \
287
ARMArchNames[static_cast<unsigned>(ArchKind::ID)].ArchBaseExtensions | \
288
DEFAULT_EXT)
289
#include "llvm/TargetParser/ARMTargetParser.def"
290
.Default(ARM::AEK_INVALID);
291
}
292
293
bool ARM::getHWDivFeatures(uint64_t HWDivKind,
294
std::vector<StringRef> &Features) {
295
296
if (HWDivKind == AEK_INVALID)
297
return false;
298
299
if (HWDivKind & AEK_HWDIVARM)
300
Features.push_back("+hwdiv-arm");
301
else
302
Features.push_back("-hwdiv-arm");
303
304
if (HWDivKind & AEK_HWDIVTHUMB)
305
Features.push_back("+hwdiv");
306
else
307
Features.push_back("-hwdiv");
308
309
return true;
310
}
311
312
bool ARM::getExtensionFeatures(uint64_t Extensions,
313
std::vector<StringRef> &Features) {
314
315
if (Extensions == AEK_INVALID)
316
return false;
317
318
for (const auto &AE : ARCHExtNames) {
319
if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())
320
Features.push_back(AE.Feature);
321
else if (!AE.NegFeature.empty())
322
Features.push_back(AE.NegFeature);
323
}
324
325
return getHWDivFeatures(Extensions, Features);
326
}
327
328
StringRef ARM::getArchName(ARM::ArchKind AK) {
329
return ARMArchNames[static_cast<unsigned>(AK)].Name;
330
}
331
332
StringRef ARM::getCPUAttr(ARM::ArchKind AK) {
333
return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;
334
}
335
336
StringRef ARM::getSubArch(ARM::ArchKind AK) {
337
return ARMArchNames[static_cast<unsigned>(AK)].getSubArch();
338
}
339
340
unsigned ARM::getArchAttr(ARM::ArchKind AK) {
341
return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;
342
}
343
344
StringRef ARM::getArchExtName(uint64_t ArchExtKind) {
345
for (const auto &AE : ARCHExtNames) {
346
if (ArchExtKind == AE.ID)
347
return AE.Name;
348
}
349
return StringRef();
350
}
351
352
static bool stripNegationPrefix(StringRef &Name) {
353
return Name.consume_front("no");
354
}
355
356
StringRef ARM::getArchExtFeature(StringRef ArchExt) {
357
bool Negated = stripNegationPrefix(ArchExt);
358
for (const auto &AE : ARCHExtNames) {
359
if (!AE.Feature.empty() && ArchExt == AE.Name)
360
return StringRef(Negated ? AE.NegFeature : AE.Feature);
361
}
362
363
return StringRef();
364
}
365
366
static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) {
367
if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
368
return ARM::FK_INVALID;
369
370
const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
371
372
// If the input FPU already supports double-precision, then there
373
// isn't any different FPU we can return here.
374
if (ARM::isDoublePrecision(InputFPU.Restriction))
375
return InputFPUKind;
376
377
// Otherwise, look for an FPU entry with all the same fields, except
378
// that it supports double precision.
379
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
380
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
381
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
382
ARM::has32Regs(CandidateFPU.Restriction) ==
383
ARM::has32Regs(InputFPU.Restriction) &&
384
ARM::isDoublePrecision(CandidateFPU.Restriction)) {
385
return CandidateFPU.ID;
386
}
387
}
388
389
// nothing found
390
return ARM::FK_INVALID;
391
}
392
393
static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) {
394
if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
395
return ARM::FK_INVALID;
396
397
const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind];
398
399
// If the input FPU already is single-precision only, then there
400
// isn't any different FPU we can return here.
401
if (!ARM::isDoublePrecision(InputFPU.Restriction))
402
return InputFPUKind;
403
404
// Otherwise, look for an FPU entry with all the same fields, except
405
// that it does not support double precision.
406
for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) {
407
if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
408
CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
409
ARM::has32Regs(CandidateFPU.Restriction) ==
410
ARM::has32Regs(InputFPU.Restriction) &&
411
!ARM::isDoublePrecision(CandidateFPU.Restriction)) {
412
return CandidateFPU.ID;
413
}
414
}
415
416
// nothing found
417
return ARM::FK_INVALID;
418
}
419
420
bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK,
421
StringRef ArchExt,
422
std::vector<StringRef> &Features,
423
ARM::FPUKind &ArgFPUKind) {
424
425
size_t StartingNumFeatures = Features.size();
426
const bool Negated = stripNegationPrefix(ArchExt);
427
uint64_t ID = parseArchExt(ArchExt);
428
429
if (ID == AEK_INVALID)
430
return false;
431
432
for (const auto &AE : ARCHExtNames) {
433
if (Negated) {
434
if ((AE.ID & ID) == ID && !AE.NegFeature.empty())
435
Features.push_back(AE.NegFeature);
436
} else {
437
if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())
438
Features.push_back(AE.Feature);
439
}
440
}
441
442
if (CPU == "")
443
CPU = "generic";
444
445
if (ArchExt == "fp" || ArchExt == "fp.dp") {
446
const ARM::FPUKind DefaultFPU = getDefaultFPU(CPU, AK);
447
ARM::FPUKind FPUKind;
448
if (ArchExt == "fp.dp") {
449
const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
450
ArgFPUKind != ARM::FK_NONE &&
451
isDoublePrecision(getFPURestriction(ArgFPUKind));
452
if (Negated) {
453
/* If there is no FPU selected yet, we still need to set ArgFPUKind, as
454
* leaving it as FK_INVALID, would cause default FPU to be selected
455
* later and that could be double precision one. */
456
if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
457
return true;
458
FPUKind = findSinglePrecisionFPU(DefaultFPU);
459
if (FPUKind == ARM::FK_INVALID)
460
FPUKind = ARM::FK_NONE;
461
} else {
462
if (IsDP)
463
return true;
464
FPUKind = findDoublePrecisionFPU(DefaultFPU);
465
if (FPUKind == ARM::FK_INVALID)
466
return false;
467
}
468
} else if (Negated) {
469
FPUKind = ARM::FK_NONE;
470
} else {
471
FPUKind = DefaultFPU;
472
}
473
ArgFPUKind = FPUKind;
474
return true;
475
}
476
return StartingNumFeatures != Features.size();
477
}
478
479
ARM::ArchKind ARM::convertV9toV8(ARM::ArchKind AK) {
480
if (getProfileKind(AK) != ProfileKind::A)
481
return ARM::ArchKind::INVALID;
482
if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A)
483
return ARM::ArchKind::INVALID;
484
unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A);
485
AK_v8 += static_cast<unsigned>(AK) -
486
static_cast<unsigned>(ARM::ArchKind::ARMV9A);
487
return static_cast<ARM::ArchKind>(AK_v8);
488
}
489
490
StringRef ARM::getDefaultCPU(StringRef Arch) {
491
ArchKind AK = parseArch(Arch);
492
if (AK == ArchKind::INVALID)
493
return StringRef();
494
495
// Look for multiple AKs to find the default for pair AK+Name.
496
for (const auto &CPU : CPUNames) {
497
if (CPU.ArchID == AK && CPU.Default)
498
return CPU.Name;
499
}
500
501
// If we can't find a default then target the architecture instead
502
return "generic";
503
}
504
505
uint64_t ARM::parseHWDiv(StringRef HWDiv) {
506
StringRef Syn = getHWDivSynonym(HWDiv);
507
for (const auto &D : HWDivNames) {
508
if (Syn == D.Name)
509
return D.ID;
510
}
511
return AEK_INVALID;
512
}
513
514
uint64_t ARM::parseArchExt(StringRef ArchExt) {
515
for (const auto &A : ARCHExtNames) {
516
if (ArchExt == A.Name)
517
return A.ID;
518
}
519
return AEK_INVALID;
520
}
521
522
ARM::ArchKind ARM::parseCPUArch(StringRef CPU) {
523
for (const auto &C : CPUNames) {
524
if (CPU == C.Name)
525
return C.ArchID;
526
}
527
return ArchKind::INVALID;
528
}
529
530
void ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
531
for (const auto &Arch : CPUNames) {
532
if (Arch.ArchID != ArchKind::INVALID)
533
Values.push_back(Arch.Name);
534
}
535
}
536
537
StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
538
StringRef ArchName =
539
CPU.empty() ? TT.getArchName() : getArchName(parseCPUArch(CPU));
540
541
if (TT.isOSBinFormatMachO()) {
542
if (TT.getEnvironment() == Triple::EABI ||
543
TT.getOS() == Triple::UnknownOS ||
544
parseArchProfile(ArchName) == ProfileKind::M)
545
return "aapcs";
546
if (TT.isWatchABI())
547
return "aapcs16";
548
return "apcs-gnu";
549
} else if (TT.isOSWindows())
550
// FIXME: this is invalid for WindowsCE.
551
return "aapcs";
552
553
// Select the default based on the platform.
554
switch (TT.getEnvironment()) {
555
case Triple::Android:
556
case Triple::GNUEABI:
557
case Triple::GNUEABIT64:
558
case Triple::GNUEABIHF:
559
case Triple::GNUEABIHFT64:
560
case Triple::MuslEABI:
561
case Triple::MuslEABIHF:
562
case Triple::OpenHOS:
563
return "aapcs-linux";
564
case Triple::EABIHF:
565
case Triple::EABI:
566
return "aapcs";
567
default:
568
if (TT.isOSNetBSD())
569
return "apcs-gnu";
570
if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() ||
571
TT.isOHOSFamily())
572
return "aapcs-linux";
573
return "aapcs";
574
}
575
}
576
577
StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) {
578
if (MArch.empty())
579
MArch = Triple.getArchName();
580
MArch = llvm::ARM::getCanonicalArchName(MArch);
581
582
// Some defaults are forced.
583
switch (Triple.getOS()) {
584
case llvm::Triple::FreeBSD:
585
case llvm::Triple::NetBSD:
586
case llvm::Triple::OpenBSD:
587
case llvm::Triple::Haiku:
588
if (!MArch.empty() && MArch == "v6")
589
return "arm1176jzf-s";
590
if (!MArch.empty() && MArch == "v7")
591
return "cortex-a8";
592
break;
593
case llvm::Triple::Win32:
594
// FIXME: this is invalid for WindowsCE
595
if (llvm::ARM::parseArchVersion(MArch) <= 7)
596
return "cortex-a9";
597
break;
598
case llvm::Triple::IOS:
599
case llvm::Triple::MacOSX:
600
case llvm::Triple::TvOS:
601
case llvm::Triple::WatchOS:
602
case llvm::Triple::DriverKit:
603
case llvm::Triple::XROS:
604
if (MArch == "v7k")
605
return "cortex-a7";
606
break;
607
default:
608
break;
609
}
610
611
if (MArch.empty())
612
return StringRef();
613
614
StringRef CPU = llvm::ARM::getDefaultCPU(MArch);
615
if (!CPU.empty() && CPU != "invalid")
616
return CPU;
617
618
// If no specific architecture version is requested, return the minimum CPU
619
// required by the OS and environment.
620
switch (Triple.getOS()) {
621
case llvm::Triple::Haiku:
622
return "arm1176jzf-s";
623
case llvm::Triple::NetBSD:
624
switch (Triple.getEnvironment()) {
625
case llvm::Triple::EABI:
626
case llvm::Triple::EABIHF:
627
case llvm::Triple::GNUEABI:
628
case llvm::Triple::GNUEABIHF:
629
return "arm926ej-s";
630
default:
631
return "strongarm";
632
}
633
case llvm::Triple::NaCl:
634
case llvm::Triple::OpenBSD:
635
return "cortex-a8";
636
default:
637
switch (Triple.getEnvironment()) {
638
case llvm::Triple::EABIHF:
639
case llvm::Triple::GNUEABIHF:
640
case llvm::Triple::GNUEABIHFT64:
641
case llvm::Triple::MuslEABIHF:
642
return "arm1176jzf-s";
643
default:
644
return "arm7tdmi";
645
}
646
}
647
648
llvm_unreachable("invalid arch name");
649
}
650
651
void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) {
652
outs() << "All available -march extensions for ARM\n\n"
653
<< " " << left_justify("Name", 20)
654
<< (DescMap.empty() ? "\n" : "Description\n");
655
for (const auto &Ext : ARCHExtNames) {
656
// Extensions without a feature cannot be used with -march.
657
if (!Ext.Feature.empty()) {
658
std::string Description = DescMap[Ext.Name].str();
659
outs() << " "
660
<< format(Description.empty() ? "%s\n" : "%-20s%s\n",
661
Ext.Name.str().c_str(), Description.c_str());
662
}
663
}
664
}
665
666