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