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
24using namespace clang;
25using namespace clang::targets;
26
27static 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
57void 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
130AArch64TargetInfo::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
199StringRef AArch64TargetInfo::getABI() const { return ABI; }
200
201bool AArch64TargetInfo::setABI(const std::string &Name) {
202  if (Name != "aapcs" && Name != "darwinpcs")
203    return false;
204
205  ABI = Name;
206  return true;
207}
208
209bool 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
233bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
234  return Name == "generic" || llvm::AArch64::parseCpu(Name);
235}
236
237bool AArch64TargetInfo::setCPU(const std::string &Name) {
238  return isValidCPUName(Name);
239}
240
241void AArch64TargetInfo::fillValidCPUList(
242    SmallVectorImpl<StringRef> &Values) const {
243  llvm::AArch64::fillValidCPUArchList(Values);
244}
245
246void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
247                                                MacroBuilder &Builder) const {
248  Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
249}
250
251void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
252                                                MacroBuilder &Builder) const {
253  // Also include the ARMv8.1 defines
254  getTargetDefinesARMV81A(Opts, Builder);
255}
256
257void 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
265void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
266                                                MacroBuilder &Builder) const {
267  // Also include the Armv8.3 defines
268  getTargetDefinesARMV83A(Opts, Builder);
269}
270
271void 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
279void 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
289void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
290                                                MacroBuilder &Builder) const {
291  // Also include the Armv8.6 defines
292  getTargetDefinesARMV86A(Opts, Builder);
293}
294
295void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
296                                                MacroBuilder &Builder) const {
297  // Also include the Armv8.7 defines
298  getTargetDefinesARMV87A(Opts, Builder);
299}
300
301void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
302                                                MacroBuilder &Builder) const {
303  // Also include the Armv8.8 defines
304  getTargetDefinesARMV88A(Opts, Builder);
305}
306
307void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
308                                               MacroBuilder &Builder) const {
309  // Armv9-A maps to Armv8.5-A
310  getTargetDefinesARMV85A(Opts, Builder);
311}
312
313void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
314                                                MacroBuilder &Builder) const {
315  // Armv9.1-A maps to Armv8.6-A
316  getTargetDefinesARMV86A(Opts, Builder);
317}
318
319void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
320                                                MacroBuilder &Builder) const {
321  // Armv9.2-A maps to Armv8.7-A
322  getTargetDefinesARMV87A(Opts, Builder);
323}
324
325void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
326                                                MacroBuilder &Builder) const {
327  // Armv9.3-A maps to Armv8.8-A
328  getTargetDefinesARMV88A(Opts, Builder);
329}
330
331void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
332                                                MacroBuilder &Builder) const {
333  // Armv9.4-A maps to Armv8.9-A
334  getTargetDefinesARMV89A(Opts, Builder);
335}
336
337void 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
343void 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
620ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
621  return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
622                                         Builtin::FirstTSBuiltin);
623}
624
625std::optional<std::pair<unsigned, unsigned>>
626AArch64TargetInfo::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
637unsigned 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
645unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
646  // Take the maximum priority as per feature cost, so more features win.
647  return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
648}
649
650bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
651  if (auto Ext = llvm::AArch64::parseArchExtension(Name))
652    return !Ext->DependentFeatures.empty();
653  return false;
654}
655
656StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
657  if (auto Ext = llvm::AArch64::parseArchExtension(Name))
658    return Ext->DependentFeatures;
659  return StringRef();
660}
661
662bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
663  return llvm::AArch64::parseArchExtension(FeatureStr).has_value();
664}
665
666bool 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
719void 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
748bool 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
1019bool 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.
1070ParsedTargetAttr 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
1160bool AArch64TargetInfo::hasBFloat16Type() const {
1161  return true;
1162}
1163
1164TargetInfo::CallingConvCheckResult
1165AArch64TargetInfo::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
1182bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1183
1184TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1185  return TargetInfo::AArch64ABIBuiltinVaList;
1186}
1187
1188const 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
1235ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1236  return llvm::ArrayRef(GCCRegNames);
1237}
1238
1239const 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
1278ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1279  return llvm::ArrayRef(GCCRegAliases);
1280}
1281
1282// Returns the length of cc constraint.
1283static 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
1306std::string
1307AArch64TargetInfo::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
1328bool 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
1393bool 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
1426std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1427
1428int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1429  if (RegNo == 0)
1430    return 0;
1431  if (RegNo == 1)
1432    return 1;
1433  return -1;
1434}
1435
1436bool AArch64TargetInfo::hasInt128Type() const { return true; }
1437
1438AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1439                                         const TargetOptions &Opts)
1440    : AArch64TargetInfo(Triple, Opts) {}
1441
1442void 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
1452void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1453                                           MacroBuilder &Builder) const {
1454  Builder.defineMacro("__AARCH64EL__");
1455  AArch64TargetInfo::getTargetDefines(Opts, Builder);
1456}
1457
1458AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1459                                         const TargetOptions &Opts)
1460    : AArch64TargetInfo(Triple, Opts) {}
1461
1462void 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
1470void 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
1475WindowsARM64TargetInfo::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
1493void 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
1500TargetInfo::BuiltinVaListKind
1501WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1502  return TargetInfo::CharPtrBuiltinVaList;
1503}
1504
1505TargetInfo::CallingConvCheckResult
1506WindowsARM64TargetInfo::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
1526MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1527                                                   const TargetOptions &Opts)
1528    : WindowsARM64TargetInfo(Triple, Opts) {
1529  TheCXXABI.set(TargetCXXABI::Microsoft);
1530}
1531
1532void 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
1544TargetInfo::CallingConvKind
1545MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1546  return CCK_MicrosoftWin64;
1547}
1548
1549unsigned 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
1566MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1567                                           const TargetOptions &Opts)
1568    : WindowsARM64TargetInfo(Triple, Opts) {
1569  TheCXXABI.set(TargetCXXABI::GenericAArch64);
1570}
1571
1572DarwinAArch64TargetInfo::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
1596void 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
1615TargetInfo::BuiltinVaListKind
1616DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1617  return TargetInfo::CharPtrBuiltinVaList;
1618}
1619
1620// 64-bit RenderScript is aarch64
1621RenderScript64TargetInfo::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
1630void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
1631                                                MacroBuilder &Builder) const {
1632  Builder.defineMacro("__RENDERSCRIPT__");
1633  AArch64leTargetInfo::getTargetDefines(Opts, Builder);
1634}
1635