Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
35294 views
//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements AArch64 TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#include "AArch64.h"13#include "clang/Basic/Diagnostic.h"14#include "clang/Basic/LangOptions.h"15#include "clang/Basic/TargetBuiltins.h"16#include "clang/Basic/TargetInfo.h"17#include "llvm/ADT/APSInt.h"18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/StringExtras.h"20#include "llvm/ADT/StringSwitch.h"21#include "llvm/TargetParser/AArch64TargetParser.h"22#include "llvm/TargetParser/ARMTargetParserCommon.h"23#include <optional>2425using namespace clang;26using namespace clang::targets;2728static constexpr Builtin::Info BuiltinInfo[] = {29#define BUILTIN(ID, TYPE, ATTRS) \30{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},31#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \32{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},33#include "clang/Basic/BuiltinsNEON.def"3435#define BUILTIN(ID, TYPE, ATTRS) \36{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},37#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \38{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},39#include "clang/Basic/BuiltinsSVE.def"4041#define BUILTIN(ID, TYPE, ATTRS) \42{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},43#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \44{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},45#include "clang/Basic/BuiltinsSME.def"4647#define BUILTIN(ID, TYPE, ATTRS) \48{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},49#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \50{#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},51#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \52{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},53#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \54{#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},55#include "clang/Basic/BuiltinsAArch64.def"56};5758void AArch64TargetInfo::setArchFeatures() {59if (*ArchInfo == llvm::AArch64::ARMV8R) {60HasDotProd = true;61HasDIT = true;62HasFlagM = true;63HasRCPC = true;64FPU |= NeonMode;65HasCCPP = true;66HasCRC = true;67HasLSE = true;68HasRDM = true;69} else if (ArchInfo->Version.getMajor() == 8) {70if (ArchInfo->Version.getMinor() >= 7u) {71HasWFxT = true;72}73if (ArchInfo->Version.getMinor() >= 6u) {74HasBFloat16 = true;75HasMatMul = true;76}77if (ArchInfo->Version.getMinor() >= 5u) {78HasAlternativeNZCV = true;79HasFRInt3264 = true;80HasSSBS = true;81HasSB = true;82HasPredRes = true;83HasBTI = true;84}85if (ArchInfo->Version.getMinor() >= 4u) {86HasDotProd = true;87HasDIT = true;88HasFlagM = true;89}90if (ArchInfo->Version.getMinor() >= 3u) {91HasRCPC = true;92FPU |= NeonMode;93}94if (ArchInfo->Version.getMinor() >= 2u) {95HasCCPP = true;96}97if (ArchInfo->Version.getMinor() >= 1u) {98HasCRC = true;99HasLSE = true;100HasRDM = true;101}102} else if (ArchInfo->Version.getMajor() == 9) {103if (ArchInfo->Version.getMinor() >= 2u) {104HasWFxT = true;105}106if (ArchInfo->Version.getMinor() >= 1u) {107HasBFloat16 = true;108HasMatMul = true;109}110FPU |= SveMode;111HasSVE2 = true;112HasFullFP16 = true;113HasAlternativeNZCV = true;114HasFRInt3264 = true;115HasSSBS = true;116HasSB = true;117HasPredRes = true;118HasBTI = true;119HasDotProd = true;120HasDIT = true;121HasFlagM = true;122HasRCPC = true;123FPU |= NeonMode;124HasCCPP = true;125HasCRC = true;126HasLSE = true;127HasRDM = true;128}129}130131AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,132const TargetOptions &Opts)133: TargetInfo(Triple), ABI("aapcs") {134if (getTriple().isOSOpenBSD()) {135Int64Type = SignedLongLong;136IntMaxType = SignedLongLong;137} else {138if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())139WCharType = UnsignedInt;140141Int64Type = SignedLong;142IntMaxType = SignedLong;143}144145// All AArch64 implementations support ARMv8 FP, which makes half a legal type.146HasLegalHalfType = true;147HalfArgsAndReturns = true;148HasFloat16 = true;149HasStrictFP = true;150151if (Triple.isArch64Bit())152LongWidth = LongAlign = PointerWidth = PointerAlign = 64;153else154LongWidth = LongAlign = PointerWidth = PointerAlign = 32;155156BitIntMaxAlign = 128;157MaxVectorAlign = 128;158MaxAtomicInlineWidth = 128;159MaxAtomicPromoteWidth = 128;160161LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;162LongDoubleFormat = &llvm::APFloat::IEEEquad();163164BFloat16Width = BFloat16Align = 16;165BFloat16Format = &llvm::APFloat::BFloat();166167// Make __builtin_ms_va_list available.168HasBuiltinMSVaList = true;169170// Make the SVE types available. Note that this deliberately doesn't171// depend on SveMode, since in principle it should be possible to turn172// SVE on and off within a translation unit. It should also be possible173// to compile the global declaration:174//175// __SVInt8_t *ptr;176//177// even without SVE.178HasAArch64SVETypes = true;179180// {} in inline assembly are neon specifiers, not assembly variant181// specifiers.182NoAsmVariants = true;183184// AAPCS gives rules for bitfields. 7.1.7 says: "The container type185// contributes to the alignment of the containing aggregate in the same way186// a plain (non bit-field) member of that type would, without exception for187// zero-sized or anonymous bit-fields."188assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");189UseZeroLengthBitfieldAlignment = true;190191HasUnalignedAccess = true;192193// AArch64 targets default to using the ARM C++ ABI.194TheCXXABI.set(TargetCXXABI::GenericAArch64);195196if (Triple.getOS() == llvm::Triple::Linux)197this->MCountName = "\01_mcount";198else if (Triple.getOS() == llvm::Triple::UnknownOS)199this->MCountName =200Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";201}202203StringRef AArch64TargetInfo::getABI() const { return ABI; }204205bool AArch64TargetInfo::setABI(const std::string &Name) {206if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&207Name != "pauthtest")208return false;209210ABI = Name;211return true;212}213214bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {215if (hasFeature("fp") && ABI == "aapcs-soft") {216// aapcs-soft is not allowed for targets with an FPU, to avoid there being217// two incomatible ABIs.218Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;219return false;220}221if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&222getTriple().getOS() != llvm::Triple::Linux) {223Diags.Report(diag::err_target_unsupported_abi_for_triple)224<< getTriple().getEnvironmentName() << getTriple().getTriple();225return false;226}227return true;228}229230bool AArch64TargetInfo::validateGlobalRegisterVariable(231StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {232if ((RegName == "sp") || RegName.starts_with("x")) {233HasSizeMismatch = RegSize != 64;234return true;235} else if (RegName.starts_with("w")) {236HasSizeMismatch = RegSize != 32;237return true;238}239return false;240}241242bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,243BranchProtectionInfo &BPI,244StringRef &Err) const {245llvm::ARM::ParsedBranchProtection PBP;246if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))247return false;248249BPI.SignReturnAddr =250llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)251.Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)252.Case("all", LangOptions::SignReturnAddressScopeKind::All)253.Default(LangOptions::SignReturnAddressScopeKind::None);254255if (PBP.Key == "a_key")256BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;257else258BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;259260BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;261BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;262BPI.GuardedControlStack = PBP.GuardedControlStack;263return true;264}265266bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {267return llvm::AArch64::parseCpu(Name).has_value();268}269270bool AArch64TargetInfo::setCPU(const std::string &Name) {271return isValidCPUName(Name);272}273274void AArch64TargetInfo::fillValidCPUList(275SmallVectorImpl<StringRef> &Values) const {276llvm::AArch64::fillValidCPUArchList(Values);277}278279void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,280MacroBuilder &Builder) const {281Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");282}283284void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,285MacroBuilder &Builder) const {286// Also include the ARMv8.1 defines287getTargetDefinesARMV81A(Opts, Builder);288}289290void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,291MacroBuilder &Builder) const {292Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");293Builder.defineMacro("__ARM_FEATURE_JCVT", "1");294// Also include the Armv8.2 defines295getTargetDefinesARMV82A(Opts, Builder);296}297298void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,299MacroBuilder &Builder) const {300// Also include the Armv8.3 defines301getTargetDefinesARMV83A(Opts, Builder);302}303304void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,305MacroBuilder &Builder) const {306Builder.defineMacro("__ARM_FEATURE_FRINT", "1");307// Also include the Armv8.4 defines308getTargetDefinesARMV84A(Opts, Builder);309}310311void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,312MacroBuilder &Builder) const {313// Also include the Armv8.5 defines314// FIXME: Armv8.6 makes the following extensions mandatory:315// - __ARM_FEATURE_BF16316// - __ARM_FEATURE_MATMUL_INT8317// Handle them here.318getTargetDefinesARMV85A(Opts, Builder);319}320321void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,322MacroBuilder &Builder) const {323// Also include the Armv8.6 defines324getTargetDefinesARMV86A(Opts, Builder);325}326327void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,328MacroBuilder &Builder) const {329// Also include the Armv8.7 defines330getTargetDefinesARMV87A(Opts, Builder);331}332333void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,334MacroBuilder &Builder) const {335// Also include the Armv8.8 defines336getTargetDefinesARMV88A(Opts, Builder);337}338339void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,340MacroBuilder &Builder) const {341// Armv9-A maps to Armv8.5-A342getTargetDefinesARMV85A(Opts, Builder);343}344345void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,346MacroBuilder &Builder) const {347// Armv9.1-A maps to Armv8.6-A348getTargetDefinesARMV86A(Opts, Builder);349}350351void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,352MacroBuilder &Builder) const {353// Armv9.2-A maps to Armv8.7-A354getTargetDefinesARMV87A(Opts, Builder);355}356357void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,358MacroBuilder &Builder) const {359// Armv9.3-A maps to Armv8.8-A360getTargetDefinesARMV88A(Opts, Builder);361}362363void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,364MacroBuilder &Builder) const {365// Armv9.4-A maps to Armv8.9-A366getTargetDefinesARMV89A(Opts, Builder);367}368369void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,370MacroBuilder &Builder) const {371// Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.372getTargetDefinesARMV94A(Opts, Builder);373}374375void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,376MacroBuilder &Builder) const {377// Target identification.378if (getTriple().isWindowsArm64EC()) {379// Define the same set of macros as would be defined on x86_64 to ensure that380// ARM64EC datatype layouts match those of x86_64 compiled code381Builder.defineMacro("__amd64__");382Builder.defineMacro("__amd64");383Builder.defineMacro("__x86_64");384Builder.defineMacro("__x86_64__");385Builder.defineMacro("__arm64ec__");386} else {387Builder.defineMacro("__aarch64__");388}389390// Inline assembly supports AArch64 flag outputs.391Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");392393std::string CodeModel = getTargetOpts().CodeModel;394if (CodeModel == "default")395CodeModel = "small";396for (char &c : CodeModel)397c = toupper(c);398Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");399400// ACLE predefines. Many can only have one possible value on v8 AArch64.401Builder.defineMacro("__ARM_ACLE", "200");402Builder.defineMacro("__ARM_ARCH",403std::to_string(ArchInfo->Version.getMajor()));404Builder.defineMacro("__ARM_ARCH_PROFILE",405std::string("'") + (char)ArchInfo->Profile + "'");406407Builder.defineMacro("__ARM_64BIT_STATE", "1");408Builder.defineMacro("__ARM_PCS_AAPCS64", "1");409Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");410411Builder.defineMacro("__ARM_FEATURE_CLZ", "1");412Builder.defineMacro("__ARM_FEATURE_FMA", "1");413Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");414Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE415Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility416Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");417Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");418419Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");420421// These macros are set when Clang can parse declarations with these422// attributes.423Builder.defineMacro("__ARM_STATE_ZA", "1");424Builder.defineMacro("__ARM_STATE_ZT0", "1");425426// 0xe implies support for half, single and double precision operations.427if (FPU & FPUMode)428Builder.defineMacro("__ARM_FP", "0xE");429430// PCS specifies this for SysV variants, which is all we support. Other ABIs431// may choose __ARM_FP16_FORMAT_ALTERNATIVE.432Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");433Builder.defineMacro("__ARM_FP16_ARGS", "1");434435if (Opts.UnsafeFPMath)436Builder.defineMacro("__ARM_FP_FAST", "1");437438Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",439Twine(Opts.WCharSize ? Opts.WCharSize : 4));440441Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");442443if (FPU & NeonMode) {444Builder.defineMacro("__ARM_NEON", "1");445// 64-bit NEON supports half, single and double precision operations.446Builder.defineMacro("__ARM_NEON_FP", "0xE");447}448449if (FPU & SveMode)450Builder.defineMacro("__ARM_FEATURE_SVE", "1");451452if ((FPU & NeonMode) && (FPU & SveMode))453Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");454455if (HasSVE2)456Builder.defineMacro("__ARM_FEATURE_SVE2", "1");457458if (HasSVE2p1)459Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");460461if (HasSVE2 && HasSVE2AES)462Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");463464if (HasSVE2 && HasSVE2BitPerm)465Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");466467if (HasSVE2 && HasSVE2SHA3)468Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");469470if (HasSVE2 && HasSVE2SM4)471Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");472473if (HasSVEB16B16)474Builder.defineMacro("__ARM_FEATURE_SVE_B16B16", "1");475476if (HasSME) {477Builder.defineMacro("__ARM_FEATURE_SME");478Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");479}480481if (HasSME2)482Builder.defineMacro("__ARM_FEATURE_SME2", "1");483484if (HasSME2p1)485Builder.defineMacro("__ARM_FEATURE_SME2p1", "1");486487if (HasSMEF16F16)488Builder.defineMacro("__ARM_FEATURE_SME_F16F16", "1");489490if (HasSMEB16B16)491Builder.defineMacro("__ARM_FEATURE_SME_B16B16", "1");492493if (HasCRC)494Builder.defineMacro("__ARM_FEATURE_CRC32", "1");495496if (HasRCPC3)497Builder.defineMacro("__ARM_FEATURE_RCPC", "3");498else if (HasRCPC)499Builder.defineMacro("__ARM_FEATURE_RCPC", "1");500501if (HasFMV)502Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");503504// The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature505// macros for AES, SHA2, SHA3 and SM4506if (HasAES && HasSHA2)507Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");508509if (HasAES)510Builder.defineMacro("__ARM_FEATURE_AES", "1");511512if (HasSHA2)513Builder.defineMacro("__ARM_FEATURE_SHA2", "1");514515if (HasSHA3) {516Builder.defineMacro("__ARM_FEATURE_SHA3", "1");517Builder.defineMacro("__ARM_FEATURE_SHA512", "1");518}519520if (HasSM4) {521Builder.defineMacro("__ARM_FEATURE_SM3", "1");522Builder.defineMacro("__ARM_FEATURE_SM4", "1");523}524525if (HasPAuth)526Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");527528if (HasPAuthLR)529Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");530531if (HasBTI)532Builder.defineMacro("__ARM_FEATURE_BTI", "1");533534if (HasUnalignedAccess)535Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");536537if ((FPU & NeonMode) && HasFullFP16)538Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");539if (HasFullFP16)540Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");541542if (HasDotProd)543Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");544545if (HasMTE)546Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");547548if (HasTME)549Builder.defineMacro("__ARM_FEATURE_TME", "1");550551if (HasMatMul)552Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");553554if (HasLSE)555Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");556557if (HasBFloat16) {558Builder.defineMacro("__ARM_FEATURE_BF16", "1");559Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");560Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");561Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");562}563564if ((FPU & SveMode) && HasBFloat16) {565Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");566}567568if ((FPU & SveMode) && HasMatmulFP64)569Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");570571if ((FPU & SveMode) && HasMatmulFP32)572Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");573574if ((FPU & SveMode) && HasMatMul)575Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");576577if ((FPU & NeonMode) && HasFP16FML)578Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");579580if (Opts.hasSignReturnAddress()) {581// Bitmask:582// 0: Protection using the A key583// 1: Protection using the B key584// 2: Protection including leaf functions585// 3: Protection using PC as a diversifier586unsigned Value = 0;587588if (Opts.isSignReturnAddressWithAKey())589Value |= (1 << 0);590else591Value |= (1 << 1);592593if (Opts.isSignReturnAddressScopeAll())594Value |= (1 << 2);595596if (Opts.BranchProtectionPAuthLR)597Value |= (1 << 3);598599Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));600}601602if (Opts.BranchTargetEnforcement)603Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");604605if (Opts.GuardedControlStack)606Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");607608if (HasLS64)609Builder.defineMacro("__ARM_FEATURE_LS64", "1");610611if (HasRandGen)612Builder.defineMacro("__ARM_FEATURE_RNG", "1");613614if (HasMOPS)615Builder.defineMacro("__ARM_FEATURE_MOPS", "1");616617if (HasD128)618Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");619620if (HasGCS)621Builder.defineMacro("__ARM_FEATURE_GCS", "1");622623if (*ArchInfo == llvm::AArch64::ARMV8_1A)624getTargetDefinesARMV81A(Opts, Builder);625else if (*ArchInfo == llvm::AArch64::ARMV8_2A)626getTargetDefinesARMV82A(Opts, Builder);627else if (*ArchInfo == llvm::AArch64::ARMV8_3A)628getTargetDefinesARMV83A(Opts, Builder);629else if (*ArchInfo == llvm::AArch64::ARMV8_4A)630getTargetDefinesARMV84A(Opts, Builder);631else if (*ArchInfo == llvm::AArch64::ARMV8_5A)632getTargetDefinesARMV85A(Opts, Builder);633else if (*ArchInfo == llvm::AArch64::ARMV8_6A)634getTargetDefinesARMV86A(Opts, Builder);635else if (*ArchInfo == llvm::AArch64::ARMV8_7A)636getTargetDefinesARMV87A(Opts, Builder);637else if (*ArchInfo == llvm::AArch64::ARMV8_8A)638getTargetDefinesARMV88A(Opts, Builder);639else if (*ArchInfo == llvm::AArch64::ARMV8_9A)640getTargetDefinesARMV89A(Opts, Builder);641else if (*ArchInfo == llvm::AArch64::ARMV9A)642getTargetDefinesARMV9A(Opts, Builder);643else if (*ArchInfo == llvm::AArch64::ARMV9_1A)644getTargetDefinesARMV91A(Opts, Builder);645else if (*ArchInfo == llvm::AArch64::ARMV9_2A)646getTargetDefinesARMV92A(Opts, Builder);647else if (*ArchInfo == llvm::AArch64::ARMV9_3A)648getTargetDefinesARMV93A(Opts, Builder);649else if (*ArchInfo == llvm::AArch64::ARMV9_4A)650getTargetDefinesARMV94A(Opts, Builder);651else if (*ArchInfo == llvm::AArch64::ARMV9_5A)652getTargetDefinesARMV95A(Opts, Builder);653654// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.655Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");656Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");657Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");658Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");659Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");660661// Allow detection of fast FMA support.662Builder.defineMacro("__FP_FAST_FMA", "1");663Builder.defineMacro("__FP_FAST_FMAF", "1");664665// C/C++ operators work on both VLS and VLA SVE types666if (FPU & SveMode)667Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");668669if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {670Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));671}672}673674ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {675return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -676Builtin::FirstTSBuiltin);677}678679std::optional<std::pair<unsigned, unsigned>>680AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {681if (LangOpts.VScaleMin || LangOpts.VScaleMax)682return std::pair<unsigned, unsigned>(683LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);684685if (hasFeature("sve"))686return std::pair<unsigned, unsigned>(1, 16);687688return std::nullopt;689}690691unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {692if (Name == "default")693return 0;694if (auto Ext = llvm::AArch64::parseFMVExtension(Name))695return Ext->Priority;696return 0;697}698699unsigned AArch64TargetInfo::multiVersionFeatureCost() const {700// Take the maximum priority as per feature cost, so more features win.701constexpr unsigned MaxFMVPriority = 1000;702return MaxFMVPriority;703}704705bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {706// FMV extensions which imply no backend features do not affect codegen.707if (auto Ext = llvm::AArch64::parseFMVExtension(Name))708return !Ext->Features.empty();709return false;710}711712bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {713// CPU features might be separated by '+', extract them and check714llvm::SmallVector<StringRef, 8> Features;715FeatureStr.split(Features, "+");716for (auto &Feature : Features)717if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())718return false;719return true;720}721722bool AArch64TargetInfo::hasFeature(StringRef Feature) const {723return llvm::StringSwitch<bool>(Feature)724.Cases("aarch64", "arm64", "arm", true)725.Case("fmv", HasFMV)726.Case("fp", FPU & FPUMode)727.Cases("neon", "simd", FPU & NeonMode)728.Case("jscvt", HasJSCVT)729.Case("fcma", HasFCMA)730.Case("rng", HasRandGen)731.Case("flagm", HasFlagM)732.Case("flagm2", HasAlternativeNZCV)733.Case("fp16fml", HasFP16FML)734.Case("dotprod", HasDotProd)735.Case("sm4", HasSM4)736.Case("rdm", HasRDM)737.Case("lse", HasLSE)738.Case("crc", HasCRC)739.Case("sha2", HasSHA2)740.Case("sha3", HasSHA3)741.Cases("aes", "pmull", HasAES)742.Cases("fp16", "fullfp16", HasFullFP16)743.Case("dit", HasDIT)744.Case("dpb", HasCCPP)745.Case("dpb2", HasCCDP)746.Case("rcpc", HasRCPC)747.Case("frintts", HasFRInt3264)748.Case("i8mm", HasMatMul)749.Case("bf16", HasBFloat16)750.Case("sve", FPU & SveMode)751.Case("sve-bf16", FPU & SveMode && HasBFloat16)752.Case("sve-i8mm", FPU & SveMode && HasMatMul)753.Case("sve-b16b16", HasSVEB16B16)754.Case("f32mm", FPU & SveMode && HasMatmulFP32)755.Case("f64mm", FPU & SveMode && HasMatmulFP64)756.Case("sve2", FPU & SveMode && HasSVE2)757.Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)758.Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)759.Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)760.Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)761.Case("sve2p1", FPU & SveMode && HasSVE2p1)762.Case("sme", HasSME)763.Case("sme2", HasSME2)764.Case("sme2p1", HasSME2p1)765.Case("sme-f64f64", HasSMEF64F64)766.Case("sme-i16i64", HasSMEI16I64)767.Case("sme-fa64", HasSMEFA64)768.Case("sme-f16f16", HasSMEF16F16)769.Case("sme-b16b16", HasSMEB16B16)770.Cases("memtag", "memtag2", HasMTE)771.Case("sb", HasSB)772.Case("predres", HasPredRes)773.Cases("ssbs", "ssbs2", HasSSBS)774.Case("bti", HasBTI)775.Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)776.Case("wfxt", HasWFxT)777.Case("rcpc3", HasRCPC3)778.Default(false);779}780781void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,782StringRef Name, bool Enabled) const {783Features[Name] = Enabled;784// If the feature is an architecture feature (like v8.2a), add all previous785// architecture versions and any dependant target features.786const std::optional<llvm::AArch64::ArchInfo> ArchInfo =787llvm::AArch64::ArchInfo::findBySubArch(Name);788789if (!ArchInfo)790return; // Not an architecture, nothing more to do.791792// Disabling an architecture feature does not affect dependent features793if (!Enabled)794return;795796for (const auto *OtherArch : llvm::AArch64::ArchInfos)797if (ArchInfo->implies(*OtherArch))798Features[OtherArch->getSubArch()] = true;799800// Set any features implied by the architecture801std::vector<StringRef> CPUFeats;802if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {803for (auto F : CPUFeats) {804assert(F[0] == '+' && "Expected + in target feature!");805Features[F.drop_front(1)] = true;806}807}808}809810bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,811DiagnosticsEngine &Diags) {812for (const auto &Feature : Features) {813if (Feature == "-fp-armv8")814HasNoFP = true;815if (Feature == "-neon")816HasNoNeon = true;817if (Feature == "-sve")818HasNoSVE = true;819820if (Feature == "+neon" || Feature == "+fp-armv8")821FPU |= NeonMode;822if (Feature == "+jscvt") {823HasJSCVT = true;824FPU |= NeonMode;825}826if (Feature == "+fcma") {827HasFCMA = true;828FPU |= NeonMode;829}830831if (Feature == "+sve") {832FPU |= NeonMode;833FPU |= SveMode;834HasFullFP16 = true;835}836if (Feature == "+sve2") {837FPU |= NeonMode;838FPU |= SveMode;839HasFullFP16 = true;840HasSVE2 = true;841}842if (Feature == "+sve2p1") {843FPU |= NeonMode;844FPU |= SveMode;845HasFullFP16 = true;846HasSVE2 = true;847HasSVE2p1 = true;848}849if (Feature == "+sve2-aes") {850FPU |= NeonMode;851FPU |= SveMode;852HasFullFP16 = true;853HasSVE2 = true;854HasSVE2AES = true;855}856if (Feature == "+sve2-sha3") {857FPU |= NeonMode;858FPU |= SveMode;859HasFullFP16 = true;860HasSVE2 = true;861HasSVE2SHA3 = true;862}863if (Feature == "+sve2-sm4") {864FPU |= NeonMode;865FPU |= SveMode;866HasFullFP16 = true;867HasSVE2 = true;868HasSVE2SM4 = true;869}870if (Feature == "+sve-b16b16")871HasSVEB16B16 = true;872if (Feature == "+sve2-bitperm") {873FPU |= NeonMode;874FPU |= SveMode;875HasFullFP16 = true;876HasSVE2 = true;877HasSVE2BitPerm = true;878}879if (Feature == "+f32mm") {880FPU |= NeonMode;881FPU |= SveMode;882HasFullFP16 = true;883HasMatmulFP32 = true;884}885if (Feature == "+f64mm") {886FPU |= NeonMode;887FPU |= SveMode;888HasFullFP16 = true;889HasMatmulFP64 = true;890}891if (Feature == "+sme") {892HasSME = true;893HasBFloat16 = true;894HasFullFP16 = true;895}896if (Feature == "+sme2") {897HasSME = true;898HasSME2 = true;899HasBFloat16 = true;900HasFullFP16 = true;901}902if (Feature == "+sme2p1") {903HasSME = true;904HasSME2 = true;905HasSME2p1 = true;906HasBFloat16 = true;907HasFullFP16 = true;908}909if (Feature == "+sme-f64f64") {910HasSME = true;911HasSMEF64F64 = true;912HasBFloat16 = true;913HasFullFP16 = true;914}915if (Feature == "+sme-i16i64") {916HasSME = true;917HasSMEI16I64 = true;918HasBFloat16 = true;919HasFullFP16 = true;920}921if (Feature == "+sme-fa64") {922FPU |= NeonMode;923FPU |= SveMode;924HasSME = true;925HasSVE2 = true;926HasSMEFA64 = true;927}928if (Feature == "+sme-f16f16") {929HasSME = true;930HasSME2 = true;931HasBFloat16 = true;932HasFullFP16 = true;933HasSMEF16F16 = true;934}935if (Feature == "+sme-b16b16") {936HasSME = true;937HasSME2 = true;938HasBFloat16 = true;939HasFullFP16 = true;940HasSVEB16B16 = true;941HasSMEB16B16 = true;942}943if (Feature == "+sb")944HasSB = true;945if (Feature == "+predres")946HasPredRes = true;947if (Feature == "+ssbs")948HasSSBS = true;949if (Feature == "+bti")950HasBTI = true;951if (Feature == "+wfxt")952HasWFxT = true;953if (Feature == "-fmv")954HasFMV = false;955if (Feature == "+crc")956HasCRC = true;957if (Feature == "+rcpc")958HasRCPC = true;959if (Feature == "+aes") {960FPU |= NeonMode;961HasAES = true;962}963if (Feature == "+sha2") {964FPU |= NeonMode;965HasSHA2 = true;966}967if (Feature == "+sha3") {968FPU |= NeonMode;969HasSHA2 = true;970HasSHA3 = true;971}972if (Feature == "+rdm") {973FPU |= NeonMode;974HasRDM = true;975}976if (Feature == "+dit")977HasDIT = true;978if (Feature == "+cccp")979HasCCPP = true;980if (Feature == "+ccdp") {981HasCCPP = true;982HasCCDP = true;983}984if (Feature == "+fptoint")985HasFRInt3264 = true;986if (Feature == "+sm4") {987FPU |= NeonMode;988HasSM4 = true;989}990if (Feature == "+strict-align")991HasUnalignedAccess = false;992993// All predecessor archs are added but select the latest one for ArchKind.994if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)995ArchInfo = &llvm::AArch64::ARMV8A;996if (Feature == "+v8.1a" &&997ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)998ArchInfo = &llvm::AArch64::ARMV8_1A;999if (Feature == "+v8.2a" &&1000ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)1001ArchInfo = &llvm::AArch64::ARMV8_2A;1002if (Feature == "+v8.3a" &&1003ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)1004ArchInfo = &llvm::AArch64::ARMV8_3A;1005if (Feature == "+v8.4a" &&1006ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)1007ArchInfo = &llvm::AArch64::ARMV8_4A;1008if (Feature == "+v8.5a" &&1009ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)1010ArchInfo = &llvm::AArch64::ARMV8_5A;1011if (Feature == "+v8.6a" &&1012ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)1013ArchInfo = &llvm::AArch64::ARMV8_6A;1014if (Feature == "+v8.7a" &&1015ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)1016ArchInfo = &llvm::AArch64::ARMV8_7A;1017if (Feature == "+v8.8a" &&1018ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)1019ArchInfo = &llvm::AArch64::ARMV8_8A;1020if (Feature == "+v8.9a" &&1021ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)1022ArchInfo = &llvm::AArch64::ARMV8_9A;1023if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)1024ArchInfo = &llvm::AArch64::ARMV9A;1025if (Feature == "+v9.1a" &&1026ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)1027ArchInfo = &llvm::AArch64::ARMV9_1A;1028if (Feature == "+v9.2a" &&1029ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)1030ArchInfo = &llvm::AArch64::ARMV9_2A;1031if (Feature == "+v9.3a" &&1032ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)1033ArchInfo = &llvm::AArch64::ARMV9_3A;1034if (Feature == "+v9.4a" &&1035ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)1036ArchInfo = &llvm::AArch64::ARMV9_4A;1037if (Feature == "+v9.5a" &&1038ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)1039ArchInfo = &llvm::AArch64::ARMV9_5A;1040if (Feature == "+v8r")1041ArchInfo = &llvm::AArch64::ARMV8R;1042if (Feature == "+fullfp16") {1043FPU |= NeonMode;1044HasFullFP16 = true;1045}1046if (Feature == "+dotprod") {1047FPU |= NeonMode;1048HasDotProd = true;1049}1050if (Feature == "+fp16fml") {1051FPU |= NeonMode;1052HasFullFP16 = true;1053HasFP16FML = true;1054}1055if (Feature == "+mte")1056HasMTE = true;1057if (Feature == "+tme")1058HasTME = true;1059if (Feature == "+pauth")1060HasPAuth = true;1061if (Feature == "+i8mm")1062HasMatMul = true;1063if (Feature == "+bf16")1064HasBFloat16 = true;1065if (Feature == "+lse")1066HasLSE = true;1067if (Feature == "+ls64")1068HasLS64 = true;1069if (Feature == "+rand")1070HasRandGen = true;1071if (Feature == "+flagm")1072HasFlagM = true;1073if (Feature == "+altnzcv") {1074HasFlagM = true;1075HasAlternativeNZCV = true;1076}1077if (Feature == "+mops")1078HasMOPS = true;1079if (Feature == "+d128")1080HasD128 = true;1081if (Feature == "+gcs")1082HasGCS = true;1083if (Feature == "+rcpc3")1084HasRCPC3 = true;1085if (Feature == "+pauth-lr") {1086HasPAuthLR = true;1087HasPAuth = true;1088}1089}10901091// Check features that are manually disabled by command line options.1092// This needs to be checked after architecture-related features are handled,1093// making sure they are properly disabled when required.1094for (const auto &Feature : Features) {1095if (Feature == "-d128")1096HasD128 = false;1097}10981099setDataLayout();1100setArchFeatures();11011102if (HasNoFP) {1103FPU &= ~FPUMode;1104FPU &= ~NeonMode;1105FPU &= ~SveMode;1106}1107if (HasNoNeon) {1108FPU &= ~NeonMode;1109FPU &= ~SveMode;1110}1111if (HasNoSVE)1112FPU &= ~SveMode;11131114return true;1115}11161117// Parse AArch64 Target attributes, which are a comma separated list of:1118// "arch=<arch>" - parsed to features as per -march=..1119// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>1120// "tune=<cpu>" - TuneCPU set to <cpu>1121// "feature", "no-feature" - Add (or remove) feature.1122// "+feature", "+nofeature" - Add (or remove) feature.1123//1124// A feature may correspond to an Extension (anything with a corresponding1125// AEK_), in which case an ExtensionSet is used to parse it and expand its1126// dependencies. If the feature does not yield a successful parse then it1127// is passed through.1128ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {1129ParsedTargetAttr Ret;1130if (Features == "default")1131return Ret;1132SmallVector<StringRef, 1> AttrFeatures;1133Features.split(AttrFeatures, ",");1134bool FoundArch = false;11351136auto SplitAndAddFeatures = [](StringRef FeatString,1137std::vector<std::string> &Features,1138llvm::AArch64::ExtensionSet &FeatureBits) {1139SmallVector<StringRef, 8> SplitFeatures;1140FeatString.split(SplitFeatures, StringRef("+"), -1, false);1141for (StringRef Feature : SplitFeatures) {1142if (FeatureBits.parseModifier(Feature))1143continue;1144// Pass through anything that failed to parse so that we can emit1145// diagnostics, as well as valid internal feature names.1146//1147// FIXME: We should consider rejecting internal feature names like1148// neon, v8a, etc.1149// FIXME: We should consider emitting diagnostics here.1150if (Feature.starts_with("no"))1151Features.push_back("-" + Feature.drop_front(2).str());1152else1153Features.push_back("+" + Feature.str());1154}1155};11561157llvm::AArch64::ExtensionSet FeatureBits;1158// Reconstruct the bitset from the command line option features.1159FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten,1160Ret.Features);11611162for (auto &Feature : AttrFeatures) {1163Feature = Feature.trim();1164if (Feature.starts_with("fpmath="))1165continue;11661167if (Feature.starts_with("branch-protection=")) {1168Ret.BranchProtection = Feature.split('=').second.trim();1169continue;1170}11711172if (Feature.starts_with("arch=")) {1173if (FoundArch)1174Ret.Duplicate = "arch=";1175FoundArch = true;1176std::pair<StringRef, StringRef> Split =1177Feature.split("=").second.trim().split("+");1178const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);11791180// Parse the architecture version, adding the required features to1181// Ret.Features.1182if (!AI)1183continue;1184FeatureBits.addArchDefaults(*AI);1185// Add any extra features, after the +1186SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);1187} else if (Feature.starts_with("cpu=")) {1188if (!Ret.CPU.empty())1189Ret.Duplicate = "cpu=";1190else {1191// Split the cpu string into "cpu=", "cortex-a710" and any remaining1192// "+feat" features.1193std::pair<StringRef, StringRef> Split =1194Feature.split("=").second.trim().split("+");1195Ret.CPU = Split.first;1196if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {1197FeatureBits.addCPUDefaults(*CpuInfo);1198SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);1199}1200}1201} else if (Feature.starts_with("tune=")) {1202if (!Ret.Tune.empty())1203Ret.Duplicate = "tune=";1204else1205Ret.Tune = Feature.split("=").second.trim();1206} else if (Feature.starts_with("+")) {1207SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);1208} else {1209if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))1210continue;1211// Pass through anything that failed to parse so that we can emit1212// diagnostics, as well as valid internal feature names.1213//1214// FIXME: We should consider rejecting internal feature names like1215// neon, v8a, etc.1216// FIXME: We should consider emitting diagnostics here.1217if (Feature.starts_with("no-"))1218Ret.Features.push_back("-" + Feature.drop_front(3).str());1219else1220Ret.Features.push_back("+" + Feature.str());1221}1222}1223FeatureBits.toLLVMFeatureList(Ret.Features);1224return Ret;1225}12261227bool AArch64TargetInfo::hasBFloat16Type() const {1228return true;1229}12301231TargetInfo::CallingConvCheckResult1232AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {1233switch (CC) {1234case CC_C:1235case CC_Swift:1236case CC_SwiftAsync:1237case CC_PreserveMost:1238case CC_PreserveAll:1239case CC_PreserveNone:1240case CC_OpenCLKernel:1241case CC_AArch64VectorCall:1242case CC_AArch64SVEPCS:1243case CC_Win64:1244return CCCR_OK;1245default:1246return CCCR_Warning;1247}1248}12491250bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }12511252TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {1253return TargetInfo::AArch64ABIBuiltinVaList;1254}12551256const char *const AArch64TargetInfo::GCCRegNames[] = {1257// clang-format off12581259// 32-bit Integer registers1260"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",1261"w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",1262"w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",12631264// 64-bit Integer registers1265"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",1266"x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",1267"x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",12681269// 32-bit floating point regsisters1270"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",1271"s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",1272"s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",12731274// 64-bit floating point regsisters1275"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",1276"d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",1277"d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",12781279// Neon vector registers1280"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",1281"v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",1282"v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",12831284// SVE vector registers1285"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",1286"z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",1287"z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",12881289// SVE predicate registers1290"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",1291"p11", "p12", "p13", "p14", "p15",12921293// SVE predicate-as-counter registers1294"pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",1295"pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",12961297// SME registers1298"za", "zt0",12991300// clang-format on1301};13021303ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {1304return llvm::ArrayRef(GCCRegNames);1305}13061307const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {1308{{"w31"}, "wsp"},1309{{"x31"}, "sp"},1310// GCC rN registers are aliases of xN registers.1311{{"r0"}, "x0"},1312{{"r1"}, "x1"},1313{{"r2"}, "x2"},1314{{"r3"}, "x3"},1315{{"r4"}, "x4"},1316{{"r5"}, "x5"},1317{{"r6"}, "x6"},1318{{"r7"}, "x7"},1319{{"r8"}, "x8"},1320{{"r9"}, "x9"},1321{{"r10"}, "x10"},1322{{"r11"}, "x11"},1323{{"r12"}, "x12"},1324{{"r13"}, "x13"},1325{{"r14"}, "x14"},1326{{"r15"}, "x15"},1327{{"r16"}, "x16"},1328{{"r17"}, "x17"},1329{{"r18"}, "x18"},1330{{"r19"}, "x19"},1331{{"r20"}, "x20"},1332{{"r21"}, "x21"},1333{{"r22"}, "x22"},1334{{"r23"}, "x23"},1335{{"r24"}, "x24"},1336{{"r25"}, "x25"},1337{{"r26"}, "x26"},1338{{"r27"}, "x27"},1339{{"r28"}, "x28"},1340{{"r29", "x29"}, "fp"},1341{{"r30", "x30"}, "lr"},1342// The S/D/Q and W/X registers overlap, but aren't really aliases; we1343// don't want to substitute one of these for a different-sized one.1344};13451346ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {1347return llvm::ArrayRef(GCCRegAliases);1348}13491350// Returns the length of cc constraint.1351static unsigned matchAsmCCConstraint(const char *Name) {1352constexpr unsigned len = 5;1353auto RV = llvm::StringSwitch<unsigned>(Name)1354.Case("@cceq", len)1355.Case("@ccne", len)1356.Case("@cchs", len)1357.Case("@cccs", len)1358.Case("@cccc", len)1359.Case("@cclo", len)1360.Case("@ccmi", len)1361.Case("@ccpl", len)1362.Case("@ccvs", len)1363.Case("@ccvc", len)1364.Case("@cchi", len)1365.Case("@ccls", len)1366.Case("@ccge", len)1367.Case("@cclt", len)1368.Case("@ccgt", len)1369.Case("@ccle", len)1370.Default(0);1371return RV;1372}13731374std::string1375AArch64TargetInfo::convertConstraint(const char *&Constraint) const {1376std::string R;1377switch (*Constraint) {1378case 'U': // Three-character constraint; add "@3" hint for later parsing.1379R = std::string("@3") + std::string(Constraint, 3);1380Constraint += 2;1381break;1382case '@':1383if (const unsigned Len = matchAsmCCConstraint(Constraint)) {1384std::string Converted = "{" + std::string(Constraint, Len) + "}";1385Constraint += Len - 1;1386return Converted;1387}1388return std::string(1, *Constraint);1389default:1390R = TargetInfo::convertConstraint(Constraint);1391break;1392}1393return R;1394}13951396bool AArch64TargetInfo::validateAsmConstraint(1397const char *&Name, TargetInfo::ConstraintInfo &Info) const {1398switch (*Name) {1399default:1400return false;1401case 'w': // Floating point and SIMD registers (V0-V31)1402Info.setAllowsRegister();1403return true;1404case 'I': // Constant that can be used with an ADD instruction1405case 'J': // Constant that can be used with a SUB instruction1406case 'K': // Constant that can be used with a 32-bit logical instruction1407case 'L': // Constant that can be used with a 64-bit logical instruction1408case 'M': // Constant that can be used as a 32-bit MOV immediate1409case 'N': // Constant that can be used as a 64-bit MOV immediate1410case 'Y': // Floating point constant zero1411case 'Z': // Integer constant zero1412return true;1413case 'Q': // A memory reference with base register and no offset1414Info.setAllowsMemory();1415return true;1416case 'S': // A symbolic address1417Info.setAllowsRegister();1418return true;1419case 'U':1420if (Name[1] == 'p' &&1421(Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {1422// SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)1423Info.setAllowsRegister();1424Name += 2;1425return true;1426}1427if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {1428// Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)1429Info.setAllowsRegister();1430Name += 2;1431return true;1432}1433// Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.1434// Utf: A memory address suitable for ldp/stp in TF mode.1435// Usa: An absolute symbolic address.1436// Ush: The high part (bits 32:12) of a pc-relative symbolic address.14371438// Better to return an error saying that it's an unrecognised constraint1439// even if this is a valid constraint in gcc.1440return false;1441case 'z': // Zero register, wzr or xzr1442Info.setAllowsRegister();1443return true;1444case 'x': // Floating point and SIMD registers (V0-V15)1445Info.setAllowsRegister();1446return true;1447case 'y': // SVE registers (V0-V7)1448Info.setAllowsRegister();1449return true;1450case '@':1451// CC condition1452if (const unsigned Len = matchAsmCCConstraint(Name)) {1453Name += Len - 1;1454Info.setAllowsRegister();1455return true;1456}1457}1458return false;1459}14601461bool AArch64TargetInfo::validateConstraintModifier(1462StringRef Constraint, char Modifier, unsigned Size,1463std::string &SuggestedModifier) const {1464// Strip off constraint modifiers.1465Constraint = Constraint.ltrim("=+&");14661467switch (Constraint[0]) {1468default:1469return true;1470case 'z':1471case 'r': {1472switch (Modifier) {1473case 'x':1474case 'w':1475// For now assume that the person knows what they're1476// doing with the modifier.1477return true;1478default:1479// By default an 'r' constraint will be in the 'x'1480// registers.1481if (Size == 64)1482return true;14831484if (Size == 512)1485return HasLS64;14861487SuggestedModifier = "w";1488return false;1489}1490}1491}1492}14931494std::string_view AArch64TargetInfo::getClobbers() const { return ""; }14951496int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {1497if (RegNo == 0)1498return 0;1499if (RegNo == 1)1500return 1;1501return -1;1502}15031504bool AArch64TargetInfo::validatePointerAuthKey(1505const llvm::APSInt &value) const {1506return 0 <= value && value <= 3;1507}15081509bool AArch64TargetInfo::hasInt128Type() const { return true; }15101511AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,1512const TargetOptions &Opts)1513: AArch64TargetInfo(Triple, Opts) {}15141515void AArch64leTargetInfo::setDataLayout() {1516if (getTriple().isOSBinFormatMachO()) {1517if(getTriple().isArch32Bit())1518resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32", "_");1519else1520resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128-Fn32", "_");1521} else1522resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32");1523}15241525void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,1526MacroBuilder &Builder) const {1527Builder.defineMacro("__AARCH64EL__");1528AArch64TargetInfo::getTargetDefines(Opts, Builder);1529}15301531AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,1532const TargetOptions &Opts)1533: AArch64TargetInfo(Triple, Opts) {}15341535void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,1536MacroBuilder &Builder) const {1537Builder.defineMacro("__AARCH64EB__");1538Builder.defineMacro("__AARCH_BIG_ENDIAN");1539Builder.defineMacro("__ARM_BIG_ENDIAN");1540AArch64TargetInfo::getTargetDefines(Opts, Builder);1541}15421543void AArch64beTargetInfo::setDataLayout() {1544assert(!getTriple().isOSBinFormatMachO());1545resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32");1546}15471548WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,1549const TargetOptions &Opts)1550: WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {15511552// This is an LLP64 platform.1553// int:4, long:4, long long:8, long double:8.1554IntWidth = IntAlign = 32;1555LongWidth = LongAlign = 32;1556DoubleAlign = LongLongAlign = 64;1557LongDoubleWidth = LongDoubleAlign = 64;1558LongDoubleFormat = &llvm::APFloat::IEEEdouble();1559IntMaxType = SignedLongLong;1560Int64Type = SignedLongLong;1561SizeType = UnsignedLongLong;1562PtrDiffType = SignedLongLong;1563IntPtrType = SignedLongLong;1564}15651566void WindowsARM64TargetInfo::setDataLayout() {1567resetDataLayout(Triple.isOSBinFormatMachO()1568? "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"1569: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32",1570Triple.isOSBinFormatMachO() ? "_" : "");1571}15721573TargetInfo::BuiltinVaListKind1574WindowsARM64TargetInfo::getBuiltinVaListKind() const {1575return TargetInfo::CharPtrBuiltinVaList;1576}15771578TargetInfo::CallingConvCheckResult1579WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {1580switch (CC) {1581case CC_X86VectorCall:1582if (getTriple().isWindowsArm64EC())1583return CCCR_OK;1584return CCCR_Ignore;1585case CC_X86StdCall:1586case CC_X86ThisCall:1587case CC_X86FastCall:1588return CCCR_Ignore;1589case CC_C:1590case CC_OpenCLKernel:1591case CC_PreserveMost:1592case CC_PreserveAll:1593case CC_PreserveNone:1594case CC_Swift:1595case CC_SwiftAsync:1596case CC_Win64:1597return CCCR_OK;1598default:1599return CCCR_Warning;1600}1601}16021603MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,1604const TargetOptions &Opts)1605: WindowsARM64TargetInfo(Triple, Opts) {1606TheCXXABI.set(TargetCXXABI::Microsoft);1607}16081609void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,1610MacroBuilder &Builder) const {1611WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);1612if (getTriple().isWindowsArm64EC()) {1613Builder.defineMacro("_M_X64", "100");1614Builder.defineMacro("_M_AMD64", "100");1615Builder.defineMacro("_M_ARM64EC", "1");1616} else {1617Builder.defineMacro("_M_ARM64", "1");1618}1619}16201621TargetInfo::CallingConvKind1622MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {1623return CCK_MicrosoftWin64;1624}16251626unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,1627bool HasNonWeakDef) const {1628unsigned Align =1629WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);16301631// MSVC does size based alignment for arm64 based on alignment section in1632// below document, replicate that to keep alignment consistent with object1633// files compiled by MSVC.1634// https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions1635if (TypeSize >= 512) { // TypeSize >= 64 bytes1636Align = std::max(Align, 128u); // align type at least 16 bytes1637} else if (TypeSize >= 64) { // TypeSize >= 8 bytes1638Align = std::max(Align, 64u); // align type at least 8 butes1639} else if (TypeSize >= 16) { // TypeSize >= 2 bytes1640Align = std::max(Align, 32u); // align type at least 4 bytes1641}1642return Align;1643}16441645MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,1646const TargetOptions &Opts)1647: WindowsARM64TargetInfo(Triple, Opts) {1648TheCXXABI.set(TargetCXXABI::GenericAArch64);1649}16501651DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,1652const TargetOptions &Opts)1653: DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {1654Int64Type = SignedLongLong;1655if (getTriple().isArch32Bit())1656IntMaxType = SignedLongLong;16571658WCharType = SignedInt;1659UseSignedCharForObjCBool = false;16601661LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;1662LongDoubleFormat = &llvm::APFloat::IEEEdouble();16631664UseZeroLengthBitfieldAlignment = false;16651666if (getTriple().isArch32Bit()) {1667UseBitFieldTypeAlignment = false;1668ZeroLengthBitfieldBoundary = 32;1669UseZeroLengthBitfieldAlignment = true;1670TheCXXABI.set(TargetCXXABI::WatchOS);1671} else1672TheCXXABI.set(TargetCXXABI::AppleARM64);1673}16741675void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,1676const llvm::Triple &Triple,1677MacroBuilder &Builder) const {1678Builder.defineMacro("__AARCH64_SIMD__");1679if (Triple.isArch32Bit())1680Builder.defineMacro("__ARM64_ARCH_8_32__");1681else1682Builder.defineMacro("__ARM64_ARCH_8__");1683Builder.defineMacro("__ARM_NEON__");1684Builder.defineMacro("__REGISTER_PREFIX__", "");1685Builder.defineMacro("__arm64", "1");1686Builder.defineMacro("__arm64__", "1");16871688if (Triple.isArm64e())1689Builder.defineMacro("__arm64e__", "1");16901691getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);1692}16931694TargetInfo::BuiltinVaListKind1695DarwinAArch64TargetInfo::getBuiltinVaListKind() const {1696return TargetInfo::CharPtrBuiltinVaList;1697}16981699// 64-bit RenderScript is aarch641700RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,1701const TargetOptions &Opts)1702: AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),1703Triple.getOSName(),1704Triple.getEnvironmentName()),1705Opts) {1706IsRenderScriptTarget = true;1707}17081709void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,1710MacroBuilder &Builder) const {1711Builder.defineMacro("__RENDERSCRIPT__");1712AArch64leTargetInfo::getTargetDefines(Opts, Builder);1713}171417151716