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