xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
10b57cec5SDimitry Andric //===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements AArch64 TargetInfo objects.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "AArch64.h"
140fca6ea1SDimitry Andric #include "clang/Basic/Diagnostic.h"
155ffd83dbSDimitry Andric #include "clang/Basic/LangOptions.h"
160b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h"
170b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
180fca6ea1SDimitry Andric #include "llvm/ADT/APSInt.h"
190b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
21480093f4SDimitry Andric #include "llvm/ADT/StringSwitch.h"
2206c3fb27SDimitry Andric #include "llvm/TargetParser/AArch64TargetParser.h"
2306c3fb27SDimitry Andric #include "llvm/TargetParser/ARMTargetParserCommon.h"
24bdd1243dSDimitry Andric #include <optional>
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace clang;
270b57cec5SDimitry Andric using namespace clang::targets;
280b57cec5SDimitry Andric 
29bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfo[] = {
300b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
31bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
32bdd1243dSDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
33bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
340b57cec5SDimitry Andric #include "clang/Basic/BuiltinsNEON.def"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
37bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
38bdd1243dSDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
39bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
405ffd83dbSDimitry Andric #include "clang/Basic/BuiltinsSVE.def"
415ffd83dbSDimitry Andric 
425ffd83dbSDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
43bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
4406c3fb27SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
4506c3fb27SDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
4606c3fb27SDimitry Andric #include "clang/Basic/BuiltinsSME.def"
4706c3fb27SDimitry Andric 
4806c3fb27SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)                                               \
4906c3fb27SDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
500b57cec5SDimitry Andric #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
51bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
528792c038SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
53bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
540b57cec5SDimitry Andric #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
55bdd1243dSDimitry Andric   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
560b57cec5SDimitry Andric #include "clang/Basic/BuiltinsAArch64.def"
570b57cec5SDimitry Andric };
580b57cec5SDimitry Andric 
59bdd1243dSDimitry Andric void AArch64TargetInfo::setArchFeatures() {
60bdd1243dSDimitry Andric   if (*ArchInfo == llvm::AArch64::ARMV8R) {
61bdd1243dSDimitry Andric     HasDotProd = true;
62bdd1243dSDimitry Andric     HasDIT = true;
63bdd1243dSDimitry Andric     HasFlagM = true;
64bdd1243dSDimitry Andric     HasRCPC = true;
65bdd1243dSDimitry Andric     FPU |= NeonMode;
66bdd1243dSDimitry Andric     HasCCPP = true;
67bdd1243dSDimitry Andric     HasCRC = true;
68bdd1243dSDimitry Andric     HasLSE = true;
69bdd1243dSDimitry Andric     HasRDM = true;
70bdd1243dSDimitry Andric   } else if (ArchInfo->Version.getMajor() == 8) {
71bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 7u) {
72bdd1243dSDimitry Andric       HasWFxT = true;
73349cc55cSDimitry Andric     }
74bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 6u) {
75bdd1243dSDimitry Andric       HasBFloat16 = true;
76bdd1243dSDimitry Andric       HasMatMul = true;
77349cc55cSDimitry Andric     }
78bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 5u) {
79bdd1243dSDimitry Andric       HasAlternativeNZCV = true;
80bdd1243dSDimitry Andric       HasFRInt3264 = true;
81bdd1243dSDimitry Andric       HasSSBS = true;
82bdd1243dSDimitry Andric       HasSB = true;
83bdd1243dSDimitry Andric       HasPredRes = true;
84bdd1243dSDimitry Andric       HasBTI = true;
85bdd1243dSDimitry Andric     }
86bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 4u) {
87bdd1243dSDimitry Andric       HasDotProd = true;
88bdd1243dSDimitry Andric       HasDIT = true;
89bdd1243dSDimitry Andric       HasFlagM = true;
90bdd1243dSDimitry Andric     }
91bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 3u) {
92bdd1243dSDimitry Andric       HasRCPC = true;
93bdd1243dSDimitry Andric       FPU |= NeonMode;
94bdd1243dSDimitry Andric     }
95bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 2u) {
96bdd1243dSDimitry Andric       HasCCPP = true;
97bdd1243dSDimitry Andric     }
98bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 1u) {
99bdd1243dSDimitry Andric       HasCRC = true;
100bdd1243dSDimitry Andric       HasLSE = true;
101bdd1243dSDimitry Andric       HasRDM = true;
102bdd1243dSDimitry Andric     }
103bdd1243dSDimitry Andric   } else if (ArchInfo->Version.getMajor() == 9) {
104bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 2u) {
105bdd1243dSDimitry Andric       HasWFxT = true;
106bdd1243dSDimitry Andric     }
107bdd1243dSDimitry Andric     if (ArchInfo->Version.getMinor() >= 1u) {
108bdd1243dSDimitry Andric       HasBFloat16 = true;
109bdd1243dSDimitry Andric       HasMatMul = true;
110bdd1243dSDimitry Andric     }
111bdd1243dSDimitry Andric     FPU |= SveMode;
112bdd1243dSDimitry Andric     HasSVE2 = true;
113bdd1243dSDimitry Andric     HasFullFP16 = true;
114bdd1243dSDimitry Andric     HasAlternativeNZCV = true;
115bdd1243dSDimitry Andric     HasFRInt3264 = true;
116bdd1243dSDimitry Andric     HasSSBS = true;
117bdd1243dSDimitry Andric     HasSB = true;
118bdd1243dSDimitry Andric     HasPredRes = true;
119bdd1243dSDimitry Andric     HasBTI = true;
120bdd1243dSDimitry Andric     HasDotProd = true;
121bdd1243dSDimitry Andric     HasDIT = true;
122bdd1243dSDimitry Andric     HasFlagM = true;
123bdd1243dSDimitry Andric     HasRCPC = true;
124bdd1243dSDimitry Andric     FPU |= NeonMode;
125bdd1243dSDimitry Andric     HasCCPP = true;
126bdd1243dSDimitry Andric     HasCRC = true;
127bdd1243dSDimitry Andric     HasLSE = true;
128bdd1243dSDimitry Andric     HasRDM = true;
129349cc55cSDimitry Andric   }
130349cc55cSDimitry Andric }
131349cc55cSDimitry Andric 
1320b57cec5SDimitry Andric AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
1330b57cec5SDimitry Andric                                      const TargetOptions &Opts)
1340b57cec5SDimitry Andric     : TargetInfo(Triple), ABI("aapcs") {
1350b57cec5SDimitry Andric   if (getTriple().isOSOpenBSD()) {
1360b57cec5SDimitry Andric     Int64Type = SignedLongLong;
1370b57cec5SDimitry Andric     IntMaxType = SignedLongLong;
1380b57cec5SDimitry Andric   } else {
1390b57cec5SDimitry Andric     if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
1400b57cec5SDimitry Andric       WCharType = UnsignedInt;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric     Int64Type = SignedLong;
1430b57cec5SDimitry Andric     IntMaxType = SignedLong;
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
1470b57cec5SDimitry Andric   HasLegalHalfType = true;
148bdd1243dSDimitry Andric   HalfArgsAndReturns = true;
1490b57cec5SDimitry Andric   HasFloat16 = true;
150bdd1243dSDimitry Andric   HasStrictFP = true;
1510b57cec5SDimitry Andric 
152480093f4SDimitry Andric   if (Triple.isArch64Bit())
1530b57cec5SDimitry Andric     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
154480093f4SDimitry Andric   else
155480093f4SDimitry Andric     LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
156480093f4SDimitry Andric 
1570fca6ea1SDimitry Andric   BitIntMaxAlign = 128;
1580b57cec5SDimitry Andric   MaxVectorAlign = 128;
1590b57cec5SDimitry Andric   MaxAtomicInlineWidth = 128;
1600b57cec5SDimitry Andric   MaxAtomicPromoteWidth = 128;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
1630b57cec5SDimitry Andric   LongDoubleFormat = &llvm::APFloat::IEEEquad();
1640b57cec5SDimitry Andric 
1655ffd83dbSDimitry Andric   BFloat16Width = BFloat16Align = 16;
1665ffd83dbSDimitry Andric   BFloat16Format = &llvm::APFloat::BFloat();
1675ffd83dbSDimitry Andric 
1680b57cec5SDimitry Andric   // Make __builtin_ms_va_list available.
1690b57cec5SDimitry Andric   HasBuiltinMSVaList = true;
1700b57cec5SDimitry Andric 
171a7dea167SDimitry Andric   // Make the SVE types available.  Note that this deliberately doesn't
172a7dea167SDimitry Andric   // depend on SveMode, since in principle it should be possible to turn
173a7dea167SDimitry Andric   // SVE on and off within a translation unit.  It should also be possible
174a7dea167SDimitry Andric   // to compile the global declaration:
175a7dea167SDimitry Andric   //
176a7dea167SDimitry Andric   // __SVInt8_t *ptr;
177a7dea167SDimitry Andric   //
178a7dea167SDimitry Andric   // even without SVE.
179a7dea167SDimitry Andric   HasAArch64SVETypes = true;
180a7dea167SDimitry Andric 
1810b57cec5SDimitry Andric   // {} in inline assembly are neon specifiers, not assembly variant
1820b57cec5SDimitry Andric   // specifiers.
1830b57cec5SDimitry Andric   NoAsmVariants = true;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
1860b57cec5SDimitry Andric   // contributes to the alignment of the containing aggregate in the same way
1870b57cec5SDimitry Andric   // a plain (non bit-field) member of that type would, without exception for
1880b57cec5SDimitry Andric   // zero-sized or anonymous bit-fields."
1890b57cec5SDimitry Andric   assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
1900b57cec5SDimitry Andric   UseZeroLengthBitfieldAlignment = true;
1910b57cec5SDimitry Andric 
1920fca6ea1SDimitry Andric   HasUnalignedAccess = true;
1930fca6ea1SDimitry Andric 
1940b57cec5SDimitry Andric   // AArch64 targets default to using the ARM C++ ABI.
1950b57cec5SDimitry Andric   TheCXXABI.set(TargetCXXABI::GenericAArch64);
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   if (Triple.getOS() == llvm::Triple::Linux)
1980b57cec5SDimitry Andric     this->MCountName = "\01_mcount";
1990b57cec5SDimitry Andric   else if (Triple.getOS() == llvm::Triple::UnknownOS)
2000b57cec5SDimitry Andric     this->MCountName =
2010b57cec5SDimitry Andric         Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric StringRef AArch64TargetInfo::getABI() const { return ABI; }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric bool AArch64TargetInfo::setABI(const std::string &Name) {
2070fca6ea1SDimitry Andric   if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&
2080fca6ea1SDimitry Andric       Name != "pauthtest")
2090b57cec5SDimitry Andric     return false;
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   ABI = Name;
2120b57cec5SDimitry Andric   return true;
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150fca6ea1SDimitry Andric bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
2160fca6ea1SDimitry Andric   if (hasFeature("fp") && ABI == "aapcs-soft") {
2170fca6ea1SDimitry Andric     // aapcs-soft is not allowed for targets with an FPU, to avoid there being
2180fca6ea1SDimitry Andric     // two incomatible ABIs.
2190fca6ea1SDimitry Andric     Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
2200fca6ea1SDimitry Andric     return false;
2210fca6ea1SDimitry Andric   }
2220fca6ea1SDimitry Andric   if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&
2230fca6ea1SDimitry Andric       getTriple().getOS() != llvm::Triple::Linux) {
2240fca6ea1SDimitry Andric     Diags.Report(diag::err_target_unsupported_abi_for_triple)
2250fca6ea1SDimitry Andric         << getTriple().getEnvironmentName() << getTriple().getTriple();
2260fca6ea1SDimitry Andric     return false;
2270fca6ea1SDimitry Andric   }
2280fca6ea1SDimitry Andric   return true;
2290fca6ea1SDimitry Andric }
2300fca6ea1SDimitry Andric 
2310fca6ea1SDimitry Andric bool AArch64TargetInfo::validateGlobalRegisterVariable(
2320fca6ea1SDimitry Andric     StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
2330fca6ea1SDimitry Andric   if ((RegName == "sp") || RegName.starts_with("x")) {
2340fca6ea1SDimitry Andric     HasSizeMismatch = RegSize != 64;
2350fca6ea1SDimitry Andric     return true;
2360fca6ea1SDimitry Andric   } else if (RegName.starts_with("w")) {
2370fca6ea1SDimitry Andric     HasSizeMismatch = RegSize != 32;
2380fca6ea1SDimitry Andric     return true;
2390fca6ea1SDimitry Andric   }
2400fca6ea1SDimitry Andric   return false;
2410fca6ea1SDimitry Andric }
2420fca6ea1SDimitry Andric 
2431fd87a68SDimitry Andric bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
244480093f4SDimitry Andric                                                  BranchProtectionInfo &BPI,
245480093f4SDimitry Andric                                                  StringRef &Err) const {
2464824e7fdSDimitry Andric   llvm::ARM::ParsedBranchProtection PBP;
2470fca6ea1SDimitry Andric   if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
248480093f4SDimitry Andric     return false;
249480093f4SDimitry Andric 
250480093f4SDimitry Andric   BPI.SignReturnAddr =
2515ffd83dbSDimitry Andric       llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
2525ffd83dbSDimitry Andric           .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
2535ffd83dbSDimitry Andric           .Case("all", LangOptions::SignReturnAddressScopeKind::All)
2545ffd83dbSDimitry Andric           .Default(LangOptions::SignReturnAddressScopeKind::None);
255480093f4SDimitry Andric 
256480093f4SDimitry Andric   if (PBP.Key == "a_key")
2575ffd83dbSDimitry Andric     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
258480093f4SDimitry Andric   else
2595ffd83dbSDimitry Andric     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
260480093f4SDimitry Andric 
261480093f4SDimitry Andric   BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
262cb14a3feSDimitry Andric   BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
263297eecfbSDimitry Andric   BPI.GuardedControlStack = PBP.GuardedControlStack;
264480093f4SDimitry Andric   return true;
265480093f4SDimitry Andric }
266480093f4SDimitry Andric 
2670b57cec5SDimitry Andric bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
2680fca6ea1SDimitry Andric   return llvm::AArch64::parseCpu(Name).has_value();
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric bool AArch64TargetInfo::setCPU(const std::string &Name) {
2720b57cec5SDimitry Andric   return isValidCPUName(Name);
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric void AArch64TargetInfo::fillValidCPUList(
2760b57cec5SDimitry Andric     SmallVectorImpl<StringRef> &Values) const {
2770b57cec5SDimitry Andric   llvm::AArch64::fillValidCPUArchList(Values);
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
2810b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
2820b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
2860b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
2870b57cec5SDimitry Andric   // Also include the ARMv8.1 defines
2880b57cec5SDimitry Andric   getTargetDefinesARMV81A(Opts, Builder);
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
2920b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
293480093f4SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
2940b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
2950b57cec5SDimitry Andric   // Also include the Armv8.2 defines
2960b57cec5SDimitry Andric   getTargetDefinesARMV82A(Opts, Builder);
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
3000b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
3010b57cec5SDimitry Andric   // Also include the Armv8.3 defines
3020b57cec5SDimitry Andric   getTargetDefinesARMV83A(Opts, Builder);
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
3060b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
307fe6060f1SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
3080b57cec5SDimitry Andric   // Also include the Armv8.4 defines
3090b57cec5SDimitry Andric   getTargetDefinesARMV84A(Opts, Builder);
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
3125ffd83dbSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
3135ffd83dbSDimitry Andric                                                 MacroBuilder &Builder) const {
3145ffd83dbSDimitry Andric   // Also include the Armv8.5 defines
3155ffd83dbSDimitry Andric   // FIXME: Armv8.6 makes the following extensions mandatory:
3165ffd83dbSDimitry Andric   // - __ARM_FEATURE_BF16
3175ffd83dbSDimitry Andric   // - __ARM_FEATURE_MATMUL_INT8
3185ffd83dbSDimitry Andric   // Handle them here.
3195ffd83dbSDimitry Andric   getTargetDefinesARMV85A(Opts, Builder);
3205ffd83dbSDimitry Andric }
3210b57cec5SDimitry Andric 
322e8d8bef9SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
323e8d8bef9SDimitry Andric                                                 MacroBuilder &Builder) const {
324e8d8bef9SDimitry Andric   // Also include the Armv8.6 defines
325e8d8bef9SDimitry Andric   getTargetDefinesARMV86A(Opts, Builder);
326e8d8bef9SDimitry Andric }
327e8d8bef9SDimitry Andric 
32804eeddc0SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
32904eeddc0SDimitry Andric                                                 MacroBuilder &Builder) const {
33004eeddc0SDimitry Andric   // Also include the Armv8.7 defines
33104eeddc0SDimitry Andric   getTargetDefinesARMV87A(Opts, Builder);
33204eeddc0SDimitry Andric }
33304eeddc0SDimitry Andric 
334bdd1243dSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
335bdd1243dSDimitry Andric                                                 MacroBuilder &Builder) const {
336bdd1243dSDimitry Andric   // Also include the Armv8.8 defines
337bdd1243dSDimitry Andric   getTargetDefinesARMV88A(Opts, Builder);
338bdd1243dSDimitry Andric }
339bdd1243dSDimitry Andric 
340349cc55cSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
341349cc55cSDimitry Andric                                                MacroBuilder &Builder) const {
342349cc55cSDimitry Andric   // Armv9-A maps to Armv8.5-A
343349cc55cSDimitry Andric   getTargetDefinesARMV85A(Opts, Builder);
344349cc55cSDimitry Andric }
345349cc55cSDimitry Andric 
346349cc55cSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
347349cc55cSDimitry Andric                                                 MacroBuilder &Builder) const {
348349cc55cSDimitry Andric   // Armv9.1-A maps to Armv8.6-A
349349cc55cSDimitry Andric   getTargetDefinesARMV86A(Opts, Builder);
350349cc55cSDimitry Andric }
351349cc55cSDimitry Andric 
352349cc55cSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
353349cc55cSDimitry Andric                                                 MacroBuilder &Builder) const {
354349cc55cSDimitry Andric   // Armv9.2-A maps to Armv8.7-A
355349cc55cSDimitry Andric   getTargetDefinesARMV87A(Opts, Builder);
356349cc55cSDimitry Andric }
357349cc55cSDimitry Andric 
35804eeddc0SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
35904eeddc0SDimitry Andric                                                 MacroBuilder &Builder) const {
36004eeddc0SDimitry Andric   // Armv9.3-A maps to Armv8.8-A
36104eeddc0SDimitry Andric   getTargetDefinesARMV88A(Opts, Builder);
36204eeddc0SDimitry Andric }
36304eeddc0SDimitry Andric 
364bdd1243dSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
365bdd1243dSDimitry Andric                                                 MacroBuilder &Builder) const {
366bdd1243dSDimitry Andric   // Armv9.4-A maps to Armv8.9-A
367bdd1243dSDimitry Andric   getTargetDefinesARMV89A(Opts, Builder);
368bdd1243dSDimitry Andric }
369bdd1243dSDimitry Andric 
3705f757f3fSDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
3715f757f3fSDimitry Andric                                                 MacroBuilder &Builder) const {
3725f757f3fSDimitry Andric   // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
3735f757f3fSDimitry Andric   getTargetDefinesARMV94A(Opts, Builder);
3745f757f3fSDimitry Andric }
3755f757f3fSDimitry Andric 
3760b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
3770b57cec5SDimitry Andric                                          MacroBuilder &Builder) const {
3780b57cec5SDimitry Andric   // Target identification.
3795f757f3fSDimitry Andric   if (getTriple().isWindowsArm64EC()) {
3805f757f3fSDimitry Andric     // Define the same set of macros as would be defined on x86_64 to ensure that
3815f757f3fSDimitry Andric     // ARM64EC datatype layouts match those of x86_64 compiled code
3825f757f3fSDimitry Andric     Builder.defineMacro("__amd64__");
3835f757f3fSDimitry Andric     Builder.defineMacro("__amd64");
3845f757f3fSDimitry Andric     Builder.defineMacro("__x86_64");
3855f757f3fSDimitry Andric     Builder.defineMacro("__x86_64__");
3865f757f3fSDimitry Andric     Builder.defineMacro("__arm64ec__");
3875f757f3fSDimitry Andric   } else {
3880b57cec5SDimitry Andric     Builder.defineMacro("__aarch64__");
3895f757f3fSDimitry Andric   }
3905f757f3fSDimitry Andric 
39106c3fb27SDimitry Andric   // Inline assembly supports AArch64 flag outputs.
39206c3fb27SDimitry Andric   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
3930b57cec5SDimitry Andric 
3945ffd83dbSDimitry Andric   std::string CodeModel = getTargetOpts().CodeModel;
3955ffd83dbSDimitry Andric   if (CodeModel == "default")
3965ffd83dbSDimitry Andric     CodeModel = "small";
3975ffd83dbSDimitry Andric   for (char &c : CodeModel)
3985ffd83dbSDimitry Andric     c = toupper(c);
3995ffd83dbSDimitry Andric   Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
4005ffd83dbSDimitry Andric 
4010b57cec5SDimitry Andric   // ACLE predefines. Many can only have one possible value on v8 AArch64.
4020b57cec5SDimitry Andric   Builder.defineMacro("__ARM_ACLE", "200");
403bdd1243dSDimitry Andric   Builder.defineMacro("__ARM_ARCH",
404bdd1243dSDimitry Andric                       std::to_string(ArchInfo->Version.getMajor()));
405bdd1243dSDimitry Andric   Builder.defineMacro("__ARM_ARCH_PROFILE",
406bdd1243dSDimitry Andric                       std::string("'") + (char)ArchInfo->Profile + "'");
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   Builder.defineMacro("__ARM_64BIT_STATE", "1");
4090b57cec5SDimitry Andric   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
4100b57cec5SDimitry Andric   Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
4130b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_FMA", "1");
4140b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
4150b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
4160b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_DIV");       // For backwards compatibility
4170b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
4180b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
4210b57cec5SDimitry Andric 
422b3edf446SDimitry Andric   // These macros are set when Clang can parse declarations with these
423b3edf446SDimitry Andric   // attributes.
424b3edf446SDimitry Andric   Builder.defineMacro("__ARM_STATE_ZA", "1");
425b3edf446SDimitry Andric   Builder.defineMacro("__ARM_STATE_ZT0", "1");
426b3edf446SDimitry Andric 
4270b57cec5SDimitry Andric   // 0xe implies support for half, single and double precision operations.
42806c3fb27SDimitry Andric   if (FPU & FPUMode)
4290b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FP", "0xE");
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   // PCS specifies this for SysV variants, which is all we support. Other ABIs
4320b57cec5SDimitry Andric   // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
4330b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
4340b57cec5SDimitry Andric   Builder.defineMacro("__ARM_FP16_ARGS", "1");
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   if (Opts.UnsafeFPMath)
4370b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FP_FAST", "1");
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
4400b57cec5SDimitry Andric                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   if (FPU & NeonMode) {
4450b57cec5SDimitry Andric     Builder.defineMacro("__ARM_NEON", "1");
4460b57cec5SDimitry Andric     // 64-bit NEON supports half, single and double precision operations.
4470b57cec5SDimitry Andric     Builder.defineMacro("__ARM_NEON_FP", "0xE");
4480b57cec5SDimitry Andric   }
4490b57cec5SDimitry Andric 
4505ffd83dbSDimitry Andric   if (FPU & SveMode)
4515ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE", "1");
4525ffd83dbSDimitry Andric 
4530eae32dcSDimitry Andric   if ((FPU & NeonMode) && (FPU & SveMode))
4540eae32dcSDimitry Andric     Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
4550eae32dcSDimitry Andric 
4565ffd83dbSDimitry Andric   if (HasSVE2)
4575ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
4585ffd83dbSDimitry Andric 
4590fca6ea1SDimitry Andric   if (HasSVE2p1)
4600fca6ea1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");
4610fca6ea1SDimitry Andric 
4625ffd83dbSDimitry Andric   if (HasSVE2 && HasSVE2AES)
4635ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
4645ffd83dbSDimitry Andric 
4655ffd83dbSDimitry Andric   if (HasSVE2 && HasSVE2BitPerm)
4665ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
4675ffd83dbSDimitry Andric 
4685ffd83dbSDimitry Andric   if (HasSVE2 && HasSVE2SHA3)
4695ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
4705ffd83dbSDimitry Andric 
4715ffd83dbSDimitry Andric   if (HasSVE2 && HasSVE2SM4)
4725ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
4735ffd83dbSDimitry Andric 
474*6c4b055cSDimitry Andric   if (HasSVEB16B16)
475*6c4b055cSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_B16B16", "1");
476*6c4b055cSDimitry Andric 
477b3edf446SDimitry Andric   if (HasSME) {
478b3edf446SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SME");
479b3edf446SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
480b3edf446SDimitry Andric   }
481b3edf446SDimitry Andric 
482*6c4b055cSDimitry Andric   if (HasSME2)
4830fca6ea1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SME2", "1");
4840fca6ea1SDimitry Andric 
485*6c4b055cSDimitry Andric   if (HasSME2p1)
4860fca6ea1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SME2p1", "1");
487*6c4b055cSDimitry Andric 
488*6c4b055cSDimitry Andric   if (HasSMEF16F16)
489*6c4b055cSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SME_F16F16", "1");
490*6c4b055cSDimitry Andric 
491*6c4b055cSDimitry Andric   if (HasSMEB16B16)
492*6c4b055cSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SME_B16B16", "1");
493b3edf446SDimitry Andric 
4940b57cec5SDimitry Andric   if (HasCRC)
4950b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
4960b57cec5SDimitry Andric 
49706c3fb27SDimitry Andric   if (HasRCPC3)
49806c3fb27SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
49906c3fb27SDimitry Andric   else if (HasRCPC)
500bdd1243dSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
501bdd1243dSDimitry Andric 
502bdd1243dSDimitry Andric   if (HasFMV)
503bdd1243dSDimitry Andric     Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
504bdd1243dSDimitry Andric 
505fe6060f1SDimitry Andric   // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
506fe6060f1SDimitry Andric   // macros for AES, SHA2, SHA3 and SM4
507fe6060f1SDimitry Andric   if (HasAES && HasSHA2)
5080b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
5090b57cec5SDimitry Andric 
510fe6060f1SDimitry Andric   if (HasAES)
511fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_AES", "1");
512fe6060f1SDimitry Andric 
513fe6060f1SDimitry Andric   if (HasSHA2)
514fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
515fe6060f1SDimitry Andric 
516fe6060f1SDimitry Andric   if (HasSHA3) {
517fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
518fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
519fe6060f1SDimitry Andric   }
520fe6060f1SDimitry Andric 
521fe6060f1SDimitry Andric   if (HasSM4) {
522fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SM3", "1");
523fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SM4", "1");
524fe6060f1SDimitry Andric   }
525fe6060f1SDimitry Andric 
526bdd1243dSDimitry Andric   if (HasPAuth)
527bdd1243dSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
528bdd1243dSDimitry Andric 
5290fca6ea1SDimitry Andric   if (HasPAuthLR)
5300fca6ea1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
5310fca6ea1SDimitry Andric 
5320fca6ea1SDimitry Andric   if (HasBTI)
5330fca6ea1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_BTI", "1");
5340fca6ea1SDimitry Andric 
5350fca6ea1SDimitry Andric   if (HasUnalignedAccess)
5360b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   if ((FPU & NeonMode) && HasFullFP16)
5390b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
5400b57cec5SDimitry Andric   if (HasFullFP16)
5410b57cec5SDimitry Andric    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   if (HasDotProd)
5440b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   if (HasMTE)
5470b57cec5SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
5480b57cec5SDimitry Andric 
549a7dea167SDimitry Andric   if (HasTME)
550a7dea167SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_TME", "1");
551a7dea167SDimitry Andric 
5525ffd83dbSDimitry Andric   if (HasMatMul)
5535ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
5545ffd83dbSDimitry Andric 
555e8d8bef9SDimitry Andric   if (HasLSE)
556e8d8bef9SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
557e8d8bef9SDimitry Andric 
5585ffd83dbSDimitry Andric   if (HasBFloat16) {
5595ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_BF16", "1");
5605ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
5615ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
5625ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
5635ffd83dbSDimitry Andric   }
5645ffd83dbSDimitry Andric 
5655ffd83dbSDimitry Andric   if ((FPU & SveMode) && HasBFloat16) {
5665ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
5675ffd83dbSDimitry Andric   }
5685ffd83dbSDimitry Andric 
5695ffd83dbSDimitry Andric   if ((FPU & SveMode) && HasMatmulFP64)
5705ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
5715ffd83dbSDimitry Andric 
5725ffd83dbSDimitry Andric   if ((FPU & SveMode) && HasMatmulFP32)
5735ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
5745ffd83dbSDimitry Andric 
5755ffd83dbSDimitry Andric   if ((FPU & SveMode) && HasMatMul)
5765ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
5775ffd83dbSDimitry Andric 
5780b57cec5SDimitry Andric   if ((FPU & NeonMode) && HasFP16FML)
579fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
5800b57cec5SDimitry Andric 
5815ffd83dbSDimitry Andric   if (Opts.hasSignReturnAddress()) {
5825ffd83dbSDimitry Andric     // Bitmask:
5835ffd83dbSDimitry Andric     // 0: Protection using the A key
5845ffd83dbSDimitry Andric     // 1: Protection using the B key
5855ffd83dbSDimitry Andric     // 2: Protection including leaf functions
5860fca6ea1SDimitry Andric     // 3: Protection using PC as a diversifier
5875ffd83dbSDimitry Andric     unsigned Value = 0;
5885ffd83dbSDimitry Andric 
5895ffd83dbSDimitry Andric     if (Opts.isSignReturnAddressWithAKey())
5905ffd83dbSDimitry Andric       Value |= (1 << 0);
5915ffd83dbSDimitry Andric     else
5925ffd83dbSDimitry Andric       Value |= (1 << 1);
5935ffd83dbSDimitry Andric 
5945ffd83dbSDimitry Andric     if (Opts.isSignReturnAddressScopeAll())
5955ffd83dbSDimitry Andric       Value |= (1 << 2);
5965ffd83dbSDimitry Andric 
5970fca6ea1SDimitry Andric     if (Opts.BranchProtectionPAuthLR)
5980fca6ea1SDimitry Andric       Value |= (1 << 3);
5990fca6ea1SDimitry Andric 
6005ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
6015ffd83dbSDimitry Andric   }
6025ffd83dbSDimitry Andric 
6035ffd83dbSDimitry Andric   if (Opts.BranchTargetEnforcement)
6045ffd83dbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
6055ffd83dbSDimitry Andric 
606297eecfbSDimitry Andric   if (Opts.GuardedControlStack)
607297eecfbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
608297eecfbSDimitry Andric 
609e8d8bef9SDimitry Andric   if (HasLS64)
610e8d8bef9SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_LS64", "1");
611e8d8bef9SDimitry Andric 
612fe6060f1SDimitry Andric   if (HasRandGen)
613fe6060f1SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_RNG", "1");
614fe6060f1SDimitry Andric 
61581ad6265SDimitry Andric   if (HasMOPS)
61681ad6265SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
61781ad6265SDimitry Andric 
618bdd1243dSDimitry Andric   if (HasD128)
619bdd1243dSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
620bdd1243dSDimitry Andric 
621297eecfbSDimitry Andric   if (HasGCS)
622297eecfbSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_GCS", "1");
623297eecfbSDimitry Andric 
624bdd1243dSDimitry Andric   if (*ArchInfo == llvm::AArch64::ARMV8_1A)
6250b57cec5SDimitry Andric     getTargetDefinesARMV81A(Opts, Builder);
626bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
6270b57cec5SDimitry Andric     getTargetDefinesARMV82A(Opts, Builder);
628bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
6290b57cec5SDimitry Andric     getTargetDefinesARMV83A(Opts, Builder);
630bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
6310b57cec5SDimitry Andric     getTargetDefinesARMV84A(Opts, Builder);
632bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
6330b57cec5SDimitry Andric     getTargetDefinesARMV85A(Opts, Builder);
634bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
6355ffd83dbSDimitry Andric     getTargetDefinesARMV86A(Opts, Builder);
636bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
637e8d8bef9SDimitry Andric     getTargetDefinesARMV87A(Opts, Builder);
638bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
63904eeddc0SDimitry Andric     getTargetDefinesARMV88A(Opts, Builder);
640bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
641bdd1243dSDimitry Andric     getTargetDefinesARMV89A(Opts, Builder);
642bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9A)
643349cc55cSDimitry Andric     getTargetDefinesARMV9A(Opts, Builder);
644bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
645349cc55cSDimitry Andric     getTargetDefinesARMV91A(Opts, Builder);
646bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
647349cc55cSDimitry Andric     getTargetDefinesARMV92A(Opts, Builder);
648bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
64904eeddc0SDimitry Andric     getTargetDefinesARMV93A(Opts, Builder);
650bdd1243dSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
651bdd1243dSDimitry Andric     getTargetDefinesARMV94A(Opts, Builder);
6525f757f3fSDimitry Andric   else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
6535f757f3fSDimitry Andric     getTargetDefinesARMV95A(Opts, Builder);
6540b57cec5SDimitry Andric 
6555f757f3fSDimitry Andric   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
6560b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
6570b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
6580b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
6590b57cec5SDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
6605f757f3fSDimitry Andric   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
661e8d8bef9SDimitry Andric 
66281ad6265SDimitry Andric   // Allow detection of fast FMA support.
66381ad6265SDimitry Andric   Builder.defineMacro("__FP_FAST_FMA", "1");
66481ad6265SDimitry Andric   Builder.defineMacro("__FP_FAST_FMAF", "1");
66581ad6265SDimitry Andric 
666a4a491e2SDimitry Andric   // C/C++ operators work on both VLS and VLA SVE types
667a4a491e2SDimitry Andric   if (FPU & SveMode)
668a4a491e2SDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
669a4a491e2SDimitry Andric 
670349cc55cSDimitry Andric   if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
671349cc55cSDimitry Andric     Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
672e8d8bef9SDimitry Andric   }
6730b57cec5SDimitry Andric }
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
676bdd1243dSDimitry Andric   return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
6770b57cec5SDimitry Andric                                          Builtin::FirstTSBuiltin);
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric 
680bdd1243dSDimitry Andric std::optional<std::pair<unsigned, unsigned>>
681349cc55cSDimitry Andric AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
682349cc55cSDimitry Andric   if (LangOpts.VScaleMin || LangOpts.VScaleMax)
6830eae32dcSDimitry Andric     return std::pair<unsigned, unsigned>(
6840eae32dcSDimitry Andric         LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
6850eae32dcSDimitry Andric 
686349cc55cSDimitry Andric   if (hasFeature("sve"))
6870eae32dcSDimitry Andric     return std::pair<unsigned, unsigned>(1, 16);
6880eae32dcSDimitry Andric 
689bdd1243dSDimitry Andric   return std::nullopt;
690bdd1243dSDimitry Andric }
691bdd1243dSDimitry Andric 
692bdd1243dSDimitry Andric unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
693bdd1243dSDimitry Andric   if (Name == "default")
694bdd1243dSDimitry Andric     return 0;
6950fca6ea1SDimitry Andric   if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
6960fca6ea1SDimitry Andric     return Ext->Priority;
697bdd1243dSDimitry Andric   return 0;
698bdd1243dSDimitry Andric }
699bdd1243dSDimitry Andric 
700bdd1243dSDimitry Andric unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
701bdd1243dSDimitry Andric   // Take the maximum priority as per feature cost, so more features win.
7020fca6ea1SDimitry Andric   constexpr unsigned MaxFMVPriority = 1000;
7030fca6ea1SDimitry Andric   return MaxFMVPriority;
704bdd1243dSDimitry Andric }
705bdd1243dSDimitry Andric 
70606c3fb27SDimitry Andric bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
7070fca6ea1SDimitry Andric   // FMV extensions which imply no backend features do not affect codegen.
7080fca6ea1SDimitry Andric   if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
7090fca6ea1SDimitry Andric     return !Ext->Features.empty();
7107a6dacacSDimitry Andric   return false;
711bdd1243dSDimitry Andric }
71206c3fb27SDimitry Andric 
713bdd1243dSDimitry Andric bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
7140fca6ea1SDimitry Andric   // CPU features might be separated by '+', extract them and check
7150fca6ea1SDimitry Andric   llvm::SmallVector<StringRef, 8> Features;
7160fca6ea1SDimitry Andric   FeatureStr.split(Features, "+");
7170fca6ea1SDimitry Andric   for (auto &Feature : Features)
7180fca6ea1SDimitry Andric     if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())
7190fca6ea1SDimitry Andric       return false;
7200fca6ea1SDimitry Andric   return true;
721349cc55cSDimitry Andric }
722349cc55cSDimitry Andric 
7230b57cec5SDimitry Andric bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
72481ad6265SDimitry Andric   return llvm::StringSwitch<bool>(Feature)
72581ad6265SDimitry Andric       .Cases("aarch64", "arm64", "arm", true)
726bdd1243dSDimitry Andric       .Case("fmv", HasFMV)
7270fca6ea1SDimitry Andric       .Case("fp", FPU & FPUMode)
7280fca6ea1SDimitry Andric       .Cases("neon", "simd", FPU & NeonMode)
729bdd1243dSDimitry Andric       .Case("jscvt", HasJSCVT)
730bdd1243dSDimitry Andric       .Case("fcma", HasFCMA)
731bdd1243dSDimitry Andric       .Case("rng", HasRandGen)
732bdd1243dSDimitry Andric       .Case("flagm", HasFlagM)
733bdd1243dSDimitry Andric       .Case("flagm2", HasAlternativeNZCV)
734bdd1243dSDimitry Andric       .Case("fp16fml", HasFP16FML)
735bdd1243dSDimitry Andric       .Case("dotprod", HasDotProd)
736bdd1243dSDimitry Andric       .Case("sm4", HasSM4)
737bdd1243dSDimitry Andric       .Case("rdm", HasRDM)
738bdd1243dSDimitry Andric       .Case("lse", HasLSE)
739bdd1243dSDimitry Andric       .Case("crc", HasCRC)
740bdd1243dSDimitry Andric       .Case("sha2", HasSHA2)
741bdd1243dSDimitry Andric       .Case("sha3", HasSHA3)
742bdd1243dSDimitry Andric       .Cases("aes", "pmull", HasAES)
743bdd1243dSDimitry Andric       .Cases("fp16", "fullfp16", HasFullFP16)
744bdd1243dSDimitry Andric       .Case("dit", HasDIT)
745bdd1243dSDimitry Andric       .Case("dpb", HasCCPP)
746bdd1243dSDimitry Andric       .Case("dpb2", HasCCDP)
747bdd1243dSDimitry Andric       .Case("rcpc", HasRCPC)
748bdd1243dSDimitry Andric       .Case("frintts", HasFRInt3264)
749bdd1243dSDimitry Andric       .Case("i8mm", HasMatMul)
750bdd1243dSDimitry Andric       .Case("bf16", HasBFloat16)
751bdd1243dSDimitry Andric       .Case("sve", FPU & SveMode)
752bdd1243dSDimitry Andric       .Case("sve-bf16", FPU & SveMode && HasBFloat16)
753bdd1243dSDimitry Andric       .Case("sve-i8mm", FPU & SveMode && HasMatMul)
754*6c4b055cSDimitry Andric       .Case("sve-b16b16", HasSVEB16B16)
755bdd1243dSDimitry Andric       .Case("f32mm", FPU & SveMode && HasMatmulFP32)
756bdd1243dSDimitry Andric       .Case("f64mm", FPU & SveMode && HasMatmulFP64)
757bdd1243dSDimitry Andric       .Case("sve2", FPU & SveMode && HasSVE2)
758bdd1243dSDimitry Andric       .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
759bdd1243dSDimitry Andric       .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
760bdd1243dSDimitry Andric       .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
761bdd1243dSDimitry Andric       .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
7620fca6ea1SDimitry Andric       .Case("sve2p1", FPU & SveMode && HasSVE2p1)
763bdd1243dSDimitry Andric       .Case("sme", HasSME)
764b3edf446SDimitry Andric       .Case("sme2", HasSME2)
7650fca6ea1SDimitry Andric       .Case("sme2p1", HasSME2p1)
76606c3fb27SDimitry Andric       .Case("sme-f64f64", HasSMEF64F64)
76706c3fb27SDimitry Andric       .Case("sme-i16i64", HasSMEI16I64)
7685f757f3fSDimitry Andric       .Case("sme-fa64", HasSMEFA64)
769*6c4b055cSDimitry Andric       .Case("sme-f16f16", HasSMEF16F16)
770*6c4b055cSDimitry Andric       .Case("sme-b16b16", HasSMEB16B16)
771bdd1243dSDimitry Andric       .Cases("memtag", "memtag2", HasMTE)
772bdd1243dSDimitry Andric       .Case("sb", HasSB)
773bdd1243dSDimitry Andric       .Case("predres", HasPredRes)
774bdd1243dSDimitry Andric       .Cases("ssbs", "ssbs2", HasSSBS)
775bdd1243dSDimitry Andric       .Case("bti", HasBTI)
776bdd1243dSDimitry Andric       .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
777bdd1243dSDimitry Andric       .Case("wfxt", HasWFxT)
77806c3fb27SDimitry Andric       .Case("rcpc3", HasRCPC3)
77981ad6265SDimitry Andric       .Default(false);
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric 
782bdd1243dSDimitry Andric void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
783bdd1243dSDimitry Andric                                           StringRef Name, bool Enabled) const {
784bdd1243dSDimitry Andric   Features[Name] = Enabled;
785bdd1243dSDimitry Andric   // If the feature is an architecture feature (like v8.2a), add all previous
786bdd1243dSDimitry Andric   // architecture versions and any dependant target features.
78706c3fb27SDimitry Andric   const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
788bdd1243dSDimitry Andric       llvm::AArch64::ArchInfo::findBySubArch(Name);
789bdd1243dSDimitry Andric 
79006c3fb27SDimitry Andric   if (!ArchInfo)
79106c3fb27SDimitry Andric     return; // Not an architecture, nothing more to do.
792bdd1243dSDimitry Andric 
7931ac55f4cSDimitry Andric   // Disabling an architecture feature does not affect dependent features
7941ac55f4cSDimitry Andric   if (!Enabled)
7951ac55f4cSDimitry Andric     return;
7961ac55f4cSDimitry Andric 
797bdd1243dSDimitry Andric   for (const auto *OtherArch : llvm::AArch64::ArchInfos)
79806c3fb27SDimitry Andric     if (ArchInfo->implies(*OtherArch))
7991ac55f4cSDimitry Andric       Features[OtherArch->getSubArch()] = true;
800bdd1243dSDimitry Andric 
801bdd1243dSDimitry Andric   // Set any features implied by the architecture
802bdd1243dSDimitry Andric   std::vector<StringRef> CPUFeats;
80306c3fb27SDimitry Andric   if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
804bdd1243dSDimitry Andric     for (auto F : CPUFeats) {
805bdd1243dSDimitry Andric       assert(F[0] == '+' && "Expected + in target feature!");
806bdd1243dSDimitry Andric       Features[F.drop_front(1)] = true;
807bdd1243dSDimitry Andric     }
808bdd1243dSDimitry Andric   }
809bdd1243dSDimitry Andric }
810bdd1243dSDimitry Andric 
8110b57cec5SDimitry Andric bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
8120b57cec5SDimitry Andric                                              DiagnosticsEngine &Diags) {
8130b57cec5SDimitry Andric   for (const auto &Feature : Features) {
81406c3fb27SDimitry Andric     if (Feature == "-fp-armv8")
81506c3fb27SDimitry Andric       HasNoFP = true;
816bdd1243dSDimitry Andric     if (Feature == "-neon")
817bdd1243dSDimitry Andric       HasNoNeon = true;
818bdd1243dSDimitry Andric     if (Feature == "-sve")
819bdd1243dSDimitry Andric       HasNoSVE = true;
820bdd1243dSDimitry Andric 
821bdd1243dSDimitry Andric     if (Feature == "+neon" || Feature == "+fp-armv8")
8220b57cec5SDimitry Andric       FPU |= NeonMode;
823bdd1243dSDimitry Andric     if (Feature == "+jscvt") {
824bdd1243dSDimitry Andric       HasJSCVT = true;
825bdd1243dSDimitry Andric       FPU |= NeonMode;
826bdd1243dSDimitry Andric     }
827bdd1243dSDimitry Andric     if (Feature == "+fcma") {
828bdd1243dSDimitry Andric       HasFCMA = true;
829bdd1243dSDimitry Andric       FPU |= NeonMode;
830bdd1243dSDimitry Andric     }
831bdd1243dSDimitry Andric 
8325ffd83dbSDimitry Andric     if (Feature == "+sve") {
833bdd1243dSDimitry Andric       FPU |= NeonMode;
8340b57cec5SDimitry Andric       FPU |= SveMode;
83504eeddc0SDimitry Andric       HasFullFP16 = true;
8365ffd83dbSDimitry Andric     }
8375ffd83dbSDimitry Andric     if (Feature == "+sve2") {
838bdd1243dSDimitry Andric       FPU |= NeonMode;
8395ffd83dbSDimitry Andric       FPU |= SveMode;
84004eeddc0SDimitry Andric       HasFullFP16 = true;
84104eeddc0SDimitry Andric       HasSVE2 = true;
8425ffd83dbSDimitry Andric     }
8430fca6ea1SDimitry Andric     if (Feature == "+sve2p1") {
8440fca6ea1SDimitry Andric       FPU |= NeonMode;
8450fca6ea1SDimitry Andric       FPU |= SveMode;
8460fca6ea1SDimitry Andric       HasFullFP16 = true;
8470fca6ea1SDimitry Andric       HasSVE2 = true;
8480fca6ea1SDimitry Andric       HasSVE2p1 = true;
8490fca6ea1SDimitry Andric     }
8505ffd83dbSDimitry Andric     if (Feature == "+sve2-aes") {
851bdd1243dSDimitry Andric       FPU |= NeonMode;
8525ffd83dbSDimitry Andric       FPU |= SveMode;
85304eeddc0SDimitry Andric       HasFullFP16 = true;
85404eeddc0SDimitry Andric       HasSVE2 = true;
85504eeddc0SDimitry Andric       HasSVE2AES = true;
8565ffd83dbSDimitry Andric     }
8575ffd83dbSDimitry Andric     if (Feature == "+sve2-sha3") {
858bdd1243dSDimitry Andric       FPU |= NeonMode;
8595ffd83dbSDimitry Andric       FPU |= SveMode;
86004eeddc0SDimitry Andric       HasFullFP16 = true;
86104eeddc0SDimitry Andric       HasSVE2 = true;
86204eeddc0SDimitry Andric       HasSVE2SHA3 = true;
8635ffd83dbSDimitry Andric     }
8645ffd83dbSDimitry Andric     if (Feature == "+sve2-sm4") {
865bdd1243dSDimitry Andric       FPU |= NeonMode;
8665ffd83dbSDimitry Andric       FPU |= SveMode;
86704eeddc0SDimitry Andric       HasFullFP16 = true;
86804eeddc0SDimitry Andric       HasSVE2 = true;
86904eeddc0SDimitry Andric       HasSVE2SM4 = true;
8705ffd83dbSDimitry Andric     }
871*6c4b055cSDimitry Andric     if (Feature == "+sve-b16b16")
872*6c4b055cSDimitry Andric       HasSVEB16B16 = true;
8735ffd83dbSDimitry Andric     if (Feature == "+sve2-bitperm") {
874bdd1243dSDimitry Andric       FPU |= NeonMode;
8755ffd83dbSDimitry Andric       FPU |= SveMode;
87604eeddc0SDimitry Andric       HasFullFP16 = true;
87704eeddc0SDimitry Andric       HasSVE2 = true;
87804eeddc0SDimitry Andric       HasSVE2BitPerm = true;
8795ffd83dbSDimitry Andric     }
8805ffd83dbSDimitry Andric     if (Feature == "+f32mm") {
881bdd1243dSDimitry Andric       FPU |= NeonMode;
8825ffd83dbSDimitry Andric       FPU |= SveMode;
883bdd1243dSDimitry Andric       HasFullFP16 = true;
8845ffd83dbSDimitry Andric       HasMatmulFP32 = true;
8855ffd83dbSDimitry Andric     }
8865ffd83dbSDimitry Andric     if (Feature == "+f64mm") {
887bdd1243dSDimitry Andric       FPU |= NeonMode;
8885ffd83dbSDimitry Andric       FPU |= SveMode;
889bdd1243dSDimitry Andric       HasFullFP16 = true;
8905ffd83dbSDimitry Andric       HasMatmulFP64 = true;
8915ffd83dbSDimitry Andric     }
892bdd1243dSDimitry Andric     if (Feature == "+sme") {
893bdd1243dSDimitry Andric       HasSME = true;
894bdd1243dSDimitry Andric       HasBFloat16 = true;
89506c3fb27SDimitry Andric       HasFullFP16 = true;
896bdd1243dSDimitry Andric     }
897b3edf446SDimitry Andric     if (Feature == "+sme2") {
898b3edf446SDimitry Andric       HasSME = true;
899b3edf446SDimitry Andric       HasSME2 = true;
900b3edf446SDimitry Andric       HasBFloat16 = true;
901b3edf446SDimitry Andric       HasFullFP16 = true;
902b3edf446SDimitry Andric     }
9030fca6ea1SDimitry Andric     if (Feature == "+sme2p1") {
9040fca6ea1SDimitry Andric       HasSME = true;
9050fca6ea1SDimitry Andric       HasSME2 = true;
9060fca6ea1SDimitry Andric       HasSME2p1 = true;
9070fca6ea1SDimitry Andric       HasBFloat16 = true;
9080fca6ea1SDimitry Andric       HasFullFP16 = true;
9090fca6ea1SDimitry Andric     }
910bdd1243dSDimitry Andric     if (Feature == "+sme-f64f64") {
911bdd1243dSDimitry Andric       HasSME = true;
91206c3fb27SDimitry Andric       HasSMEF64F64 = true;
913bdd1243dSDimitry Andric       HasBFloat16 = true;
91406c3fb27SDimitry Andric       HasFullFP16 = true;
915bdd1243dSDimitry Andric     }
916bdd1243dSDimitry Andric     if (Feature == "+sme-i16i64") {
917bdd1243dSDimitry Andric       HasSME = true;
91806c3fb27SDimitry Andric       HasSMEI16I64 = true;
919bdd1243dSDimitry Andric       HasBFloat16 = true;
92006c3fb27SDimitry Andric       HasFullFP16 = true;
921bdd1243dSDimitry Andric     }
9225f757f3fSDimitry Andric     if (Feature == "+sme-fa64") {
9235f757f3fSDimitry Andric       FPU |= NeonMode;
9245f757f3fSDimitry Andric       FPU |= SveMode;
9255f757f3fSDimitry Andric       HasSME = true;
9265f757f3fSDimitry Andric       HasSVE2 = true;
9275f757f3fSDimitry Andric       HasSMEFA64 = true;
9285f757f3fSDimitry Andric     }
929*6c4b055cSDimitry Andric     if (Feature == "+sme-f16f16") {
930*6c4b055cSDimitry Andric       HasSME = true;
931*6c4b055cSDimitry Andric       HasSME2 = true;
932*6c4b055cSDimitry Andric       HasBFloat16 = true;
933*6c4b055cSDimitry Andric       HasFullFP16 = true;
934*6c4b055cSDimitry Andric       HasSMEF16F16 = true;
935*6c4b055cSDimitry Andric     }
936*6c4b055cSDimitry Andric     if (Feature == "+sme-b16b16") {
937*6c4b055cSDimitry Andric       HasSME = true;
938*6c4b055cSDimitry Andric       HasSME2 = true;
939*6c4b055cSDimitry Andric       HasBFloat16 = true;
940*6c4b055cSDimitry Andric       HasFullFP16 = true;
941*6c4b055cSDimitry Andric       HasSVEB16B16 = true;
942*6c4b055cSDimitry Andric       HasSMEB16B16 = true;
943*6c4b055cSDimitry Andric     }
944bdd1243dSDimitry Andric     if (Feature == "+sb")
945bdd1243dSDimitry Andric       HasSB = true;
946bdd1243dSDimitry Andric     if (Feature == "+predres")
947bdd1243dSDimitry Andric       HasPredRes = true;
948bdd1243dSDimitry Andric     if (Feature == "+ssbs")
949bdd1243dSDimitry Andric       HasSSBS = true;
950bdd1243dSDimitry Andric     if (Feature == "+bti")
951bdd1243dSDimitry Andric       HasBTI = true;
952bdd1243dSDimitry Andric     if (Feature == "+wfxt")
953bdd1243dSDimitry Andric       HasWFxT = true;
954bdd1243dSDimitry Andric     if (Feature == "-fmv")
955bdd1243dSDimitry Andric       HasFMV = false;
9560b57cec5SDimitry Andric     if (Feature == "+crc")
9570b57cec5SDimitry Andric       HasCRC = true;
958bdd1243dSDimitry Andric     if (Feature == "+rcpc")
959bdd1243dSDimitry Andric       HasRCPC = true;
960bdd1243dSDimitry Andric     if (Feature == "+aes") {
961bdd1243dSDimitry Andric       FPU |= NeonMode;
962fe6060f1SDimitry Andric       HasAES = true;
963bdd1243dSDimitry Andric     }
964bdd1243dSDimitry Andric     if (Feature == "+sha2") {
965bdd1243dSDimitry Andric       FPU |= NeonMode;
966fe6060f1SDimitry Andric       HasSHA2 = true;
967bdd1243dSDimitry Andric     }
968fe6060f1SDimitry Andric     if (Feature == "+sha3") {
969bdd1243dSDimitry Andric       FPU |= NeonMode;
970fe6060f1SDimitry Andric       HasSHA2 = true;
971fe6060f1SDimitry Andric       HasSHA3 = true;
972fe6060f1SDimitry Andric     }
973bdd1243dSDimitry Andric     if (Feature == "+rdm") {
974bdd1243dSDimitry Andric       FPU |= NeonMode;
975bdd1243dSDimitry Andric       HasRDM = true;
976bdd1243dSDimitry Andric     }
977bdd1243dSDimitry Andric     if (Feature == "+dit")
978bdd1243dSDimitry Andric       HasDIT = true;
979bdd1243dSDimitry Andric     if (Feature == "+cccp")
980bdd1243dSDimitry Andric       HasCCPP = true;
981bdd1243dSDimitry Andric     if (Feature == "+ccdp") {
982bdd1243dSDimitry Andric       HasCCPP = true;
983bdd1243dSDimitry Andric       HasCCDP = true;
984bdd1243dSDimitry Andric     }
985bdd1243dSDimitry Andric     if (Feature == "+fptoint")
986bdd1243dSDimitry Andric       HasFRInt3264 = true;
987bdd1243dSDimitry Andric     if (Feature == "+sm4") {
988bdd1243dSDimitry Andric       FPU |= NeonMode;
989fe6060f1SDimitry Andric       HasSM4 = true;
990bdd1243dSDimitry Andric     }
9910b57cec5SDimitry Andric     if (Feature == "+strict-align")
9920fca6ea1SDimitry Andric       HasUnalignedAccess = false;
9930fca6ea1SDimitry Andric 
994bdd1243dSDimitry Andric     // All predecessor archs are added but select the latest one for ArchKind.
995bdd1243dSDimitry Andric     if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
996bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8A;
997bdd1243dSDimitry Andric     if (Feature == "+v8.1a" &&
998bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
999bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_1A;
1000bdd1243dSDimitry Andric     if (Feature == "+v8.2a" &&
1001bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
1002bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_2A;
1003bdd1243dSDimitry Andric     if (Feature == "+v8.3a" &&
1004bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
1005bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_3A;
1006bdd1243dSDimitry Andric     if (Feature == "+v8.4a" &&
1007bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
1008bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_4A;
1009bdd1243dSDimitry Andric     if (Feature == "+v8.5a" &&
1010bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
1011bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_5A;
1012bdd1243dSDimitry Andric     if (Feature == "+v8.6a" &&
1013bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
1014bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_6A;
1015bdd1243dSDimitry Andric     if (Feature == "+v8.7a" &&
1016bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
1017bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_7A;
1018bdd1243dSDimitry Andric     if (Feature == "+v8.8a" &&
1019bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
1020bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_8A;
1021bdd1243dSDimitry Andric     if (Feature == "+v8.9a" &&
1022bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
1023bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8_9A;
1024bdd1243dSDimitry Andric     if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
1025bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9A;
1026bdd1243dSDimitry Andric     if (Feature == "+v9.1a" &&
1027bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
1028bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9_1A;
1029bdd1243dSDimitry Andric     if (Feature == "+v9.2a" &&
1030bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
1031bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9_2A;
1032bdd1243dSDimitry Andric     if (Feature == "+v9.3a" &&
1033bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
1034bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9_3A;
1035bdd1243dSDimitry Andric     if (Feature == "+v9.4a" &&
1036bdd1243dSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
1037bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9_4A;
10385f757f3fSDimitry Andric     if (Feature == "+v9.5a" &&
10395f757f3fSDimitry Andric         ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
10405f757f3fSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV9_5A;
1041e8d8bef9SDimitry Andric     if (Feature == "+v8r")
1042bdd1243dSDimitry Andric       ArchInfo = &llvm::AArch64::ARMV8R;
1043bdd1243dSDimitry Andric     if (Feature == "+fullfp16") {
1044bdd1243dSDimitry Andric       FPU |= NeonMode;
10450b57cec5SDimitry Andric       HasFullFP16 = true;
1046bdd1243dSDimitry Andric     }
1047bdd1243dSDimitry Andric     if (Feature == "+dotprod") {
1048bdd1243dSDimitry Andric       FPU |= NeonMode;
10490b57cec5SDimitry Andric       HasDotProd = true;
1050bdd1243dSDimitry Andric     }
1051bdd1243dSDimitry Andric     if (Feature == "+fp16fml") {
1052bdd1243dSDimitry Andric       FPU |= NeonMode;
1053bdd1243dSDimitry Andric       HasFullFP16 = true;
10540b57cec5SDimitry Andric       HasFP16FML = true;
1055bdd1243dSDimitry Andric     }
10560b57cec5SDimitry Andric     if (Feature == "+mte")
10570b57cec5SDimitry Andric       HasMTE = true;
1058a7dea167SDimitry Andric     if (Feature == "+tme")
1059a7dea167SDimitry Andric       HasTME = true;
1060e8d8bef9SDimitry Andric     if (Feature == "+pauth")
1061e8d8bef9SDimitry Andric       HasPAuth = true;
10625ffd83dbSDimitry Andric     if (Feature == "+i8mm")
10635ffd83dbSDimitry Andric       HasMatMul = true;
10645ffd83dbSDimitry Andric     if (Feature == "+bf16")
10655ffd83dbSDimitry Andric       HasBFloat16 = true;
1066e8d8bef9SDimitry Andric     if (Feature == "+lse")
1067e8d8bef9SDimitry Andric       HasLSE = true;
1068e8d8bef9SDimitry Andric     if (Feature == "+ls64")
1069e8d8bef9SDimitry Andric       HasLS64 = true;
1070fe6060f1SDimitry Andric     if (Feature == "+rand")
1071fe6060f1SDimitry Andric       HasRandGen = true;
1072e8d8bef9SDimitry Andric     if (Feature == "+flagm")
1073e8d8bef9SDimitry Andric       HasFlagM = true;
1074bdd1243dSDimitry Andric     if (Feature == "+altnzcv") {
1075bdd1243dSDimitry Andric       HasFlagM = true;
1076bdd1243dSDimitry Andric       HasAlternativeNZCV = true;
1077bdd1243dSDimitry Andric     }
107881ad6265SDimitry Andric     if (Feature == "+mops")
107981ad6265SDimitry Andric       HasMOPS = true;
1080bdd1243dSDimitry Andric     if (Feature == "+d128")
1081bdd1243dSDimitry Andric       HasD128 = true;
108206c3fb27SDimitry Andric     if (Feature == "+gcs")
108306c3fb27SDimitry Andric       HasGCS = true;
108406c3fb27SDimitry Andric     if (Feature == "+rcpc3")
108506c3fb27SDimitry Andric       HasRCPC3 = true;
10860fca6ea1SDimitry Andric     if (Feature == "+pauth-lr") {
10870fca6ea1SDimitry Andric       HasPAuthLR = true;
10880fca6ea1SDimitry Andric       HasPAuth = true;
10890fca6ea1SDimitry Andric     }
1090bdd1243dSDimitry Andric   }
1091bdd1243dSDimitry Andric 
1092bdd1243dSDimitry Andric   // Check features that are manually disabled by command line options.
1093bdd1243dSDimitry Andric   // This needs to be checked after architecture-related features are handled,
1094bdd1243dSDimitry Andric   // making sure they are properly disabled when required.
1095bdd1243dSDimitry Andric   for (const auto &Feature : Features) {
1096bdd1243dSDimitry Andric     if (Feature == "-d128")
1097bdd1243dSDimitry Andric       HasD128 = false;
10980b57cec5SDimitry Andric   }
10990b57cec5SDimitry Andric 
11000b57cec5SDimitry Andric   setDataLayout();
1101bdd1243dSDimitry Andric   setArchFeatures();
11020b57cec5SDimitry Andric 
110306c3fb27SDimitry Andric   if (HasNoFP) {
110406c3fb27SDimitry Andric     FPU &= ~FPUMode;
110506c3fb27SDimitry Andric     FPU &= ~NeonMode;
110606c3fb27SDimitry Andric     FPU &= ~SveMode;
110706c3fb27SDimitry Andric   }
1108bdd1243dSDimitry Andric   if (HasNoNeon) {
1109bdd1243dSDimitry Andric     FPU &= ~NeonMode;
1110bdd1243dSDimitry Andric     FPU &= ~SveMode;
1111bdd1243dSDimitry Andric   }
1112bdd1243dSDimitry Andric   if (HasNoSVE)
1113bdd1243dSDimitry Andric     FPU &= ~SveMode;
1114bdd1243dSDimitry Andric 
1115bdd1243dSDimitry Andric   return true;
1116bdd1243dSDimitry Andric }
1117bdd1243dSDimitry Andric 
1118bdd1243dSDimitry Andric // Parse AArch64 Target attributes, which are a comma separated list of:
1119bdd1243dSDimitry Andric //  "arch=<arch>" - parsed to features as per -march=..
1120bdd1243dSDimitry Andric //  "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1121bdd1243dSDimitry Andric //  "tune=<cpu>" - TuneCPU set to <cpu>
1122bdd1243dSDimitry Andric //  "feature", "no-feature" - Add (or remove) feature.
1123bdd1243dSDimitry Andric //  "+feature", "+nofeature" - Add (or remove) feature.
11240fca6ea1SDimitry Andric //
11250fca6ea1SDimitry Andric // A feature may correspond to an Extension (anything with a corresponding
11260fca6ea1SDimitry Andric // AEK_), in which case an ExtensionSet is used to parse it and expand its
11270fca6ea1SDimitry Andric // dependencies. If the feature does not yield a successful parse then it
11280fca6ea1SDimitry Andric // is passed through.
1129bdd1243dSDimitry Andric ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1130bdd1243dSDimitry Andric   ParsedTargetAttr Ret;
1131bdd1243dSDimitry Andric   if (Features == "default")
1132bdd1243dSDimitry Andric     return Ret;
1133bdd1243dSDimitry Andric   SmallVector<StringRef, 1> AttrFeatures;
1134bdd1243dSDimitry Andric   Features.split(AttrFeatures, ",");
1135bdd1243dSDimitry Andric   bool FoundArch = false;
1136bdd1243dSDimitry Andric 
1137bdd1243dSDimitry Andric   auto SplitAndAddFeatures = [](StringRef FeatString,
11380fca6ea1SDimitry Andric                                 std::vector<std::string> &Features,
11390fca6ea1SDimitry Andric                                 llvm::AArch64::ExtensionSet &FeatureBits) {
1140bdd1243dSDimitry Andric     SmallVector<StringRef, 8> SplitFeatures;
1141bdd1243dSDimitry Andric     FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1142bdd1243dSDimitry Andric     for (StringRef Feature : SplitFeatures) {
11430fca6ea1SDimitry Andric       if (FeatureBits.parseModifier(Feature))
11440fca6ea1SDimitry Andric         continue;
11450fca6ea1SDimitry Andric       // Pass through anything that failed to parse so that we can emit
11460fca6ea1SDimitry Andric       // diagnostics, as well as valid internal feature names.
11470fca6ea1SDimitry Andric       //
11480fca6ea1SDimitry Andric       // FIXME: We should consider rejecting internal feature names like
11490fca6ea1SDimitry Andric       //        neon, v8a, etc.
11500fca6ea1SDimitry Andric       // FIXME: We should consider emitting diagnostics here.
11515f757f3fSDimitry Andric       if (Feature.starts_with("no"))
1152bdd1243dSDimitry Andric         Features.push_back("-" + Feature.drop_front(2).str());
1153bdd1243dSDimitry Andric       else
1154bdd1243dSDimitry Andric         Features.push_back("+" + Feature.str());
1155bdd1243dSDimitry Andric     }
1156bdd1243dSDimitry Andric   };
1157bdd1243dSDimitry Andric 
11580fca6ea1SDimitry Andric   llvm::AArch64::ExtensionSet FeatureBits;
11590fca6ea1SDimitry Andric   // Reconstruct the bitset from the command line option features.
11600fca6ea1SDimitry Andric   FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten,
11610fca6ea1SDimitry Andric                                             Ret.Features);
11620fca6ea1SDimitry Andric 
1163bdd1243dSDimitry Andric   for (auto &Feature : AttrFeatures) {
1164bdd1243dSDimitry Andric     Feature = Feature.trim();
11655f757f3fSDimitry Andric     if (Feature.starts_with("fpmath="))
1166bdd1243dSDimitry Andric       continue;
1167bdd1243dSDimitry Andric 
11685f757f3fSDimitry Andric     if (Feature.starts_with("branch-protection=")) {
1169bdd1243dSDimitry Andric       Ret.BranchProtection = Feature.split('=').second.trim();
1170bdd1243dSDimitry Andric       continue;
1171bdd1243dSDimitry Andric     }
1172bdd1243dSDimitry Andric 
11735f757f3fSDimitry Andric     if (Feature.starts_with("arch=")) {
1174bdd1243dSDimitry Andric       if (FoundArch)
1175bdd1243dSDimitry Andric         Ret.Duplicate = "arch=";
1176bdd1243dSDimitry Andric       FoundArch = true;
1177bdd1243dSDimitry Andric       std::pair<StringRef, StringRef> Split =
1178bdd1243dSDimitry Andric           Feature.split("=").second.trim().split("+");
11797a6dacacSDimitry Andric       const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1180bdd1243dSDimitry Andric 
1181bdd1243dSDimitry Andric       // Parse the architecture version, adding the required features to
1182bdd1243dSDimitry Andric       // Ret.Features.
118306c3fb27SDimitry Andric       if (!AI)
1184bdd1243dSDimitry Andric         continue;
11850fca6ea1SDimitry Andric       FeatureBits.addArchDefaults(*AI);
1186bdd1243dSDimitry Andric       // Add any extra features, after the +
11870fca6ea1SDimitry Andric       SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
11885f757f3fSDimitry Andric     } else if (Feature.starts_with("cpu=")) {
1189bdd1243dSDimitry Andric       if (!Ret.CPU.empty())
1190bdd1243dSDimitry Andric         Ret.Duplicate = "cpu=";
1191bdd1243dSDimitry Andric       else {
1192bdd1243dSDimitry Andric         // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1193bdd1243dSDimitry Andric         // "+feat" features.
1194bdd1243dSDimitry Andric         std::pair<StringRef, StringRef> Split =
1195bdd1243dSDimitry Andric             Feature.split("=").second.trim().split("+");
1196bdd1243dSDimitry Andric         Ret.CPU = Split.first;
11970fca6ea1SDimitry Andric         if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {
11980fca6ea1SDimitry Andric           FeatureBits.addCPUDefaults(*CpuInfo);
11990fca6ea1SDimitry Andric           SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
12000fca6ea1SDimitry Andric         }
1201bdd1243dSDimitry Andric       }
12025f757f3fSDimitry Andric     } else if (Feature.starts_with("tune=")) {
1203bdd1243dSDimitry Andric       if (!Ret.Tune.empty())
1204bdd1243dSDimitry Andric         Ret.Duplicate = "tune=";
1205bdd1243dSDimitry Andric       else
1206bdd1243dSDimitry Andric         Ret.Tune = Feature.split("=").second.trim();
12075f757f3fSDimitry Andric     } else if (Feature.starts_with("+")) {
12080fca6ea1SDimitry Andric       SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);
1209bdd1243dSDimitry Andric     } else {
12100fca6ea1SDimitry Andric       if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))
12110fca6ea1SDimitry Andric         continue;
12120fca6ea1SDimitry Andric       // Pass through anything that failed to parse so that we can emit
12130fca6ea1SDimitry Andric       // diagnostics, as well as valid internal feature names.
12140fca6ea1SDimitry Andric       //
12150fca6ea1SDimitry Andric       // FIXME: We should consider rejecting internal feature names like
12160fca6ea1SDimitry Andric       //        neon, v8a, etc.
12170fca6ea1SDimitry Andric       // FIXME: We should consider emitting diagnostics here.
12180fca6ea1SDimitry Andric       if (Feature.starts_with("no-"))
12190fca6ea1SDimitry Andric         Ret.Features.push_back("-" + Feature.drop_front(3).str());
1220bdd1243dSDimitry Andric       else
1221bdd1243dSDimitry Andric         Ret.Features.push_back("+" + Feature.str());
1222bdd1243dSDimitry Andric     }
1223bdd1243dSDimitry Andric   }
12240fca6ea1SDimitry Andric   FeatureBits.toLLVMFeatureList(Ret.Features);
1225bdd1243dSDimitry Andric   return Ret;
1226bdd1243dSDimitry Andric }
1227bdd1243dSDimitry Andric 
1228bdd1243dSDimitry Andric bool AArch64TargetInfo::hasBFloat16Type() const {
12290b57cec5SDimitry Andric   return true;
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult
12330b57cec5SDimitry Andric AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
12340b57cec5SDimitry Andric   switch (CC) {
12350b57cec5SDimitry Andric   case CC_C:
12360b57cec5SDimitry Andric   case CC_Swift:
1237fe6060f1SDimitry Andric   case CC_SwiftAsync:
12380b57cec5SDimitry Andric   case CC_PreserveMost:
12390b57cec5SDimitry Andric   case CC_PreserveAll:
12400fca6ea1SDimitry Andric   case CC_PreserveNone:
12410b57cec5SDimitry Andric   case CC_OpenCLKernel:
12420b57cec5SDimitry Andric   case CC_AArch64VectorCall:
124381ad6265SDimitry Andric   case CC_AArch64SVEPCS:
12440b57cec5SDimitry Andric   case CC_Win64:
12450b57cec5SDimitry Andric     return CCCR_OK;
12460b57cec5SDimitry Andric   default:
12470b57cec5SDimitry Andric     return CCCR_Warning;
12480b57cec5SDimitry Andric   }
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
12540b57cec5SDimitry Andric   return TargetInfo::AArch64ABIBuiltinVaList;
12550b57cec5SDimitry Andric }
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric const char *const AArch64TargetInfo::GCCRegNames[] = {
125874626c16SDimitry Andric     // clang-format off
125974626c16SDimitry Andric 
12600b57cec5SDimitry Andric     // 32-bit Integer registers
12610b57cec5SDimitry Andric     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
12620b57cec5SDimitry Andric     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
12630b57cec5SDimitry Andric     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric     // 64-bit Integer registers
12660b57cec5SDimitry Andric     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
12670b57cec5SDimitry Andric     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
12680b57cec5SDimitry Andric     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric     // 32-bit floating point regsisters
12710b57cec5SDimitry Andric     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
12720b57cec5SDimitry Andric     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
12730b57cec5SDimitry Andric     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric     // 64-bit floating point regsisters
12760b57cec5SDimitry Andric     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
12770b57cec5SDimitry Andric     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
12780b57cec5SDimitry Andric     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric     // Neon vector registers
12810b57cec5SDimitry Andric     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
12820b57cec5SDimitry Andric     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
12830b57cec5SDimitry Andric     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric     // SVE vector registers
12860b57cec5SDimitry Andric     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
12870b57cec5SDimitry Andric     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
12880b57cec5SDimitry Andric     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric     // SVE predicate registers
12910b57cec5SDimitry Andric     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
129206c3fb27SDimitry Andric     "p11", "p12", "p13", "p14", "p15",
129306c3fb27SDimitry Andric 
129406c3fb27SDimitry Andric     // SVE predicate-as-counter registers
129506c3fb27SDimitry Andric     "pn0",  "pn1",  "pn2",  "pn3",  "pn4",  "pn5",  "pn6",  "pn7",  "pn8",
129674626c16SDimitry Andric     "pn9",  "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
129774626c16SDimitry Andric 
129874626c16SDimitry Andric     // SME registers
129974626c16SDimitry Andric     "za", "zt0",
130074626c16SDimitry Andric 
130174626c16SDimitry Andric     // clang-format on
13020b57cec5SDimitry Andric };
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1305bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegNames);
13060b57cec5SDimitry Andric }
13070b57cec5SDimitry Andric 
13080b57cec5SDimitry Andric const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
13090b57cec5SDimitry Andric     {{"w31"}, "wsp"},
13100b57cec5SDimitry Andric     {{"x31"}, "sp"},
13110b57cec5SDimitry Andric     // GCC rN registers are aliases of xN registers.
13120b57cec5SDimitry Andric     {{"r0"}, "x0"},
13130b57cec5SDimitry Andric     {{"r1"}, "x1"},
13140b57cec5SDimitry Andric     {{"r2"}, "x2"},
13150b57cec5SDimitry Andric     {{"r3"}, "x3"},
13160b57cec5SDimitry Andric     {{"r4"}, "x4"},
13170b57cec5SDimitry Andric     {{"r5"}, "x5"},
13180b57cec5SDimitry Andric     {{"r6"}, "x6"},
13190b57cec5SDimitry Andric     {{"r7"}, "x7"},
13200b57cec5SDimitry Andric     {{"r8"}, "x8"},
13210b57cec5SDimitry Andric     {{"r9"}, "x9"},
13220b57cec5SDimitry Andric     {{"r10"}, "x10"},
13230b57cec5SDimitry Andric     {{"r11"}, "x11"},
13240b57cec5SDimitry Andric     {{"r12"}, "x12"},
13250b57cec5SDimitry Andric     {{"r13"}, "x13"},
13260b57cec5SDimitry Andric     {{"r14"}, "x14"},
13270b57cec5SDimitry Andric     {{"r15"}, "x15"},
13280b57cec5SDimitry Andric     {{"r16"}, "x16"},
13290b57cec5SDimitry Andric     {{"r17"}, "x17"},
13300b57cec5SDimitry Andric     {{"r18"}, "x18"},
13310b57cec5SDimitry Andric     {{"r19"}, "x19"},
13320b57cec5SDimitry Andric     {{"r20"}, "x20"},
13330b57cec5SDimitry Andric     {{"r21"}, "x21"},
13340b57cec5SDimitry Andric     {{"r22"}, "x22"},
13350b57cec5SDimitry Andric     {{"r23"}, "x23"},
13360b57cec5SDimitry Andric     {{"r24"}, "x24"},
13370b57cec5SDimitry Andric     {{"r25"}, "x25"},
13380b57cec5SDimitry Andric     {{"r26"}, "x26"},
13390b57cec5SDimitry Andric     {{"r27"}, "x27"},
13400b57cec5SDimitry Andric     {{"r28"}, "x28"},
13410b57cec5SDimitry Andric     {{"r29", "x29"}, "fp"},
13420b57cec5SDimitry Andric     {{"r30", "x30"}, "lr"},
13430b57cec5SDimitry Andric     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
13440b57cec5SDimitry Andric     // don't want to substitute one of these for a different-sized one.
13450b57cec5SDimitry Andric };
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1348bdd1243dSDimitry Andric   return llvm::ArrayRef(GCCRegAliases);
13490b57cec5SDimitry Andric }
13500b57cec5SDimitry Andric 
135106c3fb27SDimitry Andric // Returns the length of cc constraint.
135206c3fb27SDimitry Andric static unsigned matchAsmCCConstraint(const char *Name) {
135306c3fb27SDimitry Andric   constexpr unsigned len = 5;
135406c3fb27SDimitry Andric   auto RV = llvm::StringSwitch<unsigned>(Name)
135506c3fb27SDimitry Andric                 .Case("@cceq", len)
135606c3fb27SDimitry Andric                 .Case("@ccne", len)
135706c3fb27SDimitry Andric                 .Case("@cchs", len)
135806c3fb27SDimitry Andric                 .Case("@cccs", len)
135906c3fb27SDimitry Andric                 .Case("@cccc", len)
136006c3fb27SDimitry Andric                 .Case("@cclo", len)
136106c3fb27SDimitry Andric                 .Case("@ccmi", len)
136206c3fb27SDimitry Andric                 .Case("@ccpl", len)
136306c3fb27SDimitry Andric                 .Case("@ccvs", len)
136406c3fb27SDimitry Andric                 .Case("@ccvc", len)
136506c3fb27SDimitry Andric                 .Case("@cchi", len)
136606c3fb27SDimitry Andric                 .Case("@ccls", len)
136706c3fb27SDimitry Andric                 .Case("@ccge", len)
136806c3fb27SDimitry Andric                 .Case("@cclt", len)
136906c3fb27SDimitry Andric                 .Case("@ccgt", len)
137006c3fb27SDimitry Andric                 .Case("@ccle", len)
137106c3fb27SDimitry Andric                 .Default(0);
137206c3fb27SDimitry Andric   return RV;
137306c3fb27SDimitry Andric }
137406c3fb27SDimitry Andric 
137506c3fb27SDimitry Andric std::string
137606c3fb27SDimitry Andric AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
137706c3fb27SDimitry Andric   std::string R;
137806c3fb27SDimitry Andric   switch (*Constraint) {
137906c3fb27SDimitry Andric   case 'U': // Three-character constraint; add "@3" hint for later parsing.
138006c3fb27SDimitry Andric     R = std::string("@3") + std::string(Constraint, 3);
138106c3fb27SDimitry Andric     Constraint += 2;
138206c3fb27SDimitry Andric     break;
138306c3fb27SDimitry Andric   case '@':
138406c3fb27SDimitry Andric     if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
138506c3fb27SDimitry Andric       std::string Converted = "{" + std::string(Constraint, Len) + "}";
138606c3fb27SDimitry Andric       Constraint += Len - 1;
138706c3fb27SDimitry Andric       return Converted;
138806c3fb27SDimitry Andric     }
138906c3fb27SDimitry Andric     return std::string(1, *Constraint);
139006c3fb27SDimitry Andric   default:
139106c3fb27SDimitry Andric     R = TargetInfo::convertConstraint(Constraint);
139206c3fb27SDimitry Andric     break;
139306c3fb27SDimitry Andric   }
139406c3fb27SDimitry Andric   return R;
139506c3fb27SDimitry Andric }
139606c3fb27SDimitry Andric 
13970b57cec5SDimitry Andric bool AArch64TargetInfo::validateAsmConstraint(
13980b57cec5SDimitry Andric     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
13990b57cec5SDimitry Andric   switch (*Name) {
14000b57cec5SDimitry Andric   default:
14010b57cec5SDimitry Andric     return false;
14020b57cec5SDimitry Andric   case 'w': // Floating point and SIMD registers (V0-V31)
14030b57cec5SDimitry Andric     Info.setAllowsRegister();
14040b57cec5SDimitry Andric     return true;
14050b57cec5SDimitry Andric   case 'I': // Constant that can be used with an ADD instruction
14060b57cec5SDimitry Andric   case 'J': // Constant that can be used with a SUB instruction
14070b57cec5SDimitry Andric   case 'K': // Constant that can be used with a 32-bit logical instruction
14080b57cec5SDimitry Andric   case 'L': // Constant that can be used with a 64-bit logical instruction
14090b57cec5SDimitry Andric   case 'M': // Constant that can be used as a 32-bit MOV immediate
14100b57cec5SDimitry Andric   case 'N': // Constant that can be used as a 64-bit MOV immediate
14110b57cec5SDimitry Andric   case 'Y': // Floating point constant zero
14120b57cec5SDimitry Andric   case 'Z': // Integer constant zero
14130b57cec5SDimitry Andric     return true;
14140b57cec5SDimitry Andric   case 'Q': // A memory reference with base register and no offset
14150b57cec5SDimitry Andric     Info.setAllowsMemory();
14160b57cec5SDimitry Andric     return true;
14170b57cec5SDimitry Andric   case 'S': // A symbolic address
14180b57cec5SDimitry Andric     Info.setAllowsRegister();
14190b57cec5SDimitry Andric     return true;
14200b57cec5SDimitry Andric   case 'U':
14215f757f3fSDimitry Andric     if (Name[1] == 'p' &&
14225f757f3fSDimitry Andric         (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
14235f757f3fSDimitry Andric       // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
14245f757f3fSDimitry Andric       Info.setAllowsRegister();
14255f757f3fSDimitry Andric       Name += 2;
14265f757f3fSDimitry Andric       return true;
14275f757f3fSDimitry Andric     }
14285f757f3fSDimitry Andric     if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
14295f757f3fSDimitry Andric       // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
14305ffd83dbSDimitry Andric       Info.setAllowsRegister();
14315ffd83dbSDimitry Andric       Name += 2;
14325ffd83dbSDimitry Andric       return true;
14335ffd83dbSDimitry Andric     }
14340b57cec5SDimitry Andric     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
14350b57cec5SDimitry Andric     // Utf: A memory address suitable for ldp/stp in TF mode.
14360b57cec5SDimitry Andric     // Usa: An absolute symbolic address.
14370b57cec5SDimitry Andric     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
14385ffd83dbSDimitry Andric 
14395ffd83dbSDimitry Andric     // Better to return an error saying that it's an unrecognised constraint
14405ffd83dbSDimitry Andric     // even if this is a valid constraint in gcc.
14415ffd83dbSDimitry Andric     return false;
14420b57cec5SDimitry Andric   case 'z': // Zero register, wzr or xzr
14430b57cec5SDimitry Andric     Info.setAllowsRegister();
14440b57cec5SDimitry Andric     return true;
14450b57cec5SDimitry Andric   case 'x': // Floating point and SIMD registers (V0-V15)
14460b57cec5SDimitry Andric     Info.setAllowsRegister();
14470b57cec5SDimitry Andric     return true;
14485ffd83dbSDimitry Andric   case 'y': // SVE registers (V0-V7)
14495ffd83dbSDimitry Andric     Info.setAllowsRegister();
14505ffd83dbSDimitry Andric     return true;
145106c3fb27SDimitry Andric   case '@':
145206c3fb27SDimitry Andric     // CC condition
145306c3fb27SDimitry Andric     if (const unsigned Len = matchAsmCCConstraint(Name)) {
145406c3fb27SDimitry Andric       Name += Len - 1;
145506c3fb27SDimitry Andric       Info.setAllowsRegister();
145606c3fb27SDimitry Andric       return true;
145706c3fb27SDimitry Andric     }
14580b57cec5SDimitry Andric   }
14590b57cec5SDimitry Andric   return false;
14600b57cec5SDimitry Andric }
14610b57cec5SDimitry Andric 
14620b57cec5SDimitry Andric bool AArch64TargetInfo::validateConstraintModifier(
14630b57cec5SDimitry Andric     StringRef Constraint, char Modifier, unsigned Size,
14640b57cec5SDimitry Andric     std::string &SuggestedModifier) const {
14650b57cec5SDimitry Andric   // Strip off constraint modifiers.
1466647cbc5dSDimitry Andric   Constraint = Constraint.ltrim("=+&");
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric   switch (Constraint[0]) {
14690b57cec5SDimitry Andric   default:
14700b57cec5SDimitry Andric     return true;
14710b57cec5SDimitry Andric   case 'z':
14720b57cec5SDimitry Andric   case 'r': {
14730b57cec5SDimitry Andric     switch (Modifier) {
14740b57cec5SDimitry Andric     case 'x':
14750b57cec5SDimitry Andric     case 'w':
14760b57cec5SDimitry Andric       // For now assume that the person knows what they're
14770b57cec5SDimitry Andric       // doing with the modifier.
14780b57cec5SDimitry Andric       return true;
14790b57cec5SDimitry Andric     default:
14800b57cec5SDimitry Andric       // By default an 'r' constraint will be in the 'x'
14810b57cec5SDimitry Andric       // registers.
14820b57cec5SDimitry Andric       if (Size == 64)
14830b57cec5SDimitry Andric         return true;
14840b57cec5SDimitry Andric 
14856e75b2fbSDimitry Andric       if (Size == 512)
14866e75b2fbSDimitry Andric         return HasLS64;
14876e75b2fbSDimitry Andric 
14880b57cec5SDimitry Andric       SuggestedModifier = "w";
14890b57cec5SDimitry Andric       return false;
14900b57cec5SDimitry Andric     }
14910b57cec5SDimitry Andric   }
14920b57cec5SDimitry Andric   }
14930b57cec5SDimitry Andric }
14940b57cec5SDimitry Andric 
149506c3fb27SDimitry Andric std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
14980b57cec5SDimitry Andric   if (RegNo == 0)
14990b57cec5SDimitry Andric     return 0;
15000b57cec5SDimitry Andric   if (RegNo == 1)
15010b57cec5SDimitry Andric     return 1;
15020b57cec5SDimitry Andric   return -1;
15030b57cec5SDimitry Andric }
15040b57cec5SDimitry Andric 
15050fca6ea1SDimitry Andric bool AArch64TargetInfo::validatePointerAuthKey(
15060fca6ea1SDimitry Andric     const llvm::APSInt &value) const {
15070fca6ea1SDimitry Andric   return 0 <= value && value <= 3;
15080fca6ea1SDimitry Andric }
15090fca6ea1SDimitry Andric 
1510480093f4SDimitry Andric bool AArch64TargetInfo::hasInt128Type() const { return true; }
1511480093f4SDimitry Andric 
15120b57cec5SDimitry Andric AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
15130b57cec5SDimitry Andric                                          const TargetOptions &Opts)
15140b57cec5SDimitry Andric     : AArch64TargetInfo(Triple, Opts) {}
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric void AArch64leTargetInfo::setDataLayout() {
1517480093f4SDimitry Andric   if (getTriple().isOSBinFormatMachO()) {
1518480093f4SDimitry Andric     if(getTriple().isArch32Bit())
15190fca6ea1SDimitry Andric       resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32", "_");
15200b57cec5SDimitry Andric     else
15210fca6ea1SDimitry Andric       resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128-Fn32", "_");
1522480093f4SDimitry Andric   } else
15230fca6ea1SDimitry Andric     resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32");
15240b57cec5SDimitry Andric }
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
15270b57cec5SDimitry Andric                                            MacroBuilder &Builder) const {
15280b57cec5SDimitry Andric   Builder.defineMacro("__AARCH64EL__");
15290b57cec5SDimitry Andric   AArch64TargetInfo::getTargetDefines(Opts, Builder);
15300b57cec5SDimitry Andric }
15310b57cec5SDimitry Andric 
15320b57cec5SDimitry Andric AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
15330b57cec5SDimitry Andric                                          const TargetOptions &Opts)
15340b57cec5SDimitry Andric     : AArch64TargetInfo(Triple, Opts) {}
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
15370b57cec5SDimitry Andric                                            MacroBuilder &Builder) const {
15380b57cec5SDimitry Andric   Builder.defineMacro("__AARCH64EB__");
15390b57cec5SDimitry Andric   Builder.defineMacro("__AARCH_BIG_ENDIAN");
15400b57cec5SDimitry Andric   Builder.defineMacro("__ARM_BIG_ENDIAN");
15410b57cec5SDimitry Andric   AArch64TargetInfo::getTargetDefines(Opts, Builder);
15420b57cec5SDimitry Andric }
15430b57cec5SDimitry Andric 
15440b57cec5SDimitry Andric void AArch64beTargetInfo::setDataLayout() {
15450b57cec5SDimitry Andric   assert(!getTriple().isOSBinFormatMachO());
15460fca6ea1SDimitry Andric   resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32");
15470b57cec5SDimitry Andric }
15480b57cec5SDimitry Andric 
15490b57cec5SDimitry Andric WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
15500b57cec5SDimitry Andric                                                const TargetOptions &Opts)
15510b57cec5SDimitry Andric     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   // This is an LLP64 platform.
15540b57cec5SDimitry Andric   // int:4, long:4, long long:8, long double:8.
15550b57cec5SDimitry Andric   IntWidth = IntAlign = 32;
15560b57cec5SDimitry Andric   LongWidth = LongAlign = 32;
15570b57cec5SDimitry Andric   DoubleAlign = LongLongAlign = 64;
15580b57cec5SDimitry Andric   LongDoubleWidth = LongDoubleAlign = 64;
15590b57cec5SDimitry Andric   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
15600b57cec5SDimitry Andric   IntMaxType = SignedLongLong;
15610b57cec5SDimitry Andric   Int64Type = SignedLongLong;
15620b57cec5SDimitry Andric   SizeType = UnsignedLongLong;
15630b57cec5SDimitry Andric   PtrDiffType = SignedLongLong;
15640b57cec5SDimitry Andric   IntPtrType = SignedLongLong;
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric void WindowsARM64TargetInfo::setDataLayout() {
1568e8d8bef9SDimitry Andric   resetDataLayout(Triple.isOSBinFormatMachO()
15690fca6ea1SDimitry Andric                       ? "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"
15700fca6ea1SDimitry Andric                       : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32",
1571fe6060f1SDimitry Andric                   Triple.isOSBinFormatMachO() ? "_" : "");
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric TargetInfo::BuiltinVaListKind
15750b57cec5SDimitry Andric WindowsARM64TargetInfo::getBuiltinVaListKind() const {
15760b57cec5SDimitry Andric   return TargetInfo::CharPtrBuiltinVaList;
15770b57cec5SDimitry Andric }
15780b57cec5SDimitry Andric 
15790b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult
15800b57cec5SDimitry Andric WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
15810b57cec5SDimitry Andric   switch (CC) {
15820fca6ea1SDimitry Andric   case CC_X86VectorCall:
15830fca6ea1SDimitry Andric     if (getTriple().isWindowsArm64EC())
15840fca6ea1SDimitry Andric       return CCCR_OK;
15850fca6ea1SDimitry Andric     return CCCR_Ignore;
15860b57cec5SDimitry Andric   case CC_X86StdCall:
15870b57cec5SDimitry Andric   case CC_X86ThisCall:
15880b57cec5SDimitry Andric   case CC_X86FastCall:
15890b57cec5SDimitry Andric     return CCCR_Ignore;
15900b57cec5SDimitry Andric   case CC_C:
15910b57cec5SDimitry Andric   case CC_OpenCLKernel:
15920b57cec5SDimitry Andric   case CC_PreserveMost:
15930b57cec5SDimitry Andric   case CC_PreserveAll:
15940fca6ea1SDimitry Andric   case CC_PreserveNone:
15950b57cec5SDimitry Andric   case CC_Swift:
1596fe6060f1SDimitry Andric   case CC_SwiftAsync:
15970b57cec5SDimitry Andric   case CC_Win64:
15980b57cec5SDimitry Andric     return CCCR_OK;
15990b57cec5SDimitry Andric   default:
16000b57cec5SDimitry Andric     return CCCR_Warning;
16010b57cec5SDimitry Andric   }
16020b57cec5SDimitry Andric }
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
16050b57cec5SDimitry Andric                                                    const TargetOptions &Opts)
16060b57cec5SDimitry Andric     : WindowsARM64TargetInfo(Triple, Opts) {
16070b57cec5SDimitry Andric   TheCXXABI.set(TargetCXXABI::Microsoft);
16080b57cec5SDimitry Andric }
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
16110b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
16120b57cec5SDimitry Andric   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
16135f757f3fSDimitry Andric   if (getTriple().isWindowsArm64EC()) {
16145f757f3fSDimitry Andric     Builder.defineMacro("_M_X64", "100");
16155f757f3fSDimitry Andric     Builder.defineMacro("_M_AMD64", "100");
16165f757f3fSDimitry Andric     Builder.defineMacro("_M_ARM64EC", "1");
16175f757f3fSDimitry Andric   } else {
16180b57cec5SDimitry Andric     Builder.defineMacro("_M_ARM64", "1");
16190b57cec5SDimitry Andric   }
16205f757f3fSDimitry Andric }
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric TargetInfo::CallingConvKind
16230b57cec5SDimitry Andric MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
16240b57cec5SDimitry Andric   return CCK_MicrosoftWin64;
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric 
16270fca6ea1SDimitry Andric unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
16280fca6ea1SDimitry Andric                                                      bool HasNonWeakDef) const {
16290fca6ea1SDimitry Andric   unsigned Align =
16300fca6ea1SDimitry Andric       WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   // MSVC does size based alignment for arm64 based on alignment section in
16330b57cec5SDimitry Andric   // below document, replicate that to keep alignment consistent with object
16340b57cec5SDimitry Andric   // files compiled by MSVC.
16350b57cec5SDimitry Andric   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
16360b57cec5SDimitry Andric   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
16370b57cec5SDimitry Andric     Align = std::max(Align, 128u);    // align type at least 16 bytes
16380b57cec5SDimitry Andric   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
16390b57cec5SDimitry Andric     Align = std::max(Align, 64u);     // align type at least 8 butes
16400b57cec5SDimitry Andric   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
16410b57cec5SDimitry Andric     Align = std::max(Align, 32u);     // align type at least 4 bytes
16420b57cec5SDimitry Andric   }
16430b57cec5SDimitry Andric   return Align;
16440b57cec5SDimitry Andric }
16450b57cec5SDimitry Andric 
16460b57cec5SDimitry Andric MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
16470b57cec5SDimitry Andric                                            const TargetOptions &Opts)
16480b57cec5SDimitry Andric     : WindowsARM64TargetInfo(Triple, Opts) {
16490b57cec5SDimitry Andric   TheCXXABI.set(TargetCXXABI::GenericAArch64);
16500b57cec5SDimitry Andric }
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
16530b57cec5SDimitry Andric                                                  const TargetOptions &Opts)
16540b57cec5SDimitry Andric     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
16550b57cec5SDimitry Andric   Int64Type = SignedLongLong;
1656480093f4SDimitry Andric   if (getTriple().isArch32Bit())
1657480093f4SDimitry Andric     IntMaxType = SignedLongLong;
1658480093f4SDimitry Andric 
1659480093f4SDimitry Andric   WCharType = SignedInt;
16600b57cec5SDimitry Andric   UseSignedCharForObjCBool = false;
16610b57cec5SDimitry Andric 
16620b57cec5SDimitry Andric   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
16630b57cec5SDimitry Andric   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
16640b57cec5SDimitry Andric 
1665480093f4SDimitry Andric   UseZeroLengthBitfieldAlignment = false;
1666480093f4SDimitry Andric 
1667480093f4SDimitry Andric   if (getTriple().isArch32Bit()) {
1668480093f4SDimitry Andric     UseBitFieldTypeAlignment = false;
1669480093f4SDimitry Andric     ZeroLengthBitfieldBoundary = 32;
1670480093f4SDimitry Andric     UseZeroLengthBitfieldAlignment = true;
1671480093f4SDimitry Andric     TheCXXABI.set(TargetCXXABI::WatchOS);
1672480093f4SDimitry Andric   } else
1673e8d8bef9SDimitry Andric     TheCXXABI.set(TargetCXXABI::AppleARM64);
16740b57cec5SDimitry Andric }
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
16770b57cec5SDimitry Andric                                            const llvm::Triple &Triple,
16780b57cec5SDimitry Andric                                            MacroBuilder &Builder) const {
16790b57cec5SDimitry Andric   Builder.defineMacro("__AARCH64_SIMD__");
1680480093f4SDimitry Andric   if (Triple.isArch32Bit())
1681480093f4SDimitry Andric     Builder.defineMacro("__ARM64_ARCH_8_32__");
1682480093f4SDimitry Andric   else
16830b57cec5SDimitry Andric     Builder.defineMacro("__ARM64_ARCH_8__");
16840b57cec5SDimitry Andric   Builder.defineMacro("__ARM_NEON__");
16850b57cec5SDimitry Andric   Builder.defineMacro("__REGISTER_PREFIX__", "");
16860b57cec5SDimitry Andric   Builder.defineMacro("__arm64", "1");
16870b57cec5SDimitry Andric   Builder.defineMacro("__arm64__", "1");
16880b57cec5SDimitry Andric 
1689e8d8bef9SDimitry Andric   if (Triple.isArm64e())
1690e8d8bef9SDimitry Andric     Builder.defineMacro("__arm64e__", "1");
1691e8d8bef9SDimitry Andric 
16920b57cec5SDimitry Andric   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
16930b57cec5SDimitry Andric }
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric TargetInfo::BuiltinVaListKind
16960b57cec5SDimitry Andric DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
16970b57cec5SDimitry Andric   return TargetInfo::CharPtrBuiltinVaList;
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric // 64-bit RenderScript is aarch64
17010b57cec5SDimitry Andric RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
17020b57cec5SDimitry Andric                                                    const TargetOptions &Opts)
17030b57cec5SDimitry Andric     : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
17040b57cec5SDimitry Andric                                        Triple.getOSName(),
17050b57cec5SDimitry Andric                                        Triple.getEnvironmentName()),
17060b57cec5SDimitry Andric                           Opts) {
17070b57cec5SDimitry Andric   IsRenderScriptTarget = true;
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
17110b57cec5SDimitry Andric                                                 MacroBuilder &Builder) const {
17120b57cec5SDimitry Andric   Builder.defineMacro("__RENDERSCRIPT__");
17130b57cec5SDimitry Andric   AArch64leTargetInfo::getTargetDefines(Opts, Builder);
17140b57cec5SDimitry Andric }
1715