xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
1 //===--- AArch64.cpp - Implement AArch64 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 AArch64 TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AArch64.h"
14 #include "clang/Basic/LangOptions.h"
15 #include "clang/Basic/TargetBuiltins.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/TargetParser/AArch64TargetParser.h"
21 #include "llvm/TargetParser/ARMTargetParserCommon.h"
22 #include <optional>
23 
24 using namespace clang;
25 using namespace clang::targets;
26 
27 static constexpr Builtin::Info BuiltinInfo[] = {
28 #define BUILTIN(ID, TYPE, ATTRS)                                               \
29   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
30 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
31   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
32 #include "clang/Basic/BuiltinsNEON.def"
33 
34 #define BUILTIN(ID, TYPE, ATTRS)                                               \
35   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
36 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
37   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
38 #include "clang/Basic/BuiltinsSVE.def"
39 
40 #define BUILTIN(ID, TYPE, ATTRS)                                               \
41   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
42 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
43   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
44 #include "clang/Basic/BuiltinsSME.def"
45 
46 #define BUILTIN(ID, TYPE, ATTRS)                                               \
47   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
48 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
49   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
50 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
51   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
52 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
53   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
54 #include "clang/Basic/BuiltinsAArch64.def"
55 };
56 
57 void AArch64TargetInfo::setArchFeatures() {
58   if (*ArchInfo == llvm::AArch64::ARMV8R) {
59     HasDotProd = true;
60     HasDIT = true;
61     HasFlagM = true;
62     HasRCPC = true;
63     FPU |= NeonMode;
64     HasCCPP = true;
65     HasCRC = true;
66     HasLSE = true;
67     HasRDM = true;
68   } else if (ArchInfo->Version.getMajor() == 8) {
69     if (ArchInfo->Version.getMinor() >= 7u) {
70       HasWFxT = true;
71     }
72     if (ArchInfo->Version.getMinor() >= 6u) {
73       HasBFloat16 = true;
74       HasMatMul = true;
75     }
76     if (ArchInfo->Version.getMinor() >= 5u) {
77       HasAlternativeNZCV = true;
78       HasFRInt3264 = true;
79       HasSSBS = true;
80       HasSB = true;
81       HasPredRes = true;
82       HasBTI = true;
83     }
84     if (ArchInfo->Version.getMinor() >= 4u) {
85       HasDotProd = true;
86       HasDIT = true;
87       HasFlagM = true;
88     }
89     if (ArchInfo->Version.getMinor() >= 3u) {
90       HasRCPC = true;
91       FPU |= NeonMode;
92     }
93     if (ArchInfo->Version.getMinor() >= 2u) {
94       HasCCPP = true;
95     }
96     if (ArchInfo->Version.getMinor() >= 1u) {
97       HasCRC = true;
98       HasLSE = true;
99       HasRDM = true;
100     }
101   } else if (ArchInfo->Version.getMajor() == 9) {
102     if (ArchInfo->Version.getMinor() >= 2u) {
103       HasWFxT = true;
104     }
105     if (ArchInfo->Version.getMinor() >= 1u) {
106       HasBFloat16 = true;
107       HasMatMul = true;
108     }
109     FPU |= SveMode;
110     HasSVE2 = true;
111     HasFullFP16 = true;
112     HasAlternativeNZCV = true;
113     HasFRInt3264 = true;
114     HasSSBS = true;
115     HasSB = true;
116     HasPredRes = true;
117     HasBTI = true;
118     HasDotProd = true;
119     HasDIT = true;
120     HasFlagM = true;
121     HasRCPC = true;
122     FPU |= NeonMode;
123     HasCCPP = true;
124     HasCRC = true;
125     HasLSE = true;
126     HasRDM = true;
127   }
128 }
129 
130 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
131                                      const TargetOptions &Opts)
132     : TargetInfo(Triple), ABI("aapcs") {
133   if (getTriple().isOSOpenBSD()) {
134     Int64Type = SignedLongLong;
135     IntMaxType = SignedLongLong;
136   } else {
137     if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
138       WCharType = UnsignedInt;
139 
140     Int64Type = SignedLong;
141     IntMaxType = SignedLong;
142   }
143 
144   // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
145   HasLegalHalfType = true;
146   HalfArgsAndReturns = true;
147   HasFloat16 = true;
148   HasStrictFP = true;
149 
150   if (Triple.isArch64Bit())
151     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
152   else
153     LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
154 
155   MaxVectorAlign = 128;
156   MaxAtomicInlineWidth = 128;
157   MaxAtomicPromoteWidth = 128;
158 
159   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
160   LongDoubleFormat = &llvm::APFloat::IEEEquad();
161 
162   BFloat16Width = BFloat16Align = 16;
163   BFloat16Format = &llvm::APFloat::BFloat();
164 
165   // Make __builtin_ms_va_list available.
166   HasBuiltinMSVaList = true;
167 
168   // Make the SVE types available.  Note that this deliberately doesn't
169   // depend on SveMode, since in principle it should be possible to turn
170   // SVE on and off within a translation unit.  It should also be possible
171   // to compile the global declaration:
172   //
173   // __SVInt8_t *ptr;
174   //
175   // even without SVE.
176   HasAArch64SVETypes = true;
177 
178   // {} in inline assembly are neon specifiers, not assembly variant
179   // specifiers.
180   NoAsmVariants = true;
181 
182   // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
183   // contributes to the alignment of the containing aggregate in the same way
184   // a plain (non bit-field) member of that type would, without exception for
185   // zero-sized or anonymous bit-fields."
186   assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
187   UseZeroLengthBitfieldAlignment = true;
188 
189   // AArch64 targets default to using the ARM C++ ABI.
190   TheCXXABI.set(TargetCXXABI::GenericAArch64);
191 
192   if (Triple.getOS() == llvm::Triple::Linux)
193     this->MCountName = "\01_mcount";
194   else if (Triple.getOS() == llvm::Triple::UnknownOS)
195     this->MCountName =
196         Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
197 }
198 
199 StringRef AArch64TargetInfo::getABI() const { return ABI; }
200 
201 bool AArch64TargetInfo::setABI(const std::string &Name) {
202   if (Name != "aapcs" && Name != "darwinpcs")
203     return false;
204 
205   ABI = Name;
206   return true;
207 }
208 
209 bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
210                                                  BranchProtectionInfo &BPI,
211                                                  StringRef &Err) const {
212   llvm::ARM::ParsedBranchProtection PBP;
213   if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
214     return false;
215 
216   BPI.SignReturnAddr =
217       llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
218           .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
219           .Case("all", LangOptions::SignReturnAddressScopeKind::All)
220           .Default(LangOptions::SignReturnAddressScopeKind::None);
221 
222   if (PBP.Key == "a_key")
223     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
224   else
225     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
226 
227   BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
228   BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
229   BPI.GuardedControlStack = PBP.GuardedControlStack;
230   return true;
231 }
232 
233 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
234   return Name == "generic" || llvm::AArch64::parseCpu(Name);
235 }
236 
237 bool AArch64TargetInfo::setCPU(const std::string &Name) {
238   return isValidCPUName(Name);
239 }
240 
241 void AArch64TargetInfo::fillValidCPUList(
242     SmallVectorImpl<StringRef> &Values) const {
243   llvm::AArch64::fillValidCPUArchList(Values);
244 }
245 
246 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
247                                                 MacroBuilder &Builder) const {
248   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
249 }
250 
251 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
252                                                 MacroBuilder &Builder) const {
253   // Also include the ARMv8.1 defines
254   getTargetDefinesARMV81A(Opts, Builder);
255 }
256 
257 void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
258                                                 MacroBuilder &Builder) const {
259   Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
260   Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
261   // Also include the Armv8.2 defines
262   getTargetDefinesARMV82A(Opts, Builder);
263 }
264 
265 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
266                                                 MacroBuilder &Builder) const {
267   // Also include the Armv8.3 defines
268   getTargetDefinesARMV83A(Opts, Builder);
269 }
270 
271 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
272                                                 MacroBuilder &Builder) const {
273   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
274   Builder.defineMacro("__ARM_FEATURE_BTI", "1");
275   // Also include the Armv8.4 defines
276   getTargetDefinesARMV84A(Opts, Builder);
277 }
278 
279 void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
280                                                 MacroBuilder &Builder) const {
281   // Also include the Armv8.5 defines
282   // FIXME: Armv8.6 makes the following extensions mandatory:
283   // - __ARM_FEATURE_BF16
284   // - __ARM_FEATURE_MATMUL_INT8
285   // Handle them here.
286   getTargetDefinesARMV85A(Opts, Builder);
287 }
288 
289 void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
290                                                 MacroBuilder &Builder) const {
291   // Also include the Armv8.6 defines
292   getTargetDefinesARMV86A(Opts, Builder);
293 }
294 
295 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
296                                                 MacroBuilder &Builder) const {
297   // Also include the Armv8.7 defines
298   getTargetDefinesARMV87A(Opts, Builder);
299 }
300 
301 void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
302                                                 MacroBuilder &Builder) const {
303   // Also include the Armv8.8 defines
304   getTargetDefinesARMV88A(Opts, Builder);
305 }
306 
307 void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
308                                                MacroBuilder &Builder) const {
309   // Armv9-A maps to Armv8.5-A
310   getTargetDefinesARMV85A(Opts, Builder);
311 }
312 
313 void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
314                                                 MacroBuilder &Builder) const {
315   // Armv9.1-A maps to Armv8.6-A
316   getTargetDefinesARMV86A(Opts, Builder);
317 }
318 
319 void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
320                                                 MacroBuilder &Builder) const {
321   // Armv9.2-A maps to Armv8.7-A
322   getTargetDefinesARMV87A(Opts, Builder);
323 }
324 
325 void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
326                                                 MacroBuilder &Builder) const {
327   // Armv9.3-A maps to Armv8.8-A
328   getTargetDefinesARMV88A(Opts, Builder);
329 }
330 
331 void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
332                                                 MacroBuilder &Builder) const {
333   // Armv9.4-A maps to Armv8.9-A
334   getTargetDefinesARMV89A(Opts, Builder);
335 }
336 
337 void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
338                                                 MacroBuilder &Builder) const {
339   // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
340   getTargetDefinesARMV94A(Opts, Builder);
341 }
342 
343 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
344                                          MacroBuilder &Builder) const {
345   // Target identification.
346   if (getTriple().isWindowsArm64EC()) {
347     // Define the same set of macros as would be defined on x86_64 to ensure that
348     // ARM64EC datatype layouts match those of x86_64 compiled code
349     Builder.defineMacro("__amd64__");
350     Builder.defineMacro("__amd64");
351     Builder.defineMacro("__x86_64");
352     Builder.defineMacro("__x86_64__");
353     Builder.defineMacro("__arm64ec__");
354   } else {
355     Builder.defineMacro("__aarch64__");
356   }
357 
358   // Inline assembly supports AArch64 flag outputs.
359   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
360 
361   std::string CodeModel = getTargetOpts().CodeModel;
362   if (CodeModel == "default")
363     CodeModel = "small";
364   for (char &c : CodeModel)
365     c = toupper(c);
366   Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
367 
368   // ACLE predefines. Many can only have one possible value on v8 AArch64.
369   Builder.defineMacro("__ARM_ACLE", "200");
370   Builder.defineMacro("__ARM_ARCH",
371                       std::to_string(ArchInfo->Version.getMajor()));
372   Builder.defineMacro("__ARM_ARCH_PROFILE",
373                       std::string("'") + (char)ArchInfo->Profile + "'");
374 
375   Builder.defineMacro("__ARM_64BIT_STATE", "1");
376   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
377   Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
378 
379   Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
380   Builder.defineMacro("__ARM_FEATURE_FMA", "1");
381   Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
382   Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
383   Builder.defineMacro("__ARM_FEATURE_DIV");       // For backwards compatibility
384   Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
385   Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
386 
387   Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
388 
389   // These macros are set when Clang can parse declarations with these
390   // attributes.
391   Builder.defineMacro("__ARM_STATE_ZA", "1");
392   Builder.defineMacro("__ARM_STATE_ZT0", "1");
393 
394   // 0xe implies support for half, single and double precision operations.
395   if (FPU & FPUMode)
396     Builder.defineMacro("__ARM_FP", "0xE");
397 
398   // PCS specifies this for SysV variants, which is all we support. Other ABIs
399   // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
400   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
401   Builder.defineMacro("__ARM_FP16_ARGS", "1");
402 
403   if (Opts.UnsafeFPMath)
404     Builder.defineMacro("__ARM_FP_FAST", "1");
405 
406   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
407                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
408 
409   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
410 
411   if (FPU & NeonMode) {
412     Builder.defineMacro("__ARM_NEON", "1");
413     // 64-bit NEON supports half, single and double precision operations.
414     Builder.defineMacro("__ARM_NEON_FP", "0xE");
415   }
416 
417   if (FPU & SveMode)
418     Builder.defineMacro("__ARM_FEATURE_SVE", "1");
419 
420   if ((FPU & NeonMode) && (FPU & SveMode))
421     Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
422 
423   if (HasSVE2)
424     Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
425 
426   if (HasSVE2 && HasSVE2AES)
427     Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
428 
429   if (HasSVE2 && HasSVE2BitPerm)
430     Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
431 
432   if (HasSVE2 && HasSVE2SHA3)
433     Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
434 
435   if (HasSVE2 && HasSVE2SM4)
436     Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
437 
438   if (HasSME) {
439     Builder.defineMacro("__ARM_FEATURE_SME");
440     Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
441   }
442 
443   if (HasSME2) {
444     Builder.defineMacro("__ARM_FEATURE_SME");
445     Builder.defineMacro("__ARM_FEATURE_SME2");
446     Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
447   }
448 
449   if (HasCRC)
450     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
451 
452   if (HasRCPC3)
453     Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
454   else if (HasRCPC)
455     Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
456 
457   if (HasFMV)
458     Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
459 
460   // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
461   // macros for AES, SHA2, SHA3 and SM4
462   if (HasAES && HasSHA2)
463     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
464 
465   if (HasAES)
466     Builder.defineMacro("__ARM_FEATURE_AES", "1");
467 
468   if (HasSHA2)
469     Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
470 
471   if (HasSHA3) {
472     Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
473     Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
474   }
475 
476   if (HasSM4) {
477     Builder.defineMacro("__ARM_FEATURE_SM3", "1");
478     Builder.defineMacro("__ARM_FEATURE_SM4", "1");
479   }
480 
481   if (HasPAuth)
482     Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
483 
484   if (HasUnaligned)
485     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
486 
487   if ((FPU & NeonMode) && HasFullFP16)
488     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
489   if (HasFullFP16)
490    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
491 
492   if (HasDotProd)
493     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
494 
495   if (HasMTE)
496     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
497 
498   if (HasTME)
499     Builder.defineMacro("__ARM_FEATURE_TME", "1");
500 
501   if (HasMatMul)
502     Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
503 
504   if (HasLSE)
505     Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
506 
507   if (HasBFloat16) {
508     Builder.defineMacro("__ARM_FEATURE_BF16", "1");
509     Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
510     Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
511     Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
512   }
513 
514   if ((FPU & SveMode) && HasBFloat16) {
515     Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
516   }
517 
518   if ((FPU & SveMode) && HasMatmulFP64)
519     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
520 
521   if ((FPU & SveMode) && HasMatmulFP32)
522     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
523 
524   if ((FPU & SveMode) && HasMatMul)
525     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
526 
527   if ((FPU & NeonMode) && HasFP16FML)
528     Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
529 
530   if (Opts.hasSignReturnAddress()) {
531     // Bitmask:
532     // 0: Protection using the A key
533     // 1: Protection using the B key
534     // 2: Protection including leaf functions
535     unsigned Value = 0;
536 
537     if (Opts.isSignReturnAddressWithAKey())
538       Value |= (1 << 0);
539     else
540       Value |= (1 << 1);
541 
542     if (Opts.isSignReturnAddressScopeAll())
543       Value |= (1 << 2);
544 
545     Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
546   }
547 
548   if (Opts.BranchTargetEnforcement)
549     Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
550 
551   if (Opts.GuardedControlStack)
552     Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
553 
554   if (HasLS64)
555     Builder.defineMacro("__ARM_FEATURE_LS64", "1");
556 
557   if (HasRandGen)
558     Builder.defineMacro("__ARM_FEATURE_RNG", "1");
559 
560   if (HasMOPS)
561     Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
562 
563   if (HasD128)
564     Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
565 
566   if (HasGCS)
567     Builder.defineMacro("__ARM_FEATURE_GCS", "1");
568 
569   if (*ArchInfo == llvm::AArch64::ARMV8_1A)
570     getTargetDefinesARMV81A(Opts, Builder);
571   else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
572     getTargetDefinesARMV82A(Opts, Builder);
573   else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
574     getTargetDefinesARMV83A(Opts, Builder);
575   else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
576     getTargetDefinesARMV84A(Opts, Builder);
577   else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
578     getTargetDefinesARMV85A(Opts, Builder);
579   else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
580     getTargetDefinesARMV86A(Opts, Builder);
581   else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
582     getTargetDefinesARMV87A(Opts, Builder);
583   else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
584     getTargetDefinesARMV88A(Opts, Builder);
585   else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
586     getTargetDefinesARMV89A(Opts, Builder);
587   else if (*ArchInfo == llvm::AArch64::ARMV9A)
588     getTargetDefinesARMV9A(Opts, Builder);
589   else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
590     getTargetDefinesARMV91A(Opts, Builder);
591   else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
592     getTargetDefinesARMV92A(Opts, Builder);
593   else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
594     getTargetDefinesARMV93A(Opts, Builder);
595   else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
596     getTargetDefinesARMV94A(Opts, Builder);
597   else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
598     getTargetDefinesARMV95A(Opts, Builder);
599 
600   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
601   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
602   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
603   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
604   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
605   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
606 
607   // Allow detection of fast FMA support.
608   Builder.defineMacro("__FP_FAST_FMA", "1");
609   Builder.defineMacro("__FP_FAST_FMAF", "1");
610 
611   // C/C++ operators work on both VLS and VLA SVE types
612   if (FPU & SveMode)
613     Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
614 
615   if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
616     Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
617   }
618 }
619 
620 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
621   return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
622                                          Builtin::FirstTSBuiltin);
623 }
624 
625 std::optional<std::pair<unsigned, unsigned>>
626 AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
627   if (LangOpts.VScaleMin || LangOpts.VScaleMax)
628     return std::pair<unsigned, unsigned>(
629         LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
630 
631   if (hasFeature("sve"))
632     return std::pair<unsigned, unsigned>(1, 16);
633 
634   return std::nullopt;
635 }
636 
637 unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
638   if (Name == "default")
639     return 0;
640   if (auto Ext = llvm::AArch64::parseArchExtension(Name))
641     return Ext->FmvPriority;
642   return 0;
643 }
644 
645 unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
646   // Take the maximum priority as per feature cost, so more features win.
647   return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
648 }
649 
650 bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
651   if (auto Ext = llvm::AArch64::parseArchExtension(Name))
652     return !Ext->DependentFeatures.empty();
653   return false;
654 }
655 
656 StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
657   if (auto Ext = llvm::AArch64::parseArchExtension(Name))
658     return Ext->DependentFeatures;
659   return StringRef();
660 }
661 
662 bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
663   return llvm::AArch64::parseArchExtension(FeatureStr).has_value();
664 }
665 
666 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
667   return llvm::StringSwitch<bool>(Feature)
668       .Cases("aarch64", "arm64", "arm", true)
669       .Case("fmv", HasFMV)
670       .Cases("neon", "fp", "simd", FPU & NeonMode)
671       .Case("jscvt", HasJSCVT)
672       .Case("fcma", HasFCMA)
673       .Case("rng", HasRandGen)
674       .Case("flagm", HasFlagM)
675       .Case("flagm2", HasAlternativeNZCV)
676       .Case("fp16fml", HasFP16FML)
677       .Case("dotprod", HasDotProd)
678       .Case("sm4", HasSM4)
679       .Case("rdm", HasRDM)
680       .Case("lse", HasLSE)
681       .Case("crc", HasCRC)
682       .Case("sha2", HasSHA2)
683       .Case("sha3", HasSHA3)
684       .Cases("aes", "pmull", HasAES)
685       .Cases("fp16", "fullfp16", HasFullFP16)
686       .Case("dit", HasDIT)
687       .Case("dpb", HasCCPP)
688       .Case("dpb2", HasCCDP)
689       .Case("rcpc", HasRCPC)
690       .Case("frintts", HasFRInt3264)
691       .Case("i8mm", HasMatMul)
692       .Case("bf16", HasBFloat16)
693       .Case("sve", FPU & SveMode)
694       .Case("sve-bf16", FPU & SveMode && HasBFloat16)
695       .Case("sve-i8mm", FPU & SveMode && HasMatMul)
696       .Case("f32mm", FPU & SveMode && HasMatmulFP32)
697       .Case("f64mm", FPU & SveMode && HasMatmulFP64)
698       .Case("sve2", FPU & SveMode && HasSVE2)
699       .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
700       .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
701       .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
702       .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
703       .Case("sme", HasSME)
704       .Case("sme2", HasSME2)
705       .Case("sme-f64f64", HasSMEF64F64)
706       .Case("sme-i16i64", HasSMEI16I64)
707       .Case("sme-fa64", HasSMEFA64)
708       .Cases("memtag", "memtag2", HasMTE)
709       .Case("sb", HasSB)
710       .Case("predres", HasPredRes)
711       .Cases("ssbs", "ssbs2", HasSSBS)
712       .Case("bti", HasBTI)
713       .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
714       .Case("wfxt", HasWFxT)
715       .Case("rcpc3", HasRCPC3)
716       .Default(false);
717 }
718 
719 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
720                                           StringRef Name, bool Enabled) const {
721   Features[Name] = Enabled;
722   // If the feature is an architecture feature (like v8.2a), add all previous
723   // architecture versions and any dependant target features.
724   const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
725       llvm::AArch64::ArchInfo::findBySubArch(Name);
726 
727   if (!ArchInfo)
728     return; // Not an architecture, nothing more to do.
729 
730   // Disabling an architecture feature does not affect dependent features
731   if (!Enabled)
732     return;
733 
734   for (const auto *OtherArch : llvm::AArch64::ArchInfos)
735     if (ArchInfo->implies(*OtherArch))
736       Features[OtherArch->getSubArch()] = true;
737 
738   // Set any features implied by the architecture
739   std::vector<StringRef> CPUFeats;
740   if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
741     for (auto F : CPUFeats) {
742       assert(F[0] == '+' && "Expected + in target feature!");
743       Features[F.drop_front(1)] = true;
744     }
745   }
746 }
747 
748 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
749                                              DiagnosticsEngine &Diags) {
750   for (const auto &Feature : Features) {
751     if (Feature == "-fp-armv8")
752       HasNoFP = true;
753     if (Feature == "-neon")
754       HasNoNeon = true;
755     if (Feature == "-sve")
756       HasNoSVE = true;
757 
758     if (Feature == "+neon" || Feature == "+fp-armv8")
759       FPU |= NeonMode;
760     if (Feature == "+jscvt") {
761       HasJSCVT = true;
762       FPU |= NeonMode;
763     }
764     if (Feature == "+fcma") {
765       HasFCMA = true;
766       FPU |= NeonMode;
767     }
768 
769     if (Feature == "+sve") {
770       FPU |= NeonMode;
771       FPU |= SveMode;
772       HasFullFP16 = true;
773     }
774     if (Feature == "+sve2") {
775       FPU |= NeonMode;
776       FPU |= SveMode;
777       HasFullFP16 = true;
778       HasSVE2 = true;
779     }
780     if (Feature == "+sve2-aes") {
781       FPU |= NeonMode;
782       FPU |= SveMode;
783       HasFullFP16 = true;
784       HasSVE2 = true;
785       HasSVE2AES = true;
786     }
787     if (Feature == "+sve2-sha3") {
788       FPU |= NeonMode;
789       FPU |= SveMode;
790       HasFullFP16 = true;
791       HasSVE2 = true;
792       HasSVE2SHA3 = true;
793     }
794     if (Feature == "+sve2-sm4") {
795       FPU |= NeonMode;
796       FPU |= SveMode;
797       HasFullFP16 = true;
798       HasSVE2 = true;
799       HasSVE2SM4 = true;
800     }
801     if (Feature == "+sve2-bitperm") {
802       FPU |= NeonMode;
803       FPU |= SveMode;
804       HasFullFP16 = true;
805       HasSVE2 = true;
806       HasSVE2BitPerm = true;
807     }
808     if (Feature == "+f32mm") {
809       FPU |= NeonMode;
810       FPU |= SveMode;
811       HasFullFP16 = true;
812       HasMatmulFP32 = true;
813     }
814     if (Feature == "+f64mm") {
815       FPU |= NeonMode;
816       FPU |= SveMode;
817       HasFullFP16 = true;
818       HasMatmulFP64 = true;
819     }
820     if (Feature == "+sme") {
821       HasSME = true;
822       HasBFloat16 = true;
823       HasFullFP16 = true;
824     }
825     if (Feature == "+sme2") {
826       HasSME = true;
827       HasSME2 = true;
828       HasBFloat16 = true;
829       HasFullFP16 = true;
830     }
831     if (Feature == "+sme-f64f64") {
832       HasSME = true;
833       HasSMEF64F64 = true;
834       HasBFloat16 = true;
835       HasFullFP16 = true;
836     }
837     if (Feature == "+sme-i16i64") {
838       HasSME = true;
839       HasSMEI16I64 = true;
840       HasBFloat16 = true;
841       HasFullFP16 = true;
842     }
843     if (Feature == "+sme-fa64") {
844       FPU |= NeonMode;
845       FPU |= SveMode;
846       HasSME = true;
847       HasSVE2 = true;
848       HasSMEFA64 = true;
849     }
850     if (Feature == "+sb")
851       HasSB = true;
852     if (Feature == "+predres")
853       HasPredRes = true;
854     if (Feature == "+ssbs")
855       HasSSBS = true;
856     if (Feature == "+bti")
857       HasBTI = true;
858     if (Feature == "+wfxt")
859       HasWFxT = true;
860     if (Feature == "-fmv")
861       HasFMV = false;
862     if (Feature == "+crc")
863       HasCRC = true;
864     if (Feature == "+rcpc")
865       HasRCPC = true;
866     if (Feature == "+aes") {
867       FPU |= NeonMode;
868       HasAES = true;
869     }
870     if (Feature == "+sha2") {
871       FPU |= NeonMode;
872       HasSHA2 = true;
873     }
874     if (Feature == "+sha3") {
875       FPU |= NeonMode;
876       HasSHA2 = true;
877       HasSHA3 = true;
878     }
879     if (Feature == "+rdm") {
880       FPU |= NeonMode;
881       HasRDM = true;
882     }
883     if (Feature == "+dit")
884       HasDIT = true;
885     if (Feature == "+cccp")
886       HasCCPP = true;
887     if (Feature == "+ccdp") {
888       HasCCPP = true;
889       HasCCDP = true;
890     }
891     if (Feature == "+fptoint")
892       HasFRInt3264 = true;
893     if (Feature == "+sm4") {
894       FPU |= NeonMode;
895       HasSM4 = true;
896     }
897     if (Feature == "+strict-align")
898       HasUnaligned = false;
899     // All predecessor archs are added but select the latest one for ArchKind.
900     if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
901       ArchInfo = &llvm::AArch64::ARMV8A;
902     if (Feature == "+v8.1a" &&
903         ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
904       ArchInfo = &llvm::AArch64::ARMV8_1A;
905     if (Feature == "+v8.2a" &&
906         ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
907       ArchInfo = &llvm::AArch64::ARMV8_2A;
908     if (Feature == "+v8.3a" &&
909         ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
910       ArchInfo = &llvm::AArch64::ARMV8_3A;
911     if (Feature == "+v8.4a" &&
912         ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
913       ArchInfo = &llvm::AArch64::ARMV8_4A;
914     if (Feature == "+v8.5a" &&
915         ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
916       ArchInfo = &llvm::AArch64::ARMV8_5A;
917     if (Feature == "+v8.6a" &&
918         ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
919       ArchInfo = &llvm::AArch64::ARMV8_6A;
920     if (Feature == "+v8.7a" &&
921         ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
922       ArchInfo = &llvm::AArch64::ARMV8_7A;
923     if (Feature == "+v8.8a" &&
924         ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
925       ArchInfo = &llvm::AArch64::ARMV8_8A;
926     if (Feature == "+v8.9a" &&
927         ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
928       ArchInfo = &llvm::AArch64::ARMV8_9A;
929     if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
930       ArchInfo = &llvm::AArch64::ARMV9A;
931     if (Feature == "+v9.1a" &&
932         ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
933       ArchInfo = &llvm::AArch64::ARMV9_1A;
934     if (Feature == "+v9.2a" &&
935         ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
936       ArchInfo = &llvm::AArch64::ARMV9_2A;
937     if (Feature == "+v9.3a" &&
938         ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
939       ArchInfo = &llvm::AArch64::ARMV9_3A;
940     if (Feature == "+v9.4a" &&
941         ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
942       ArchInfo = &llvm::AArch64::ARMV9_4A;
943     if (Feature == "+v9.5a" &&
944         ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
945       ArchInfo = &llvm::AArch64::ARMV9_5A;
946     if (Feature == "+v8r")
947       ArchInfo = &llvm::AArch64::ARMV8R;
948     if (Feature == "+fullfp16") {
949       FPU |= NeonMode;
950       HasFullFP16 = true;
951     }
952     if (Feature == "+dotprod") {
953       FPU |= NeonMode;
954       HasDotProd = true;
955     }
956     if (Feature == "+fp16fml") {
957       FPU |= NeonMode;
958       HasFullFP16 = true;
959       HasFP16FML = true;
960     }
961     if (Feature == "+mte")
962       HasMTE = true;
963     if (Feature == "+tme")
964       HasTME = true;
965     if (Feature == "+pauth")
966       HasPAuth = true;
967     if (Feature == "+i8mm")
968       HasMatMul = true;
969     if (Feature == "+bf16")
970       HasBFloat16 = true;
971     if (Feature == "+lse")
972       HasLSE = true;
973     if (Feature == "+ls64")
974       HasLS64 = true;
975     if (Feature == "+rand")
976       HasRandGen = true;
977     if (Feature == "+flagm")
978       HasFlagM = true;
979     if (Feature == "+altnzcv") {
980       HasFlagM = true;
981       HasAlternativeNZCV = true;
982     }
983     if (Feature == "+mops")
984       HasMOPS = true;
985     if (Feature == "+d128")
986       HasD128 = true;
987     if (Feature == "+gcs")
988       HasGCS = true;
989     if (Feature == "+rcpc3")
990       HasRCPC3 = true;
991   }
992 
993   // Check features that are manually disabled by command line options.
994   // This needs to be checked after architecture-related features are handled,
995   // making sure they are properly disabled when required.
996   for (const auto &Feature : Features) {
997     if (Feature == "-d128")
998       HasD128 = false;
999   }
1000 
1001   setDataLayout();
1002   setArchFeatures();
1003 
1004   if (HasNoFP) {
1005     FPU &= ~FPUMode;
1006     FPU &= ~NeonMode;
1007     FPU &= ~SveMode;
1008   }
1009   if (HasNoNeon) {
1010     FPU &= ~NeonMode;
1011     FPU &= ~SveMode;
1012   }
1013   if (HasNoSVE)
1014     FPU &= ~SveMode;
1015 
1016   return true;
1017 }
1018 
1019 bool AArch64TargetInfo::initFeatureMap(
1020     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1021     const std::vector<std::string> &FeaturesVec) const {
1022   std::vector<std::string> UpdatedFeaturesVec;
1023   // Parse the CPU and add any implied features.
1024   std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
1025   if (CpuInfo) {
1026     auto Exts = CpuInfo->getImpliedExtensions();
1027     std::vector<StringRef> CPUFeats;
1028     llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
1029     for (auto F : CPUFeats) {
1030       assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!");
1031       UpdatedFeaturesVec.push_back(F.str());
1032     }
1033   }
1034 
1035   // Process target and dependent features. This is done in two loops collecting
1036   // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1037   // add target '+/-'features that can later disable some of features added on
1038   // the first loop. Function Multi Versioning features begin with '?'.
1039   for (const auto &Feature : FeaturesVec)
1040     if (((Feature[0] == '?' || Feature[0] == '+')) &&
1041         AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) {
1042       StringRef DepFeatures =
1043           AArch64TargetInfo::getFeatureDependencies(Feature.substr(1));
1044       SmallVector<StringRef, 1> AttrFeatures;
1045       DepFeatures.split(AttrFeatures, ",");
1046       for (auto F : AttrFeatures)
1047         UpdatedFeaturesVec.push_back(F.str());
1048     }
1049   for (const auto &Feature : FeaturesVec)
1050     if (Feature[0] != '?') {
1051       std::string UpdatedFeature = Feature;
1052       if (Feature[0] == '+') {
1053         std::optional<llvm::AArch64::ExtensionInfo> Extension =
1054           llvm::AArch64::parseArchExtension(Feature.substr(1));
1055         if (Extension)
1056           UpdatedFeature = Extension->Feature.str();
1057       }
1058       UpdatedFeaturesVec.push_back(UpdatedFeature);
1059     }
1060 
1061   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
1062 }
1063 
1064 // Parse AArch64 Target attributes, which are a comma separated list of:
1065 //  "arch=<arch>" - parsed to features as per -march=..
1066 //  "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1067 //  "tune=<cpu>" - TuneCPU set to <cpu>
1068 //  "feature", "no-feature" - Add (or remove) feature.
1069 //  "+feature", "+nofeature" - Add (or remove) feature.
1070 ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1071   ParsedTargetAttr Ret;
1072   if (Features == "default")
1073     return Ret;
1074   SmallVector<StringRef, 1> AttrFeatures;
1075   Features.split(AttrFeatures, ",");
1076   bool FoundArch = false;
1077 
1078   auto SplitAndAddFeatures = [](StringRef FeatString,
1079                                 std::vector<std::string> &Features) {
1080     SmallVector<StringRef, 8> SplitFeatures;
1081     FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1082     for (StringRef Feature : SplitFeatures) {
1083       StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1084       if (!FeatureName.empty())
1085         Features.push_back(FeatureName.str());
1086       else
1087         // Pushing the original feature string to give a sema error later on
1088         // when they get checked.
1089         if (Feature.starts_with("no"))
1090           Features.push_back("-" + Feature.drop_front(2).str());
1091         else
1092           Features.push_back("+" + Feature.str());
1093     }
1094   };
1095 
1096   for (auto &Feature : AttrFeatures) {
1097     Feature = Feature.trim();
1098     if (Feature.starts_with("fpmath="))
1099       continue;
1100 
1101     if (Feature.starts_with("branch-protection=")) {
1102       Ret.BranchProtection = Feature.split('=').second.trim();
1103       continue;
1104     }
1105 
1106     if (Feature.starts_with("arch=")) {
1107       if (FoundArch)
1108         Ret.Duplicate = "arch=";
1109       FoundArch = true;
1110       std::pair<StringRef, StringRef> Split =
1111           Feature.split("=").second.trim().split("+");
1112       const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1113 
1114       // Parse the architecture version, adding the required features to
1115       // Ret.Features.
1116       if (!AI)
1117         continue;
1118       Ret.Features.push_back(AI->ArchFeature.str());
1119       // Add any extra features, after the +
1120       SplitAndAddFeatures(Split.second, Ret.Features);
1121     } else if (Feature.starts_with("cpu=")) {
1122       if (!Ret.CPU.empty())
1123         Ret.Duplicate = "cpu=";
1124       else {
1125         // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1126         // "+feat" features.
1127         std::pair<StringRef, StringRef> Split =
1128             Feature.split("=").second.trim().split("+");
1129         Ret.CPU = Split.first;
1130         SplitAndAddFeatures(Split.second, Ret.Features);
1131       }
1132     } else if (Feature.starts_with("tune=")) {
1133       if (!Ret.Tune.empty())
1134         Ret.Duplicate = "tune=";
1135       else
1136         Ret.Tune = Feature.split("=").second.trim();
1137     } else if (Feature.starts_with("+")) {
1138       SplitAndAddFeatures(Feature, Ret.Features);
1139     } else if (Feature.starts_with("no-")) {
1140       StringRef FeatureName =
1141           llvm::AArch64::getArchExtFeature(Feature.split("-").second);
1142       if (!FeatureName.empty())
1143         Ret.Features.push_back("-" + FeatureName.drop_front(1).str());
1144       else
1145         Ret.Features.push_back("-" + Feature.split("-").second.str());
1146     } else {
1147       // Try parsing the string to the internal target feature name. If it is
1148       // invalid, add the original string (which could already be an internal
1149       // name). These should be checked later by isValidFeatureName.
1150       StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1151       if (!FeatureName.empty())
1152         Ret.Features.push_back(FeatureName.str());
1153       else
1154         Ret.Features.push_back("+" + Feature.str());
1155     }
1156   }
1157   return Ret;
1158 }
1159 
1160 bool AArch64TargetInfo::hasBFloat16Type() const {
1161   return true;
1162 }
1163 
1164 TargetInfo::CallingConvCheckResult
1165 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
1166   switch (CC) {
1167   case CC_C:
1168   case CC_Swift:
1169   case CC_SwiftAsync:
1170   case CC_PreserveMost:
1171   case CC_PreserveAll:
1172   case CC_OpenCLKernel:
1173   case CC_AArch64VectorCall:
1174   case CC_AArch64SVEPCS:
1175   case CC_Win64:
1176     return CCCR_OK;
1177   default:
1178     return CCCR_Warning;
1179   }
1180 }
1181 
1182 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1183 
1184 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1185   return TargetInfo::AArch64ABIBuiltinVaList;
1186 }
1187 
1188 const char *const AArch64TargetInfo::GCCRegNames[] = {
1189     // clang-format off
1190 
1191     // 32-bit Integer registers
1192     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1193     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1194     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1195 
1196     // 64-bit Integer registers
1197     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1198     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1199     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1200 
1201     // 32-bit floating point regsisters
1202     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1203     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1204     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1205 
1206     // 64-bit floating point regsisters
1207     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1208     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1209     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1210 
1211     // Neon vector registers
1212     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1213     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1214     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1215 
1216     // SVE vector registers
1217     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
1218     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1219     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1220 
1221     // SVE predicate registers
1222     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
1223     "p11", "p12", "p13", "p14", "p15",
1224 
1225     // SVE predicate-as-counter registers
1226     "pn0",  "pn1",  "pn2",  "pn3",  "pn4",  "pn5",  "pn6",  "pn7",  "pn8",
1227     "pn9",  "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
1228 
1229     // SME registers
1230     "za", "zt0",
1231 
1232     // clang-format on
1233 };
1234 
1235 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1236   return llvm::ArrayRef(GCCRegNames);
1237 }
1238 
1239 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1240     {{"w31"}, "wsp"},
1241     {{"x31"}, "sp"},
1242     // GCC rN registers are aliases of xN registers.
1243     {{"r0"}, "x0"},
1244     {{"r1"}, "x1"},
1245     {{"r2"}, "x2"},
1246     {{"r3"}, "x3"},
1247     {{"r4"}, "x4"},
1248     {{"r5"}, "x5"},
1249     {{"r6"}, "x6"},
1250     {{"r7"}, "x7"},
1251     {{"r8"}, "x8"},
1252     {{"r9"}, "x9"},
1253     {{"r10"}, "x10"},
1254     {{"r11"}, "x11"},
1255     {{"r12"}, "x12"},
1256     {{"r13"}, "x13"},
1257     {{"r14"}, "x14"},
1258     {{"r15"}, "x15"},
1259     {{"r16"}, "x16"},
1260     {{"r17"}, "x17"},
1261     {{"r18"}, "x18"},
1262     {{"r19"}, "x19"},
1263     {{"r20"}, "x20"},
1264     {{"r21"}, "x21"},
1265     {{"r22"}, "x22"},
1266     {{"r23"}, "x23"},
1267     {{"r24"}, "x24"},
1268     {{"r25"}, "x25"},
1269     {{"r26"}, "x26"},
1270     {{"r27"}, "x27"},
1271     {{"r28"}, "x28"},
1272     {{"r29", "x29"}, "fp"},
1273     {{"r30", "x30"}, "lr"},
1274     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1275     // don't want to substitute one of these for a different-sized one.
1276 };
1277 
1278 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1279   return llvm::ArrayRef(GCCRegAliases);
1280 }
1281 
1282 // Returns the length of cc constraint.
1283 static unsigned matchAsmCCConstraint(const char *Name) {
1284   constexpr unsigned len = 5;
1285   auto RV = llvm::StringSwitch<unsigned>(Name)
1286                 .Case("@cceq", len)
1287                 .Case("@ccne", len)
1288                 .Case("@cchs", len)
1289                 .Case("@cccs", len)
1290                 .Case("@cccc", len)
1291                 .Case("@cclo", len)
1292                 .Case("@ccmi", len)
1293                 .Case("@ccpl", len)
1294                 .Case("@ccvs", len)
1295                 .Case("@ccvc", len)
1296                 .Case("@cchi", len)
1297                 .Case("@ccls", len)
1298                 .Case("@ccge", len)
1299                 .Case("@cclt", len)
1300                 .Case("@ccgt", len)
1301                 .Case("@ccle", len)
1302                 .Default(0);
1303   return RV;
1304 }
1305 
1306 std::string
1307 AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
1308   std::string R;
1309   switch (*Constraint) {
1310   case 'U': // Three-character constraint; add "@3" hint for later parsing.
1311     R = std::string("@3") + std::string(Constraint, 3);
1312     Constraint += 2;
1313     break;
1314   case '@':
1315     if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
1316       std::string Converted = "{" + std::string(Constraint, Len) + "}";
1317       Constraint += Len - 1;
1318       return Converted;
1319     }
1320     return std::string(1, *Constraint);
1321   default:
1322     R = TargetInfo::convertConstraint(Constraint);
1323     break;
1324   }
1325   return R;
1326 }
1327 
1328 bool AArch64TargetInfo::validateAsmConstraint(
1329     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1330   switch (*Name) {
1331   default:
1332     return false;
1333   case 'w': // Floating point and SIMD registers (V0-V31)
1334     Info.setAllowsRegister();
1335     return true;
1336   case 'I': // Constant that can be used with an ADD instruction
1337   case 'J': // Constant that can be used with a SUB instruction
1338   case 'K': // Constant that can be used with a 32-bit logical instruction
1339   case 'L': // Constant that can be used with a 64-bit logical instruction
1340   case 'M': // Constant that can be used as a 32-bit MOV immediate
1341   case 'N': // Constant that can be used as a 64-bit MOV immediate
1342   case 'Y': // Floating point constant zero
1343   case 'Z': // Integer constant zero
1344     return true;
1345   case 'Q': // A memory reference with base register and no offset
1346     Info.setAllowsMemory();
1347     return true;
1348   case 'S': // A symbolic address
1349     Info.setAllowsRegister();
1350     return true;
1351   case 'U':
1352     if (Name[1] == 'p' &&
1353         (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
1354       // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
1355       Info.setAllowsRegister();
1356       Name += 2;
1357       return true;
1358     }
1359     if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
1360       // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
1361       Info.setAllowsRegister();
1362       Name += 2;
1363       return true;
1364     }
1365     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1366     // Utf: A memory address suitable for ldp/stp in TF mode.
1367     // Usa: An absolute symbolic address.
1368     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1369 
1370     // Better to return an error saying that it's an unrecognised constraint
1371     // even if this is a valid constraint in gcc.
1372     return false;
1373   case 'z': // Zero register, wzr or xzr
1374     Info.setAllowsRegister();
1375     return true;
1376   case 'x': // Floating point and SIMD registers (V0-V15)
1377     Info.setAllowsRegister();
1378     return true;
1379   case 'y': // SVE registers (V0-V7)
1380     Info.setAllowsRegister();
1381     return true;
1382   case '@':
1383     // CC condition
1384     if (const unsigned Len = matchAsmCCConstraint(Name)) {
1385       Name += Len - 1;
1386       Info.setAllowsRegister();
1387       return true;
1388     }
1389   }
1390   return false;
1391 }
1392 
1393 bool AArch64TargetInfo::validateConstraintModifier(
1394     StringRef Constraint, char Modifier, unsigned Size,
1395     std::string &SuggestedModifier) const {
1396   // Strip off constraint modifiers.
1397   Constraint = Constraint.ltrim("=+&");
1398 
1399   switch (Constraint[0]) {
1400   default:
1401     return true;
1402   case 'z':
1403   case 'r': {
1404     switch (Modifier) {
1405     case 'x':
1406     case 'w':
1407       // For now assume that the person knows what they're
1408       // doing with the modifier.
1409       return true;
1410     default:
1411       // By default an 'r' constraint will be in the 'x'
1412       // registers.
1413       if (Size == 64)
1414         return true;
1415 
1416       if (Size == 512)
1417         return HasLS64;
1418 
1419       SuggestedModifier = "w";
1420       return false;
1421     }
1422   }
1423   }
1424 }
1425 
1426 std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1427 
1428 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1429   if (RegNo == 0)
1430     return 0;
1431   if (RegNo == 1)
1432     return 1;
1433   return -1;
1434 }
1435 
1436 bool AArch64TargetInfo::hasInt128Type() const { return true; }
1437 
1438 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1439                                          const TargetOptions &Opts)
1440     : AArch64TargetInfo(Triple, Opts) {}
1441 
1442 void AArch64leTargetInfo::setDataLayout() {
1443   if (getTriple().isOSBinFormatMachO()) {
1444     if(getTriple().isArch32Bit())
1445       resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_");
1446     else
1447       resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_");
1448   } else
1449     resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1450 }
1451 
1452 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1453                                            MacroBuilder &Builder) const {
1454   Builder.defineMacro("__AARCH64EL__");
1455   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1456 }
1457 
1458 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1459                                          const TargetOptions &Opts)
1460     : AArch64TargetInfo(Triple, Opts) {}
1461 
1462 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
1463                                            MacroBuilder &Builder) const {
1464   Builder.defineMacro("__AARCH64EB__");
1465   Builder.defineMacro("__AARCH_BIG_ENDIAN");
1466   Builder.defineMacro("__ARM_BIG_ENDIAN");
1467   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1468 }
1469 
1470 void AArch64beTargetInfo::setDataLayout() {
1471   assert(!getTriple().isOSBinFormatMachO());
1472   resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1473 }
1474 
1475 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
1476                                                const TargetOptions &Opts)
1477     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1478 
1479   // This is an LLP64 platform.
1480   // int:4, long:4, long long:8, long double:8.
1481   IntWidth = IntAlign = 32;
1482   LongWidth = LongAlign = 32;
1483   DoubleAlign = LongLongAlign = 64;
1484   LongDoubleWidth = LongDoubleAlign = 64;
1485   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1486   IntMaxType = SignedLongLong;
1487   Int64Type = SignedLongLong;
1488   SizeType = UnsignedLongLong;
1489   PtrDiffType = SignedLongLong;
1490   IntPtrType = SignedLongLong;
1491 }
1492 
1493 void WindowsARM64TargetInfo::setDataLayout() {
1494   resetDataLayout(Triple.isOSBinFormatMachO()
1495                       ? "e-m:o-i64:64-i128:128-n32:64-S128"
1496                       : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128",
1497                   Triple.isOSBinFormatMachO() ? "_" : "");
1498 }
1499 
1500 TargetInfo::BuiltinVaListKind
1501 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1502   return TargetInfo::CharPtrBuiltinVaList;
1503 }
1504 
1505 TargetInfo::CallingConvCheckResult
1506 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
1507   switch (CC) {
1508   case CC_X86StdCall:
1509   case CC_X86ThisCall:
1510   case CC_X86FastCall:
1511   case CC_X86VectorCall:
1512     return CCCR_Ignore;
1513   case CC_C:
1514   case CC_OpenCLKernel:
1515   case CC_PreserveMost:
1516   case CC_PreserveAll:
1517   case CC_Swift:
1518   case CC_SwiftAsync:
1519   case CC_Win64:
1520     return CCCR_OK;
1521   default:
1522     return CCCR_Warning;
1523   }
1524 }
1525 
1526 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1527                                                    const TargetOptions &Opts)
1528     : WindowsARM64TargetInfo(Triple, Opts) {
1529   TheCXXABI.set(TargetCXXABI::Microsoft);
1530 }
1531 
1532 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
1533                                                 MacroBuilder &Builder) const {
1534   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
1535   if (getTriple().isWindowsArm64EC()) {
1536     Builder.defineMacro("_M_X64", "100");
1537     Builder.defineMacro("_M_AMD64", "100");
1538     Builder.defineMacro("_M_ARM64EC", "1");
1539   } else {
1540     Builder.defineMacro("_M_ARM64", "1");
1541   }
1542 }
1543 
1544 TargetInfo::CallingConvKind
1545 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1546   return CCK_MicrosoftWin64;
1547 }
1548 
1549 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
1550   unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
1551 
1552   // MSVC does size based alignment for arm64 based on alignment section in
1553   // below document, replicate that to keep alignment consistent with object
1554   // files compiled by MSVC.
1555   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
1556   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
1557     Align = std::max(Align, 128u);    // align type at least 16 bytes
1558   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
1559     Align = std::max(Align, 64u);     // align type at least 8 butes
1560   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
1561     Align = std::max(Align, 32u);     // align type at least 4 bytes
1562   }
1563   return Align;
1564 }
1565 
1566 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1567                                            const TargetOptions &Opts)
1568     : WindowsARM64TargetInfo(Triple, Opts) {
1569   TheCXXABI.set(TargetCXXABI::GenericAArch64);
1570 }
1571 
1572 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1573                                                  const TargetOptions &Opts)
1574     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1575   Int64Type = SignedLongLong;
1576   if (getTriple().isArch32Bit())
1577     IntMaxType = SignedLongLong;
1578 
1579   WCharType = SignedInt;
1580   UseSignedCharForObjCBool = false;
1581 
1582   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1583   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1584 
1585   UseZeroLengthBitfieldAlignment = false;
1586 
1587   if (getTriple().isArch32Bit()) {
1588     UseBitFieldTypeAlignment = false;
1589     ZeroLengthBitfieldBoundary = 32;
1590     UseZeroLengthBitfieldAlignment = true;
1591     TheCXXABI.set(TargetCXXABI::WatchOS);
1592   } else
1593     TheCXXABI.set(TargetCXXABI::AppleARM64);
1594 }
1595 
1596 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1597                                            const llvm::Triple &Triple,
1598                                            MacroBuilder &Builder) const {
1599   Builder.defineMacro("__AARCH64_SIMD__");
1600   if (Triple.isArch32Bit())
1601     Builder.defineMacro("__ARM64_ARCH_8_32__");
1602   else
1603     Builder.defineMacro("__ARM64_ARCH_8__");
1604   Builder.defineMacro("__ARM_NEON__");
1605   Builder.defineMacro("__REGISTER_PREFIX__", "");
1606   Builder.defineMacro("__arm64", "1");
1607   Builder.defineMacro("__arm64__", "1");
1608 
1609   if (Triple.isArm64e())
1610     Builder.defineMacro("__arm64e__", "1");
1611 
1612   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1613 }
1614 
1615 TargetInfo::BuiltinVaListKind
1616 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1617   return TargetInfo::CharPtrBuiltinVaList;
1618 }
1619 
1620 // 64-bit RenderScript is aarch64
1621 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
1622                                                    const TargetOptions &Opts)
1623     : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
1624                                        Triple.getOSName(),
1625                                        Triple.getEnvironmentName()),
1626                           Opts) {
1627   IsRenderScriptTarget = true;
1628 }
1629 
1630 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
1631                                                 MacroBuilder &Builder) const {
1632   Builder.defineMacro("__RENDERSCRIPT__");
1633   AArch64leTargetInfo::getTargetDefines(Opts, Builder);
1634 }
1635