Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
35266 views
1
//===--- ARM.cpp - Implement ARM target feature support -------------------===//
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 ARM TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "ARM.h"
14
#include "clang/Basic/Builtins.h"
15
#include "clang/Basic/Diagnostic.h"
16
#include "clang/Basic/TargetBuiltins.h"
17
#include "llvm/ADT/StringExtras.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/ADT/StringSwitch.h"
20
#include "llvm/TargetParser/ARMTargetParser.h"
21
22
using namespace clang;
23
using namespace clang::targets;
24
25
void ARMTargetInfo::setABIAAPCS() {
26
IsAAPCS = true;
27
28
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
29
BFloat16Width = BFloat16Align = 16;
30
BFloat16Format = &llvm::APFloat::BFloat();
31
32
const llvm::Triple &T = getTriple();
33
34
bool IsNetBSD = T.isOSNetBSD();
35
bool IsOpenBSD = T.isOSOpenBSD();
36
if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
37
WCharType = UnsignedInt;
38
39
UseBitFieldTypeAlignment = true;
40
41
ZeroLengthBitfieldBoundary = 0;
42
43
// Thumb1 add sp, #imm requires the immediate value be multiple of 4,
44
// so set preferred for small types to 32.
45
if (T.isOSBinFormatMachO()) {
46
resetDataLayout(BigEndian
47
? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
48
: "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
49
"_");
50
} else if (T.isOSWindows()) {
51
assert(!BigEndian && "Windows on ARM does not support big endian");
52
resetDataLayout("e"
53
"-m:w"
54
"-p:32:32"
55
"-Fi8"
56
"-i64:64"
57
"-v128:64:128"
58
"-a:0:32"
59
"-n32"
60
"-S64");
61
} else if (T.isOSNaCl()) {
62
assert(!BigEndian && "NaCl on ARM does not support big endian");
63
resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
64
} else {
65
resetDataLayout(BigEndian
66
? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
67
: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
68
}
69
70
// FIXME: Enumerated types are variable width in straight AAPCS.
71
}
72
73
void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
74
const llvm::Triple &T = getTriple();
75
76
IsAAPCS = false;
77
78
if (IsAAPCS16)
79
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
80
else
81
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
82
BFloat16Width = BFloat16Align = 16;
83
BFloat16Format = &llvm::APFloat::BFloat();
84
85
WCharType = SignedInt;
86
87
// Do not respect the alignment of bit-field types when laying out
88
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
89
UseBitFieldTypeAlignment = false;
90
91
/// gcc forces the alignment to 4 bytes, regardless of the type of the
92
/// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
93
/// gcc.
94
ZeroLengthBitfieldBoundary = 32;
95
96
if (T.isOSBinFormatMachO() && IsAAPCS16) {
97
assert(!BigEndian && "AAPCS16 does not support big-endian");
98
resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
99
} else if (T.isOSBinFormatMachO())
100
resetDataLayout(
101
BigEndian
102
? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
103
: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
104
"_");
105
else
106
resetDataLayout(
107
BigEndian
108
? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
109
: "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
110
111
// FIXME: Override "preferred align" for double and long long.
112
}
113
114
void ARMTargetInfo::setArchInfo() {
115
StringRef ArchName = getTriple().getArchName();
116
117
ArchISA = llvm::ARM::parseArchISA(ArchName);
118
CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));
119
llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
120
if (AK != llvm::ARM::ArchKind::INVALID)
121
ArchKind = AK;
122
setArchInfo(ArchKind);
123
}
124
125
void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
126
StringRef SubArch;
127
128
// cache TargetParser info
129
ArchKind = Kind;
130
SubArch = llvm::ARM::getSubArch(ArchKind);
131
ArchProfile = llvm::ARM::parseArchProfile(SubArch);
132
ArchVersion = llvm::ARM::parseArchVersion(SubArch);
133
134
// cache CPU related strings
135
CPUAttr = getCPUAttr();
136
CPUProfile = getCPUProfile();
137
}
138
139
void ARMTargetInfo::setAtomic() {
140
// when triple does not specify a sub arch,
141
// then we are not using inline atomics
142
bool ShouldUseInlineAtomic =
143
(ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
144
(ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
145
// Cortex M does not support 8 byte atomics, while general Thumb2 does.
146
if (ArchProfile == llvm::ARM::ProfileKind::M) {
147
MaxAtomicPromoteWidth = 32;
148
if (ShouldUseInlineAtomic)
149
MaxAtomicInlineWidth = 32;
150
} else {
151
MaxAtomicPromoteWidth = 64;
152
if (ShouldUseInlineAtomic)
153
MaxAtomicInlineWidth = 64;
154
}
155
}
156
157
bool ARMTargetInfo::hasMVE() const {
158
return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
159
}
160
161
bool ARMTargetInfo::hasMVEFloat() const {
162
return hasMVE() && (MVE & MVE_FP);
163
}
164
165
bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
166
167
bool ARMTargetInfo::isThumb() const {
168
return ArchISA == llvm::ARM::ISAKind::THUMB;
169
}
170
171
bool ARMTargetInfo::supportsThumb() const {
172
return CPUAttr.count('T') || ArchVersion >= 6;
173
}
174
175
bool ARMTargetInfo::supportsThumb2() const {
176
return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE");
177
}
178
179
StringRef ARMTargetInfo::getCPUAttr() const {
180
// For most sub-arches, the build attribute CPU name is enough.
181
// For Cortex variants, it's slightly different.
182
switch (ArchKind) {
183
default:
184
return llvm::ARM::getCPUAttr(ArchKind);
185
case llvm::ARM::ArchKind::ARMV6M:
186
return "6M";
187
case llvm::ARM::ArchKind::ARMV7S:
188
return "7S";
189
case llvm::ARM::ArchKind::ARMV7A:
190
return "7A";
191
case llvm::ARM::ArchKind::ARMV7R:
192
return "7R";
193
case llvm::ARM::ArchKind::ARMV7M:
194
return "7M";
195
case llvm::ARM::ArchKind::ARMV7EM:
196
return "7EM";
197
case llvm::ARM::ArchKind::ARMV7VE:
198
return "7VE";
199
case llvm::ARM::ArchKind::ARMV8A:
200
return "8A";
201
case llvm::ARM::ArchKind::ARMV8_1A:
202
return "8_1A";
203
case llvm::ARM::ArchKind::ARMV8_2A:
204
return "8_2A";
205
case llvm::ARM::ArchKind::ARMV8_3A:
206
return "8_3A";
207
case llvm::ARM::ArchKind::ARMV8_4A:
208
return "8_4A";
209
case llvm::ARM::ArchKind::ARMV8_5A:
210
return "8_5A";
211
case llvm::ARM::ArchKind::ARMV8_6A:
212
return "8_6A";
213
case llvm::ARM::ArchKind::ARMV8_7A:
214
return "8_7A";
215
case llvm::ARM::ArchKind::ARMV8_8A:
216
return "8_8A";
217
case llvm::ARM::ArchKind::ARMV8_9A:
218
return "8_9A";
219
case llvm::ARM::ArchKind::ARMV9A:
220
return "9A";
221
case llvm::ARM::ArchKind::ARMV9_1A:
222
return "9_1A";
223
case llvm::ARM::ArchKind::ARMV9_2A:
224
return "9_2A";
225
case llvm::ARM::ArchKind::ARMV9_3A:
226
return "9_3A";
227
case llvm::ARM::ArchKind::ARMV9_4A:
228
return "9_4A";
229
case llvm::ARM::ArchKind::ARMV9_5A:
230
return "9_5A";
231
case llvm::ARM::ArchKind::ARMV8MBaseline:
232
return "8M_BASE";
233
case llvm::ARM::ArchKind::ARMV8MMainline:
234
return "8M_MAIN";
235
case llvm::ARM::ArchKind::ARMV8R:
236
return "8R";
237
case llvm::ARM::ArchKind::ARMV8_1MMainline:
238
return "8_1M_MAIN";
239
}
240
}
241
242
StringRef ARMTargetInfo::getCPUProfile() const {
243
switch (ArchProfile) {
244
case llvm::ARM::ProfileKind::A:
245
return "A";
246
case llvm::ARM::ProfileKind::R:
247
return "R";
248
case llvm::ARM::ProfileKind::M:
249
return "M";
250
default:
251
return "";
252
}
253
}
254
255
ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
256
const TargetOptions &Opts)
257
: TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
258
HW_FP(0) {
259
bool IsFreeBSD = Triple.isOSFreeBSD();
260
bool IsOpenBSD = Triple.isOSOpenBSD();
261
bool IsNetBSD = Triple.isOSNetBSD();
262
bool IsHaiku = Triple.isOSHaiku();
263
bool IsOHOS = Triple.isOHOSFamily();
264
265
// FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
266
// environment where size_t is `unsigned long` rather than `unsigned int`
267
268
PtrDiffType = IntPtrType =
269
(Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
270
IsNetBSD)
271
? SignedLong
272
: SignedInt;
273
274
SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
275
IsNetBSD)
276
? UnsignedLong
277
: UnsignedInt;
278
279
// ptrdiff_t is inconsistent on Darwin
280
if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
281
!Triple.isWatchABI())
282
PtrDiffType = SignedInt;
283
284
// Cache arch related info.
285
setArchInfo();
286
287
// {} in inline assembly are neon specifiers, not assembly variant
288
// specifiers.
289
NoAsmVariants = true;
290
291
// FIXME: This duplicates code from the driver that sets the -target-abi
292
// option - this code is used if -target-abi isn't passed and should
293
// be unified in some way.
294
if (Triple.isOSBinFormatMachO()) {
295
// The backend is hardwired to assume AAPCS for M-class processors, ensure
296
// the frontend matches that.
297
if (Triple.getEnvironment() == llvm::Triple::EABI ||
298
Triple.getOS() == llvm::Triple::UnknownOS ||
299
ArchProfile == llvm::ARM::ProfileKind::M) {
300
setABI("aapcs");
301
} else if (Triple.isWatchABI()) {
302
setABI("aapcs16");
303
} else {
304
setABI("apcs-gnu");
305
}
306
} else if (Triple.isOSWindows()) {
307
// FIXME: this is invalid for WindowsCE
308
setABI("aapcs");
309
} else {
310
// Select the default based on the platform.
311
switch (Triple.getEnvironment()) {
312
case llvm::Triple::Android:
313
case llvm::Triple::GNUEABI:
314
case llvm::Triple::GNUEABIT64:
315
case llvm::Triple::GNUEABIHF:
316
case llvm::Triple::GNUEABIHFT64:
317
case llvm::Triple::MuslEABI:
318
case llvm::Triple::MuslEABIHF:
319
case llvm::Triple::OpenHOS:
320
setABI("aapcs-linux");
321
break;
322
case llvm::Triple::EABIHF:
323
case llvm::Triple::EABI:
324
setABI("aapcs");
325
break;
326
case llvm::Triple::GNU:
327
setABI("apcs-gnu");
328
break;
329
default:
330
if (IsNetBSD)
331
setABI("apcs-gnu");
332
else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS)
333
setABI("aapcs-linux");
334
else
335
setABI("aapcs");
336
break;
337
}
338
}
339
340
// ARM targets default to using the ARM C++ ABI.
341
TheCXXABI.set(TargetCXXABI::GenericARM);
342
343
// ARM has atomics up to 8 bytes
344
setAtomic();
345
346
// Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
347
// as well the default alignment
348
if (IsAAPCS && !Triple.isAndroid())
349
DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
350
351
// Do force alignment of members that follow zero length bitfields. If
352
// the alignment of the zero-length bitfield is greater than the member
353
// that follows it, `bar', `bar' will be aligned as the type of the
354
// zero length bitfield.
355
UseZeroLengthBitfieldAlignment = true;
356
357
if (Triple.getOS() == llvm::Triple::Linux ||
358
Triple.getOS() == llvm::Triple::UnknownOS)
359
this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
360
? "llvm.arm.gnu.eabi.mcount"
361
: "\01mcount";
362
363
SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
364
}
365
366
StringRef ARMTargetInfo::getABI() const { return ABI; }
367
368
bool ARMTargetInfo::setABI(const std::string &Name) {
369
ABI = Name;
370
371
// The defaults (above) are for AAPCS, check if we need to change them.
372
//
373
// FIXME: We need support for -meabi... we could just mangle it into the
374
// name.
375
if (Name == "apcs-gnu" || Name == "aapcs16") {
376
setABIAPCS(Name == "aapcs16");
377
return true;
378
}
379
if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
380
setABIAAPCS();
381
return true;
382
}
383
return false;
384
}
385
386
bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
387
llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
388
if (CPUArch == llvm::ARM::ArchKind::INVALID)
389
CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
390
391
if (CPUArch == llvm::ARM::ArchKind::INVALID)
392
return false;
393
394
StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
395
auto a =
396
llvm::Triple(ArchFeature, getTriple().getVendorName(),
397
getTriple().getOSName(), getTriple().getEnvironmentName());
398
399
StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
400
llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
401
return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
402
}
403
404
bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
405
BranchProtectionInfo &BPI,
406
StringRef &Err) const {
407
llvm::ARM::ParsedBranchProtection PBP;
408
if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
409
return false;
410
411
if (!isBranchProtectionSupportedArch(Arch))
412
return false;
413
414
BPI.SignReturnAddr =
415
llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
416
.Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
417
.Case("all", LangOptions::SignReturnAddressScopeKind::All)
418
.Default(LangOptions::SignReturnAddressScopeKind::None);
419
420
// Don't care for the sign key, beyond issuing a warning.
421
if (PBP.Key == "b_key")
422
Err = "b-key";
423
BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
424
425
BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
426
BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
427
return true;
428
}
429
430
// FIXME: This should be based on Arch attributes, not CPU names.
431
bool ARMTargetInfo::initFeatureMap(
432
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
433
const std::vector<std::string> &FeaturesVec) const {
434
435
std::string ArchFeature;
436
std::vector<StringRef> TargetFeatures;
437
llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
438
439
// Map the base architecture to an appropriate target feature, so we don't
440
// rely on the target triple.
441
llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
442
if (CPUArch == llvm::ARM::ArchKind::INVALID)
443
CPUArch = Arch;
444
if (CPUArch != llvm::ARM::ArchKind::INVALID) {
445
ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
446
TargetFeatures.push_back(ArchFeature);
447
448
// These features are added to allow arm_neon.h target(..) attributes to
449
// match with both arm and aarch64. We need to add all previous architecture
450
// versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
451
// v8.x counterparts are added too. We only need these for anything > 8.0-A.
452
for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
453
I != llvm::ARM::ArchKind::INVALID; --I)
454
Features[llvm::ARM::getSubArch(I)] = true;
455
if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
456
CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
457
for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
458
--I)
459
Features[llvm::ARM::getSubArch(I)] = true;
460
}
461
462
// get default FPU features
463
llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
464
llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
465
466
// get default Extension features
467
uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
468
llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
469
470
for (auto Feature : TargetFeatures)
471
if (Feature[0] == '+')
472
Features[Feature.drop_front(1)] = true;
473
474
// Enable or disable thumb-mode explicitly per function to enable mixed
475
// ARM and Thumb code generation.
476
if (isThumb())
477
Features["thumb-mode"] = true;
478
else
479
Features["thumb-mode"] = false;
480
481
// Convert user-provided arm and thumb GNU target attributes to
482
// [-|+]thumb-mode target features respectively.
483
std::vector<std::string> UpdatedFeaturesVec;
484
for (const auto &Feature : FeaturesVec) {
485
// Skip soft-float-abi; it's something we only use to initialize a bit of
486
// class state, and is otherwise unrecognized.
487
if (Feature == "+soft-float-abi")
488
continue;
489
490
StringRef FixedFeature;
491
if (Feature == "+arm")
492
FixedFeature = "-thumb-mode";
493
else if (Feature == "+thumb")
494
FixedFeature = "+thumb-mode";
495
else
496
FixedFeature = Feature;
497
UpdatedFeaturesVec.push_back(FixedFeature.str());
498
}
499
500
return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
501
}
502
503
504
bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
505
DiagnosticsEngine &Diags) {
506
FPU = 0;
507
MVE = 0;
508
CRC = 0;
509
Crypto = 0;
510
SHA2 = 0;
511
AES = 0;
512
DSP = 0;
513
HasUnalignedAccess = true;
514
SoftFloat = false;
515
// Note that SoftFloatABI is initialized in our constructor.
516
HWDiv = 0;
517
DotProd = 0;
518
HasMatMul = 0;
519
HasPAC = 0;
520
HasBTI = 0;
521
HasFloat16 = true;
522
ARMCDECoprocMask = 0;
523
HasBFloat16 = false;
524
HasFullBFloat16 = false;
525
FPRegsDisabled = false;
526
527
// This does not diagnose illegal cases like having both
528
// "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
529
for (const auto &Feature : Features) {
530
if (Feature == "+soft-float") {
531
SoftFloat = true;
532
} else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
533
FPU |= VFP2FPU;
534
HW_FP |= HW_FP_SP;
535
if (Feature == "+vfp2")
536
HW_FP |= HW_FP_DP;
537
} else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
538
Feature == "+vfp3" || Feature == "+vfp3d16") {
539
FPU |= VFP3FPU;
540
HW_FP |= HW_FP_SP;
541
if (Feature == "+vfp3" || Feature == "+vfp3d16")
542
HW_FP |= HW_FP_DP;
543
} else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
544
Feature == "+vfp4" || Feature == "+vfp4d16") {
545
FPU |= VFP4FPU;
546
HW_FP |= HW_FP_SP | HW_FP_HP;
547
if (Feature == "+vfp4" || Feature == "+vfp4d16")
548
HW_FP |= HW_FP_DP;
549
} else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
550
Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
551
FPU |= FPARMV8;
552
HW_FP |= HW_FP_SP | HW_FP_HP;
553
if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
554
HW_FP |= HW_FP_DP;
555
} else if (Feature == "+neon") {
556
FPU |= NeonFPU;
557
HW_FP |= HW_FP_SP;
558
} else if (Feature == "+hwdiv") {
559
HWDiv |= HWDivThumb;
560
} else if (Feature == "+hwdiv-arm") {
561
HWDiv |= HWDivARM;
562
} else if (Feature == "+crc") {
563
CRC = 1;
564
} else if (Feature == "+crypto") {
565
Crypto = 1;
566
} else if (Feature == "+sha2") {
567
SHA2 = 1;
568
} else if (Feature == "+aes") {
569
AES = 1;
570
} else if (Feature == "+dsp") {
571
DSP = 1;
572
} else if (Feature == "+fp64") {
573
HW_FP |= HW_FP_DP;
574
} else if (Feature == "+8msecext") {
575
if (CPUProfile != "M" || ArchVersion != 8) {
576
Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
577
return false;
578
}
579
} else if (Feature == "+strict-align") {
580
HasUnalignedAccess = false;
581
} else if (Feature == "+fp16") {
582
HW_FP |= HW_FP_HP;
583
} else if (Feature == "+fullfp16") {
584
HasLegalHalfType = true;
585
} else if (Feature == "+dotprod") {
586
DotProd = true;
587
} else if (Feature == "+mve") {
588
MVE |= MVE_INT;
589
} else if (Feature == "+mve.fp") {
590
HasLegalHalfType = true;
591
FPU |= FPARMV8;
592
MVE |= MVE_INT | MVE_FP;
593
HW_FP |= HW_FP_SP | HW_FP_HP;
594
} else if (Feature == "+i8mm") {
595
HasMatMul = 1;
596
} else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
597
Feature <= "+cdecp7") {
598
unsigned Coproc = Feature.back() - '0';
599
ARMCDECoprocMask |= (1U << Coproc);
600
} else if (Feature == "+bf16") {
601
HasBFloat16 = true;
602
} else if (Feature == "-fpregs") {
603
FPRegsDisabled = true;
604
} else if (Feature == "+pacbti") {
605
HasPAC = 1;
606
HasBTI = 1;
607
} else if (Feature == "+fullbf16") {
608
HasFullBFloat16 = true;
609
}
610
}
611
612
HalfArgsAndReturns = true;
613
614
switch (ArchVersion) {
615
case 6:
616
if (ArchProfile == llvm::ARM::ProfileKind::M)
617
LDREX = 0;
618
else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
619
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
620
else
621
LDREX = LDREX_W;
622
break;
623
case 7:
624
if (ArchProfile == llvm::ARM::ProfileKind::M)
625
LDREX = LDREX_W | LDREX_H | LDREX_B;
626
else
627
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
628
break;
629
case 8:
630
case 9:
631
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
632
}
633
634
if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
635
Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
636
return false;
637
}
638
639
if (FPMath == FP_Neon)
640
Features.push_back("+neonfp");
641
else if (FPMath == FP_VFP)
642
Features.push_back("-neonfp");
643
644
return true;
645
}
646
647
bool ARMTargetInfo::hasFeature(StringRef Feature) const {
648
return llvm::StringSwitch<bool>(Feature)
649
.Case("arm", true)
650
.Case("aarch32", true)
651
.Case("softfloat", SoftFloat)
652
.Case("thumb", isThumb())
653
.Case("neon", (FPU & NeonFPU) && !SoftFloat)
654
.Case("vfp", FPU && !SoftFloat)
655
.Case("hwdiv", HWDiv & HWDivThumb)
656
.Case("hwdiv-arm", HWDiv & HWDivARM)
657
.Case("mve", hasMVE())
658
.Default(false);
659
}
660
661
bool ARMTargetInfo::hasBFloat16Type() const {
662
// The __bf16 type is generally available so long as we have any fp registers.
663
return HasBFloat16 || (FPU && !SoftFloat);
664
}
665
666
bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
667
return Name == "generic" ||
668
llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
669
}
670
671
void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
672
llvm::ARM::fillValidCPUArchList(Values);
673
}
674
675
bool ARMTargetInfo::setCPU(const std::string &Name) {
676
if (Name != "generic")
677
setArchInfo(llvm::ARM::parseCPUArch(Name));
678
679
if (ArchKind == llvm::ARM::ArchKind::INVALID)
680
return false;
681
setAtomic();
682
CPU = Name;
683
return true;
684
}
685
686
bool ARMTargetInfo::setFPMath(StringRef Name) {
687
if (Name == "neon") {
688
FPMath = FP_Neon;
689
return true;
690
} else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
691
Name == "vfp4") {
692
FPMath = FP_VFP;
693
return true;
694
}
695
return false;
696
}
697
698
void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
699
MacroBuilder &Builder) const {
700
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
701
}
702
703
void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
704
MacroBuilder &Builder) const {
705
// Also include the ARMv8.1-A defines
706
getTargetDefinesARMV81A(Opts, Builder);
707
}
708
709
void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
710
MacroBuilder &Builder) const {
711
// Also include the ARMv8.2-A defines
712
Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
713
getTargetDefinesARMV82A(Opts, Builder);
714
}
715
716
void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
717
MacroBuilder &Builder) const {
718
// Target identification.
719
Builder.defineMacro("__arm");
720
Builder.defineMacro("__arm__");
721
// For bare-metal none-eabi.
722
if (getTriple().getOS() == llvm::Triple::UnknownOS &&
723
(getTriple().getEnvironment() == llvm::Triple::EABI ||
724
getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
725
Opts.CPlusPlus) {
726
Builder.defineMacro("_GNU_SOURCE");
727
}
728
729
// Target properties.
730
Builder.defineMacro("__REGISTER_PREFIX__", "");
731
732
// Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
733
// happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
734
if (getTriple().isWatchABI())
735
Builder.defineMacro("__ARM_ARCH_7K__", "2");
736
737
if (!CPUAttr.empty())
738
Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
739
740
// ACLE 6.4.1 ARM/Thumb instruction set architecture
741
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA
742
Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
743
744
if (ArchVersion >= 8) {
745
// ACLE 6.5.7 Crypto Extension
746
// The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
747
// feature macros for AES and SHA2
748
if (SHA2 && AES)
749
Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
750
if (SHA2)
751
Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
752
if (AES)
753
Builder.defineMacro("__ARM_FEATURE_AES", "1");
754
// ACLE 6.5.8 CRC32 Extension
755
if (CRC)
756
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
757
// ACLE 6.5.10 Numeric Maximum and Minimum
758
Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
759
// ACLE 6.5.9 Directed Rounding
760
Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
761
}
762
763
// __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
764
// is not defined for the M-profile.
765
// NOTE that the default profile is assumed to be 'A'
766
if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
767
Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
768
769
// __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
770
// Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
771
// core supports the Thumb-2 ISA as found in the v6T2 architecture and all
772
// v7 and v8 architectures excluding v8-M Baseline.
773
if (supportsThumb2())
774
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
775
else if (supportsThumb())
776
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
777
778
// __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
779
// instruction set such as ARM or Thumb.
780
Builder.defineMacro("__ARM_32BIT_STATE", "1");
781
782
// ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
783
784
// __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
785
if (!CPUProfile.empty())
786
Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
787
788
// ACLE 6.4.3 Unaligned access supported in hardware
789
if (HasUnalignedAccess)
790
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
791
792
// ACLE 6.4.4 LDREX/STREX
793
if (LDREX)
794
Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
795
796
// ACLE 6.4.5 CLZ
797
if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
798
ArchVersion > 6)
799
Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
800
801
// ACLE 6.5.1 Hardware Floating Point
802
if (HW_FP)
803
Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
804
805
// ACLE predefines.
806
Builder.defineMacro("__ARM_ACLE", "200");
807
808
// FP16 support (we currently only support IEEE format).
809
Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
810
Builder.defineMacro("__ARM_FP16_ARGS", "1");
811
812
// ACLE 6.5.3 Fused multiply-accumulate (FMA)
813
if (ArchVersion >= 7 && (FPU & VFP4FPU))
814
Builder.defineMacro("__ARM_FEATURE_FMA", "1");
815
816
// Subtarget options.
817
818
// FIXME: It's more complicated than this and we don't really support
819
// interworking.
820
// Windows on ARM does not "support" interworking
821
if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
822
Builder.defineMacro("__THUMB_INTERWORK__");
823
824
if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
825
// Embedded targets on Darwin follow AAPCS, but not EABI.
826
// Windows on ARM follows AAPCS VFP, but does not conform to EABI.
827
if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
828
Builder.defineMacro("__ARM_EABI__");
829
Builder.defineMacro("__ARM_PCS", "1");
830
}
831
832
if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
833
Builder.defineMacro("__ARM_PCS_VFP", "1");
834
835
if (SoftFloat || (SoftFloatABI && !FPU))
836
Builder.defineMacro("__SOFTFP__");
837
838
// ACLE position independent code macros.
839
if (Opts.ROPI)
840
Builder.defineMacro("__ARM_ROPI", "1");
841
if (Opts.RWPI)
842
Builder.defineMacro("__ARM_RWPI", "1");
843
844
// Macros for enabling co-proc intrinsics
845
uint64_t FeatureCoprocBF = 0;
846
switch (ArchKind) {
847
default:
848
break;
849
case llvm::ARM::ArchKind::ARMV4:
850
case llvm::ARM::ArchKind::ARMV4T:
851
// Filter __arm_ldcl and __arm_stcl in acle.h
852
FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;
853
break;
854
case llvm::ARM::ArchKind::ARMV5T:
855
FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;
856
break;
857
case llvm::ARM::ArchKind::ARMV5TE:
858
case llvm::ARM::ArchKind::ARMV5TEJ:
859
if (!isThumb())
860
FeatureCoprocBF =
861
FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;
862
break;
863
case llvm::ARM::ArchKind::ARMV6:
864
case llvm::ARM::ArchKind::ARMV6K:
865
case llvm::ARM::ArchKind::ARMV6KZ:
866
case llvm::ARM::ArchKind::ARMV6T2:
867
if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)
868
FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
869
FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
870
break;
871
case llvm::ARM::ArchKind::ARMV7A:
872
case llvm::ARM::ArchKind::ARMV7R:
873
case llvm::ARM::ArchKind::ARMV7M:
874
case llvm::ARM::ArchKind::ARMV7S:
875
case llvm::ARM::ArchKind::ARMV7EM:
876
FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
877
FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
878
break;
879
case llvm::ARM::ArchKind::ARMV8A:
880
case llvm::ARM::ArchKind::ARMV8R:
881
case llvm::ARM::ArchKind::ARMV8_1A:
882
case llvm::ARM::ArchKind::ARMV8_2A:
883
case llvm::ARM::ArchKind::ARMV8_3A:
884
case llvm::ARM::ArchKind::ARMV8_4A:
885
case llvm::ARM::ArchKind::ARMV8_5A:
886
case llvm::ARM::ArchKind::ARMV8_6A:
887
case llvm::ARM::ArchKind::ARMV8_7A:
888
case llvm::ARM::ArchKind::ARMV8_8A:
889
case llvm::ARM::ArchKind::ARMV8_9A:
890
case llvm::ARM::ArchKind::ARMV9A:
891
case llvm::ARM::ArchKind::ARMV9_1A:
892
case llvm::ARM::ArchKind::ARMV9_2A:
893
case llvm::ARM::ArchKind::ARMV9_3A:
894
case llvm::ARM::ArchKind::ARMV9_4A:
895
case llvm::ARM::ArchKind::ARMV9_5A:
896
// Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
897
FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
898
break;
899
case llvm::ARM::ArchKind::ARMV8MMainline:
900
case llvm::ARM::ArchKind::ARMV8_1MMainline:
901
FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
902
FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
903
break;
904
}
905
Builder.defineMacro("__ARM_FEATURE_COPROC",
906
"0x" + Twine::utohexstr(FeatureCoprocBF));
907
908
if (ArchKind == llvm::ARM::ArchKind::XSCALE)
909
Builder.defineMacro("__XSCALE__");
910
911
if (isThumb()) {
912
Builder.defineMacro("__THUMBEL__");
913
Builder.defineMacro("__thumb__");
914
if (supportsThumb2())
915
Builder.defineMacro("__thumb2__");
916
}
917
918
// ACLE 6.4.9 32-bit SIMD instructions
919
if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
920
Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
921
922
// ACLE 6.4.10 Hardware Integer Divide
923
if (((HWDiv & HWDivThumb) && isThumb()) ||
924
((HWDiv & HWDivARM) && !isThumb())) {
925
Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
926
Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
927
}
928
929
// Note, this is always on in gcc, even though it doesn't make sense.
930
Builder.defineMacro("__APCS_32__");
931
932
// __VFP_FP__ means that the floating-point format is VFP, not that a hardware
933
// FPU is present. Moreover, the VFP format is the only one supported by
934
// clang. For these reasons, this macro is always defined.
935
Builder.defineMacro("__VFP_FP__");
936
937
if (FPUModeIsVFP((FPUMode)FPU)) {
938
if (FPU & VFP2FPU)
939
Builder.defineMacro("__ARM_VFPV2__");
940
if (FPU & VFP3FPU)
941
Builder.defineMacro("__ARM_VFPV3__");
942
if (FPU & VFP4FPU)
943
Builder.defineMacro("__ARM_VFPV4__");
944
if (FPU & FPARMV8)
945
Builder.defineMacro("__ARM_FPV5__");
946
}
947
948
// This only gets set when Neon instructions are actually available, unlike
949
// the VFP define, hence the soft float and arch check. This is subtly
950
// different from gcc, we follow the intent which was that it should be set
951
// when Neon instructions are actually available.
952
if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
953
Builder.defineMacro("__ARM_NEON", "1");
954
Builder.defineMacro("__ARM_NEON__");
955
// current AArch32 NEON implementations do not support double-precision
956
// floating-point even when it is present in VFP.
957
Builder.defineMacro("__ARM_NEON_FP",
958
"0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
959
}
960
961
if (hasMVE()) {
962
Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
963
}
964
965
if (hasCDE()) {
966
Builder.defineMacro("__ARM_FEATURE_CDE", "1");
967
Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
968
"0x" + Twine::utohexstr(getARMCDECoprocMask()));
969
}
970
971
Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
972
Twine(Opts.WCharSize ? Opts.WCharSize : 4));
973
974
Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
975
976
// CMSE
977
if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
978
Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
979
980
if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
981
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
982
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
983
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
984
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
985
}
986
987
// ACLE 6.4.7 DSP instructions
988
if (DSP) {
989
Builder.defineMacro("__ARM_FEATURE_DSP", "1");
990
}
991
992
// ACLE 6.4.8 Saturation instructions
993
bool SAT = false;
994
if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
995
Builder.defineMacro("__ARM_FEATURE_SAT", "1");
996
SAT = true;
997
}
998
999
// ACLE 6.4.6 Q (saturation) flag
1000
if (DSP || SAT)
1001
Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
1002
1003
if (Opts.UnsafeFPMath)
1004
Builder.defineMacro("__ARM_FP_FAST", "1");
1005
1006
// Armv8.2-A FP16 vector intrinsic
1007
if ((FPU & NeonFPU) && HasLegalHalfType)
1008
Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
1009
1010
// Armv8.2-A FP16 scalar intrinsics
1011
if (HasLegalHalfType)
1012
Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
1013
1014
// Armv8.2-A dot product intrinsics
1015
if (DotProd)
1016
Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
1017
1018
if (HasMatMul)
1019
Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
1020
1021
if (HasPAC)
1022
Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
1023
1024
if (HasBTI)
1025
Builder.defineMacro("__ARM_FEATURE_BTI", "1");
1026
1027
if (HasBFloat16) {
1028
Builder.defineMacro("__ARM_FEATURE_BF16", "1");
1029
Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
1030
Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
1031
}
1032
1033
if (Opts.BranchTargetEnforcement)
1034
Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
1035
1036
if (Opts.hasSignReturnAddress()) {
1037
unsigned Value = 1;
1038
if (Opts.isSignReturnAddressScopeAll())
1039
Value |= 1 << 2;
1040
Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
1041
}
1042
1043
switch (ArchKind) {
1044
default:
1045
break;
1046
case llvm::ARM::ArchKind::ARMV8_1A:
1047
getTargetDefinesARMV81A(Opts, Builder);
1048
break;
1049
case llvm::ARM::ArchKind::ARMV8_2A:
1050
getTargetDefinesARMV82A(Opts, Builder);
1051
break;
1052
case llvm::ARM::ArchKind::ARMV8_3A:
1053
case llvm::ARM::ArchKind::ARMV8_4A:
1054
case llvm::ARM::ArchKind::ARMV8_5A:
1055
case llvm::ARM::ArchKind::ARMV8_6A:
1056
case llvm::ARM::ArchKind::ARMV8_7A:
1057
case llvm::ARM::ArchKind::ARMV8_8A:
1058
case llvm::ARM::ArchKind::ARMV8_9A:
1059
case llvm::ARM::ArchKind::ARMV9A:
1060
case llvm::ARM::ArchKind::ARMV9_1A:
1061
case llvm::ARM::ArchKind::ARMV9_2A:
1062
case llvm::ARM::ArchKind::ARMV9_3A:
1063
case llvm::ARM::ArchKind::ARMV9_4A:
1064
case llvm::ARM::ArchKind::ARMV9_5A:
1065
getTargetDefinesARMV83A(Opts, Builder);
1066
break;
1067
}
1068
}
1069
1070
static constexpr Builtin::Info BuiltinInfo[] = {
1071
#define BUILTIN(ID, TYPE, ATTRS) \
1072
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1073
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1074
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1075
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1076
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1077
#include "clang/Basic/BuiltinsNEON.def"
1078
1079
#define BUILTIN(ID, TYPE, ATTRS) \
1080
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1081
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
1082
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1083
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
1084
{#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1085
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
1086
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1087
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
1088
{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1089
#include "clang/Basic/BuiltinsARM.def"
1090
};
1091
1092
ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1093
return llvm::ArrayRef(BuiltinInfo,
1094
clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1095
}
1096
1097
bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
1098
TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
1099
return IsAAPCS
1100
? AAPCSABIBuiltinVaList
1101
: (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1102
: TargetInfo::VoidPtrBuiltinVaList);
1103
}
1104
1105
const char *const ARMTargetInfo::GCCRegNames[] = {
1106
// Integer registers
1107
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1108
"r12", "sp", "lr", "pc",
1109
1110
// Float registers
1111
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1112
"s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1113
"s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1114
1115
// Double registers
1116
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1117
"d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1118
"d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1119
1120
// Quad registers
1121
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1122
"q12", "q13", "q14", "q15"};
1123
1124
ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1125
return llvm::ArrayRef(GCCRegNames);
1126
}
1127
1128
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1129
{{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
1130
{{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
1131
{{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1132
{{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
1133
// The S, D and Q registers overlap, but aren't really aliases; we
1134
// don't want to substitute one of these for a different-sized one.
1135
};
1136
1137
ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1138
return llvm::ArrayRef(GCCRegAliases);
1139
}
1140
1141
bool ARMTargetInfo::validateAsmConstraint(
1142
const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1143
switch (*Name) {
1144
default:
1145
break;
1146
case 'l': // r0-r7 if thumb, r0-r15 if ARM
1147
Info.setAllowsRegister();
1148
return true;
1149
case 'h': // r8-r15, thumb only
1150
if (isThumb()) {
1151
Info.setAllowsRegister();
1152
return true;
1153
}
1154
break;
1155
case 's': // An integer constant, but allowing only relocatable values.
1156
return true;
1157
case 't': // s0-s31, d0-d31, or q0-q15
1158
case 'w': // s0-s15, d0-d7, or q0-q3
1159
case 'x': // s0-s31, d0-d15, or q0-q7
1160
if (FPRegsDisabled)
1161
return false;
1162
Info.setAllowsRegister();
1163
return true;
1164
case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1165
// only available in ARMv6T2 and above
1166
if (CPUAttr == "6T2" || ArchVersion >= 7) {
1167
Info.setRequiresImmediate(0, 65535);
1168
return true;
1169
}
1170
break;
1171
case 'I':
1172
if (isThumb()) {
1173
if (!supportsThumb2())
1174
Info.setRequiresImmediate(0, 255);
1175
else
1176
// FIXME: should check if immediate value would be valid for a Thumb2
1177
// data-processing instruction
1178
Info.setRequiresImmediate();
1179
} else
1180
// FIXME: should check if immediate value would be valid for an ARM
1181
// data-processing instruction
1182
Info.setRequiresImmediate();
1183
return true;
1184
case 'J':
1185
if (isThumb() && !supportsThumb2())
1186
Info.setRequiresImmediate(-255, -1);
1187
else
1188
Info.setRequiresImmediate(-4095, 4095);
1189
return true;
1190
case 'K':
1191
if (isThumb()) {
1192
if (!supportsThumb2())
1193
// FIXME: should check if immediate value can be obtained from shifting
1194
// a value between 0 and 255 left by any amount
1195
Info.setRequiresImmediate();
1196
else
1197
// FIXME: should check if immediate value would be valid for a Thumb2
1198
// data-processing instruction when inverted
1199
Info.setRequiresImmediate();
1200
} else
1201
// FIXME: should check if immediate value would be valid for an ARM
1202
// data-processing instruction when inverted
1203
Info.setRequiresImmediate();
1204
return true;
1205
case 'L':
1206
if (isThumb()) {
1207
if (!supportsThumb2())
1208
Info.setRequiresImmediate(-7, 7);
1209
else
1210
// FIXME: should check if immediate value would be valid for a Thumb2
1211
// data-processing instruction when negated
1212
Info.setRequiresImmediate();
1213
} else
1214
// FIXME: should check if immediate value would be valid for an ARM
1215
// data-processing instruction when negated
1216
Info.setRequiresImmediate();
1217
return true;
1218
case 'M':
1219
if (isThumb() && !supportsThumb2())
1220
// FIXME: should check if immediate value is a multiple of 4 between 0 and
1221
// 1020
1222
Info.setRequiresImmediate();
1223
else
1224
// FIXME: should check if immediate value is a power of two or a integer
1225
// between 0 and 32
1226
Info.setRequiresImmediate();
1227
return true;
1228
case 'N':
1229
// Thumb1 only
1230
if (isThumb() && !supportsThumb2()) {
1231
Info.setRequiresImmediate(0, 31);
1232
return true;
1233
}
1234
break;
1235
case 'O':
1236
// Thumb1 only
1237
if (isThumb() && !supportsThumb2()) {
1238
// FIXME: should check if immediate value is a multiple of 4 between -508
1239
// and 508
1240
Info.setRequiresImmediate();
1241
return true;
1242
}
1243
break;
1244
case 'Q': // A memory address that is a single base register.
1245
Info.setAllowsMemory();
1246
return true;
1247
case 'T':
1248
switch (Name[1]) {
1249
default:
1250
break;
1251
case 'e': // Even general-purpose register
1252
case 'o': // Odd general-purpose register
1253
Info.setAllowsRegister();
1254
Name++;
1255
return true;
1256
}
1257
break;
1258
case 'U': // a memory reference...
1259
switch (Name[1]) {
1260
case 'q': // ...ARMV4 ldrsb
1261
case 'v': // ...VFP load/store (reg+constant offset)
1262
case 'y': // ...iWMMXt load/store
1263
case 't': // address valid for load/store opaque types wider
1264
// than 128-bits
1265
case 'n': // valid address for Neon doubleword vector load/store
1266
case 'm': // valid address for Neon element and structure load/store
1267
case 's': // valid address for non-offset loads/stores of quad-word
1268
// values in four ARM registers
1269
Info.setAllowsMemory();
1270
Name++;
1271
return true;
1272
}
1273
break;
1274
}
1275
return false;
1276
}
1277
1278
std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1279
std::string R;
1280
switch (*Constraint) {
1281
case 'U': // Two-character constraint; add "^" hint for later parsing.
1282
case 'T':
1283
R = std::string("^") + std::string(Constraint, 2);
1284
Constraint++;
1285
break;
1286
case 'p': // 'p' should be translated to 'r' by default.
1287
R = std::string("r");
1288
break;
1289
default:
1290
return std::string(1, *Constraint);
1291
}
1292
return R;
1293
}
1294
1295
bool ARMTargetInfo::validateConstraintModifier(
1296
StringRef Constraint, char Modifier, unsigned Size,
1297
std::string &SuggestedModifier) const {
1298
bool isOutput = (Constraint[0] == '=');
1299
bool isInOut = (Constraint[0] == '+');
1300
1301
// Strip off constraint modifiers.
1302
Constraint = Constraint.ltrim("=+&");
1303
1304
switch (Constraint[0]) {
1305
default:
1306
break;
1307
case 'r': {
1308
switch (Modifier) {
1309
default:
1310
return (isInOut || isOutput || Size <= 64);
1311
case 'q':
1312
// A register of size 32 cannot fit a vector type.
1313
return false;
1314
}
1315
}
1316
}
1317
1318
return true;
1319
}
1320
std::string_view ARMTargetInfo::getClobbers() const {
1321
// FIXME: Is this really right?
1322
return "";
1323
}
1324
1325
TargetInfo::CallingConvCheckResult
1326
ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1327
switch (CC) {
1328
case CC_AAPCS:
1329
case CC_AAPCS_VFP:
1330
case CC_Swift:
1331
case CC_SwiftAsync:
1332
case CC_OpenCLKernel:
1333
return CCCR_OK;
1334
default:
1335
return CCCR_Warning;
1336
}
1337
}
1338
1339
int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1340
if (RegNo == 0)
1341
return 0;
1342
if (RegNo == 1)
1343
return 1;
1344
return -1;
1345
}
1346
1347
bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1348
1349
ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1350
const TargetOptions &Opts)
1351
: ARMTargetInfo(Triple, Opts) {}
1352
1353
void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1354
MacroBuilder &Builder) const {
1355
Builder.defineMacro("__ARMEL__");
1356
ARMTargetInfo::getTargetDefines(Opts, Builder);
1357
}
1358
1359
ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1360
const TargetOptions &Opts)
1361
: ARMTargetInfo(Triple, Opts) {}
1362
1363
void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1364
MacroBuilder &Builder) const {
1365
Builder.defineMacro("__ARMEB__");
1366
Builder.defineMacro("__ARM_BIG_ENDIAN");
1367
ARMTargetInfo::getTargetDefines(Opts, Builder);
1368
}
1369
1370
WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1371
const TargetOptions &Opts)
1372
: WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1373
}
1374
1375
void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1376
MacroBuilder &Builder) const {
1377
// FIXME: this is invalid for WindowsCE
1378
Builder.defineMacro("_M_ARM_NT", "1");
1379
Builder.defineMacro("_M_ARMT", "_M_ARM");
1380
Builder.defineMacro("_M_THUMB", "_M_ARM");
1381
1382
assert((Triple.getArch() == llvm::Triple::arm ||
1383
Triple.getArch() == llvm::Triple::thumb) &&
1384
"invalid architecture for Windows ARM target info");
1385
unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1386
Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1387
1388
// TODO map the complete set of values
1389
// 31: VFPv3 40: VFPv4
1390
Builder.defineMacro("_M_ARM_FP", "31");
1391
}
1392
1393
TargetInfo::BuiltinVaListKind
1394
WindowsARMTargetInfo::getBuiltinVaListKind() const {
1395
return TargetInfo::CharPtrBuiltinVaList;
1396
}
1397
1398
TargetInfo::CallingConvCheckResult
1399
WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1400
switch (CC) {
1401
case CC_X86StdCall:
1402
case CC_X86ThisCall:
1403
case CC_X86FastCall:
1404
case CC_X86VectorCall:
1405
return CCCR_Ignore;
1406
case CC_C:
1407
case CC_OpenCLKernel:
1408
case CC_PreserveMost:
1409
case CC_PreserveAll:
1410
case CC_Swift:
1411
case CC_SwiftAsync:
1412
return CCCR_OK;
1413
default:
1414
return CCCR_Warning;
1415
}
1416
}
1417
1418
// Windows ARM + Itanium C++ ABI Target
1419
ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1420
const llvm::Triple &Triple, const TargetOptions &Opts)
1421
: WindowsARMTargetInfo(Triple, Opts) {
1422
TheCXXABI.set(TargetCXXABI::GenericARM);
1423
}
1424
1425
void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1426
const LangOptions &Opts, MacroBuilder &Builder) const {
1427
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1428
1429
if (Opts.MSVCCompat)
1430
WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1431
}
1432
1433
// Windows ARM, MS (C++) ABI
1434
MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1435
const TargetOptions &Opts)
1436
: WindowsARMTargetInfo(Triple, Opts) {
1437
TheCXXABI.set(TargetCXXABI::Microsoft);
1438
}
1439
1440
void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1441
MacroBuilder &Builder) const {
1442
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1443
WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1444
}
1445
1446
MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1447
const TargetOptions &Opts)
1448
: WindowsARMTargetInfo(Triple, Opts) {
1449
TheCXXABI.set(TargetCXXABI::GenericARM);
1450
}
1451
1452
void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1453
MacroBuilder &Builder) const {
1454
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1455
Builder.defineMacro("_ARM_");
1456
}
1457
1458
CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1459
const TargetOptions &Opts)
1460
: ARMleTargetInfo(Triple, Opts) {
1461
this->WCharType = TargetInfo::UnsignedShort;
1462
TLSSupported = false;
1463
DoubleAlign = LongLongAlign = 64;
1464
resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1465
}
1466
1467
void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1468
MacroBuilder &Builder) const {
1469
ARMleTargetInfo::getTargetDefines(Opts, Builder);
1470
Builder.defineMacro("_ARM_");
1471
Builder.defineMacro("__CYGWIN__");
1472
Builder.defineMacro("__CYGWIN32__");
1473
DefineStd(Builder, "unix", Opts);
1474
if (Opts.CPlusPlus)
1475
Builder.defineMacro("_GNU_SOURCE");
1476
}
1477
1478
DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1479
const TargetOptions &Opts)
1480
: DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1481
HasAlignMac68kSupport = true;
1482
if (Triple.isWatchABI()) {
1483
// Darwin on iOS uses a variant of the ARM C++ ABI.
1484
TheCXXABI.set(TargetCXXABI::WatchOS);
1485
1486
// BOOL should be a real boolean on the new ABI
1487
UseSignedCharForObjCBool = false;
1488
} else
1489
TheCXXABI.set(TargetCXXABI::iOS);
1490
}
1491
1492
void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1493
const llvm::Triple &Triple,
1494
MacroBuilder &Builder) const {
1495
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1496
}
1497
1498
RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1499
const TargetOptions &Opts)
1500
: ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1501
Triple.getOSName(),
1502
Triple.getEnvironmentName()),
1503
Opts) {
1504
IsRenderScriptTarget = true;
1505
LongWidth = LongAlign = 64;
1506
}
1507
1508
void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1509
MacroBuilder &Builder) const {
1510
Builder.defineMacro("__RENDERSCRIPT__");
1511
ARMleTargetInfo::getTargetDefines(Opts, Builder);
1512
}
1513
1514