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
setABIAAPCS()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
setABIAPCS(bool IsAAPCS16)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
setArchInfo()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
setArchInfo(llvm::ARM::ArchKind Kind)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
setAtomic()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
hasMVE() const157 bool ARMTargetInfo::hasMVE() const {
158 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
159 }
160
hasMVEFloat() const161 bool ARMTargetInfo::hasMVEFloat() const {
162 return hasMVE() && (MVE & MVE_FP);
163 }
164
hasCDE() const165 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
166
isThumb() const167 bool ARMTargetInfo::isThumb() const {
168 return ArchISA == llvm::ARM::ISAKind::THUMB;
169 }
170
supportsThumb() const171 bool ARMTargetInfo::supportsThumb() const {
172 return CPUAttr.count('T') || ArchVersion >= 6;
173 }
174
supportsThumb2() const175 bool ARMTargetInfo::supportsThumb2() const {
176 return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE");
177 }
178
getCPUAttr() const179 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
getCPUProfile() const242 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
ARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getABI() const366 StringRef ARMTargetInfo::getABI() const { return ABI; }
367
setABI(const std::string & Name)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
isBranchProtectionSupportedArch(StringRef Arch) const386 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
validateBranchProtection(StringRef Spec,StringRef Arch,BranchProtectionInfo & BPI,StringRef & Err) const404 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.
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const431 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
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)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
hasFeature(StringRef Feature) const647 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
hasBFloat16Type() const661 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
isValidCPUName(StringRef Name) const666 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
667 return Name == "generic" ||
668 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
669 }
670
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const671 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
672 llvm::ARM::fillValidCPUArchList(Values);
673 }
674
setCPU(const std::string & Name)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
setFPMath(StringRef Name)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
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const698 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
699 MacroBuilder &Builder) const {
700 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
701 }
702
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const703 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
704 MacroBuilder &Builder) const {
705 // Also include the ARMv8.1-A defines
706 getTargetDefinesARMV81A(Opts, Builder);
707 }
708
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const709 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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const716 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
getTargetBuiltins() const1092 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1093 return llvm::ArrayRef(BuiltinInfo,
1094 clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1095 }
1096
isCLZForZeroUndef() const1097 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
getBuiltinVaListKind() const1098 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
getGCCRegNames() const1124 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
getGCCRegAliases() const1137 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1138 return llvm::ArrayRef(GCCRegAliases);
1139 }
1140
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1141 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
convertConstraint(const char * & Constraint) const1278 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
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const1295 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 }
getClobbers() const1320 std::string_view ARMTargetInfo::getClobbers() const {
1321 // FIXME: Is this really right?
1322 return "";
1323 }
1324
1325 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1326 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
getEHDataRegisterNumber(unsigned RegNo) const1339 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
hasSjLjLowering() const1347 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1348
ARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1349 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1350 const TargetOptions &Opts)
1351 : ARMTargetInfo(Triple, Opts) {}
1352
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1353 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1354 MacroBuilder &Builder) const {
1355 Builder.defineMacro("__ARMEL__");
1356 ARMTargetInfo::getTargetDefines(Opts, Builder);
1357 }
1358
ARMbeTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1359 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1360 const TargetOptions &Opts)
1361 : ARMTargetInfo(Triple, Opts) {}
1362
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1363 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
WindowsARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1370 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1371 const TargetOptions &Opts)
1372 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1373 }
1374
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const1375 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
getBuiltinVaListKind() const1394 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1395 return TargetInfo::CharPtrBuiltinVaList;
1396 }
1397
1398 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1399 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
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1419 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1420 const llvm::Triple &Triple, const TargetOptions &Opts)
1421 : WindowsARMTargetInfo(Triple, Opts) {
1422 TheCXXABI.set(TargetCXXABI::GenericARM);
1423 }
1424
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1425 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
MicrosoftARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1434 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1435 const TargetOptions &Opts)
1436 : WindowsARMTargetInfo(Triple, Opts) {
1437 TheCXXABI.set(TargetCXXABI::Microsoft);
1438 }
1439
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1440 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1441 MacroBuilder &Builder) const {
1442 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1443 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1444 }
1445
MinGWARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1446 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1447 const TargetOptions &Opts)
1448 : WindowsARMTargetInfo(Triple, Opts) {
1449 TheCXXABI.set(TargetCXXABI::GenericARM);
1450 }
1451
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1452 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1453 MacroBuilder &Builder) const {
1454 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1455 Builder.defineMacro("_ARM_");
1456 }
1457
CygwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1467 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
DarwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1492 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1493 const llvm::Triple &Triple,
1494 MacroBuilder &Builder) const {
1495 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1496 }
1497
RenderScript32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1508 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1509 MacroBuilder &Builder) const {
1510 Builder.defineMacro("__RENDERSCRIPT__");
1511 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1512 }
1513