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
setArchFeatures()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
AArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getABI() const2040b57cec5SDimitry Andric StringRef AArch64TargetInfo::getABI() const { return ABI; }
2050b57cec5SDimitry Andric
setABI(const std::string & Name)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
validateTarget(DiagnosticsEngine & Diags) const2150fca6ea1SDimitry 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
validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch) const2310fca6ea1SDimitry 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
validateBranchProtection(StringRef Spec,StringRef,BranchProtectionInfo & BPI,StringRef & Err) const2431fd87a68SDimitry 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
isValidCPUName(StringRef Name) const2670b57cec5SDimitry Andric bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
2680fca6ea1SDimitry Andric return llvm::AArch64::parseCpu(Name).has_value();
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric
setCPU(const std::string & Name)2710b57cec5SDimitry Andric bool AArch64TargetInfo::setCPU(const std::string &Name) {
2720b57cec5SDimitry Andric return isValidCPUName(Name);
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const2750b57cec5SDimitry Andric void AArch64TargetInfo::fillValidCPUList(
2760b57cec5SDimitry Andric SmallVectorImpl<StringRef> &Values) const {
2770b57cec5SDimitry Andric llvm::AArch64::fillValidCPUArchList(Values);
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const2800b57cec5SDimitry Andric void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
2810b57cec5SDimitry Andric MacroBuilder &Builder) const {
2820b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const2850b57cec5SDimitry 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
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const2910b57cec5SDimitry 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
getTargetDefinesARMV84A(const LangOptions & Opts,MacroBuilder & Builder) const2990b57cec5SDimitry 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
getTargetDefinesARMV85A(const LangOptions & Opts,MacroBuilder & Builder) const3050b57cec5SDimitry 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
getTargetDefinesARMV86A(const LangOptions & Opts,MacroBuilder & Builder) const3125ffd83dbSDimitry 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
getTargetDefinesARMV87A(const LangOptions & Opts,MacroBuilder & Builder) const322e8d8bef9SDimitry 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
getTargetDefinesARMV88A(const LangOptions & Opts,MacroBuilder & Builder) const32804eeddc0SDimitry 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
getTargetDefinesARMV89A(const LangOptions & Opts,MacroBuilder & Builder) const334bdd1243dSDimitry 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
getTargetDefinesARMV9A(const LangOptions & Opts,MacroBuilder & Builder) const340349cc55cSDimitry 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
getTargetDefinesARMV91A(const LangOptions & Opts,MacroBuilder & Builder) const346349cc55cSDimitry 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
getTargetDefinesARMV92A(const LangOptions & Opts,MacroBuilder & Builder) const352349cc55cSDimitry 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
getTargetDefinesARMV93A(const LangOptions & Opts,MacroBuilder & Builder) const35804eeddc0SDimitry 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
getTargetDefinesARMV94A(const LangOptions & Opts,MacroBuilder & Builder) const364bdd1243dSDimitry 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
getTargetDefinesARMV95A(const LangOptions & Opts,MacroBuilder & Builder) const3705f757f3fSDimitry 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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const3760b57cec5SDimitry 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
getTargetBuiltins() const6750b57cec5SDimitry 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>>
getVScaleRange(const LangOptions & LangOpts) const681349cc55cSDimitry 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
multiVersionSortPriority(StringRef Name) const692bdd1243dSDimitry 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
multiVersionFeatureCost() const700bdd1243dSDimitry 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
doesFeatureAffectCodeGen(StringRef Name) const70606c3fb27SDimitry 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
validateCpuSupports(StringRef FeatureStr) const713bdd1243dSDimitry 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
hasFeature(StringRef Feature) const7230b57cec5SDimitry 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
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const782bdd1243dSDimitry 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
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)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.
parseTargetAttr(StringRef Features) const1129bdd1243dSDimitry 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
hasBFloat16Type() const1228bdd1243dSDimitry Andric bool AArch64TargetInfo::hasBFloat16Type() const {
12290b57cec5SDimitry Andric return true;
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const12330b57cec5SDimitry 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
isCLZForZeroUndef() const12510b57cec5SDimitry Andric bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
12520b57cec5SDimitry Andric
getBuiltinVaListKind() const12530b57cec5SDimitry 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
getGCCRegNames() const13040b57cec5SDimitry 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
getGCCRegAliases() const13470b57cec5SDimitry 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.
matchAsmCCConstraint(const char * Name)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
convertConstraint(const char * & Constraint) const137606c3fb27SDimitry 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
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const13970b57cec5SDimitry 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
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const14620b57cec5SDimitry 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
getClobbers() const149506c3fb27SDimitry Andric std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
14960b57cec5SDimitry Andric
getEHDataRegisterNumber(unsigned RegNo) const14970b57cec5SDimitry 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
validatePointerAuthKey(const llvm::APSInt & value) const15050fca6ea1SDimitry Andric bool AArch64TargetInfo::validatePointerAuthKey(
15060fca6ea1SDimitry Andric const llvm::APSInt &value) const {
15070fca6ea1SDimitry Andric return 0 <= value && value <= 3;
15080fca6ea1SDimitry Andric }
15090fca6ea1SDimitry Andric
hasInt128Type() const1510480093f4SDimitry Andric bool AArch64TargetInfo::hasInt128Type() const { return true; }
1511480093f4SDimitry Andric
AArch64leTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)15120b57cec5SDimitry Andric AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
15130b57cec5SDimitry Andric const TargetOptions &Opts)
15140b57cec5SDimitry Andric : AArch64TargetInfo(Triple, Opts) {}
15150b57cec5SDimitry Andric
setDataLayout()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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const15260b57cec5SDimitry 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
AArch64beTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)15320b57cec5SDimitry Andric AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
15330b57cec5SDimitry Andric const TargetOptions &Opts)
15340b57cec5SDimitry Andric : AArch64TargetInfo(Triple, Opts) {}
15350b57cec5SDimitry Andric
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const15360b57cec5SDimitry 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
setDataLayout()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
WindowsARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
setDataLayout()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
getBuiltinVaListKind() const15750b57cec5SDimitry Andric WindowsARM64TargetInfo::getBuiltinVaListKind() const {
15760b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList;
15770b57cec5SDimitry Andric }
15780b57cec5SDimitry Andric
15790b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const15800b57cec5SDimitry 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
MicrosoftARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const16100b57cec5SDimitry 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
getCallingConvKind(bool ClangABICompat4) const16230b57cec5SDimitry Andric MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
16240b57cec5SDimitry Andric return CCK_MicrosoftWin64;
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric
getMinGlobalAlign(uint64_t TypeSize,bool HasNonWeakDef) const16270fca6ea1SDimitry 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
MinGWARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
DarwinAArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const16760b57cec5SDimitry 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
getBuiltinVaListKind() const16960b57cec5SDimitry Andric DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
16970b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList;
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andric // 64-bit RenderScript is aarch64
RenderScript64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)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
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const17100b57cec5SDimitry 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