1839 lines · cpp
1//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements AArch64 TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#include "AArch64.h"14#include "clang/Basic/Diagnostic.h"15#include "clang/Basic/LangOptions.h"16#include "clang/Basic/TargetBuiltins.h"17#include "clang/Basic/TargetInfo.h"18#include "llvm/ADT/APSInt.h"19#include "llvm/ADT/ArrayRef.h"20#include "llvm/ADT/StringSwitch.h"21#include "llvm/TargetParser/AArch64TargetParser.h"22#include "llvm/TargetParser/ARMTargetParserCommon.h"23#include <optional>24 25using namespace clang;26using namespace clang::targets;27 28static constexpr int NumNeonBuiltins =29 NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin;30static constexpr int NumFp16Builtins =31 NEON::FirstTSBuiltin - NEON::FirstFp16Builtin;32static constexpr int NumSVEBuiltins =33 SVE::FirstNeonBridgeBuiltin - NEON::FirstTSBuiltin;34static constexpr int NumSVENeonBridgeBuiltins =35 SVE::FirstTSBuiltin - SVE::FirstNeonBridgeBuiltin;36static constexpr int NumSMEBuiltins = SME::FirstTSBuiltin - SVE::FirstTSBuiltin;37static constexpr int NumAArch64Builtins =38 AArch64::LastTSBuiltin - SME::FirstTSBuiltin;39static constexpr int NumBuiltins =40 AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;41static_assert(NumBuiltins ==42 (NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins +43 NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins));44 45namespace clang {46namespace NEON {47#define GET_NEON_BUILTIN_STR_TABLE48#include "clang/Basic/arm_neon.inc"49#undef GET_NEON_BUILTIN_STR_TABLE50 51static constexpr std::array<Builtin::Info, NumNeonBuiltins> BuiltinInfos = {52#define GET_NEON_BUILTIN_INFOS53#include "clang/Basic/arm_neon.inc"54#undef GET_NEON_BUILTIN_INFOS55};56 57namespace FP16 {58#define GET_NEON_BUILTIN_STR_TABLE59#include "clang/Basic/arm_fp16.inc"60#undef GET_NEON_BUILTIN_STR_TABLE61 62static constexpr std::array<Builtin::Info, NumFp16Builtins> BuiltinInfos = {63#define GET_NEON_BUILTIN_INFOS64#include "clang/Basic/arm_fp16.inc"65#undef GET_NEON_BUILTIN_INFOS66};67} // namespace FP1668} // namespace NEON69 70namespace SVE {71#define GET_SVE_BUILTIN_STR_TABLE72#include "clang/Basic/arm_sve_builtins.inc"73#undef GET_SVE_BUILTIN_STR_TABLE74 75static constexpr std::array<Builtin::Info, NumSVEBuiltins> BuiltinInfos = {76#define GET_SVE_BUILTIN_INFOS77#include "clang/Basic/arm_sve_builtins.inc"78#undef GET_SVE_BUILTIN_INFOS79};80} // namespace SVE81 82namespace SME {83#define GET_SME_BUILTIN_STR_TABLE84#include "clang/Basic/arm_sme_builtins.inc"85#undef GET_SME_BUILTIN_STR_TABLE86 87static constexpr std::array<Builtin::Info, NumSMEBuiltins> BuiltinInfos = {88#define GET_SME_BUILTIN_INFOS89#include "clang/Basic/arm_sme_builtins.inc"90#undef GET_SME_BUILTIN_INFOS91};92} // namespace SME93} // namespace clang94 95static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings =96 CLANG_BUILTIN_STR_TABLE_START97#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE98#define GET_SVE_BUILTINS99#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"100#undef GET_SVE_BUILTINS101#undef TARGET_BUILTIN102 ;103static constexpr llvm::StringTable BuiltinAArch64Strings =104 CLANG_BUILTIN_STR_TABLE_START105#define BUILTIN CLANG_BUILTIN_STR_TABLE106#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE107#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE108#include "clang/Basic/BuiltinsAArch64.def"109 ;110 111static constexpr auto BuiltinSVENeonBridgeInfos =112 Builtin::MakeInfos<NumSVENeonBridgeBuiltins>({113#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY114#define GET_SVE_BUILTINS115#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"116#undef GET_SVE_BUILTINS117#undef TARGET_BUILTIN118 });119static constexpr auto BuiltinAArch64Infos =120 Builtin::MakeInfos<NumAArch64Builtins>({121#define BUILTIN CLANG_BUILTIN_ENTRY122#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY123#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY124#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY125#include "clang/Basic/BuiltinsAArch64.def"126 });127 128AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,129 const TargetOptions &Opts)130 : TargetInfo(Triple), ABI("aapcs") {131 if (getTriple().isOSOpenBSD()) {132 Int64Type = SignedLongLong;133 IntMaxType = SignedLongLong;134 } else {135 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())136 WCharType = UnsignedInt;137 138 Int64Type = SignedLong;139 IntMaxType = SignedLong;140 }141 142 AddrSpaceMap = &ARM64AddrSpaceMap;143 144 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.145 HasFastHalfType = true;146 HalfArgsAndReturns = true;147 HasFloat16 = true;148 HasStrictFP = true;149 150 if (Triple.isArch64Bit())151 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;152 else153 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;154 155 BitIntMaxAlign = 128;156 MaxVectorAlign = 128;157 MaxAtomicInlineWidth = 128;158 MaxAtomicPromoteWidth = 128;159 160 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;161 LongDoubleFormat = &llvm::APFloat::IEEEquad();162 163 BFloat16Width = BFloat16Align = 16;164 BFloat16Format = &llvm::APFloat::BFloat();165 166 // Make __builtin_ms_va_list available.167 HasBuiltinMSVaList = true;168 169 // Make the Neon ACLE and SVE types available. Note that this deliberately170 // doesn't depend on SveMode, since in principle it should be possible to turn171 // SVE on and off within a translation unit. It should also be possible172 // to compile the global declaration:173 //174 // __SVInt8_t *ptr;175 //176 // even without SVE.177 HasAArch64ACLETypes = true;178 179 // {} in inline assembly are neon specifiers, not assembly variant180 // specifiers.181 NoAsmVariants = true;182 183 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type184 // contributes to the alignment of the containing aggregate in the same way185 // a plain (non bit-field) member of that type would, without exception for186 // zero-sized or anonymous bit-fields."187 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");188 UseZeroLengthBitfieldAlignment = true;189 190 // AAPCS64 allows any "fundamental integer data type" to be used for191 // over-sized bitfields, which includes 128-bit integers.192 LargestOverSizedBitfieldContainer = 128;193 194 HasUnalignedAccess = true;195 196 // AArch64 targets default to using the ARM C++ ABI.197 TheCXXABI.set(TargetCXXABI::GenericAArch64);198 199 if (Triple.getOS() == llvm::Triple::Linux)200 this->MCountName = "\01_mcount";201 else if (Triple.getOS() == llvm::Triple::UnknownOS)202 this->MCountName =203 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";204}205 206StringRef AArch64TargetInfo::getABI() const { return ABI; }207 208bool AArch64TargetInfo::setABI(const std::string &Name) {209 if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")210 return false;211 212 ABI = Name;213 return true;214}215 216bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {217 if (hasFeature("fp") && ABI == "aapcs-soft") {218 // aapcs-soft is not allowed for targets with an FPU, to avoid there being219 // two incomatible ABIs.220 Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;221 return false;222 }223 return true;224}225 226bool AArch64TargetInfo::validateGlobalRegisterVariable(227 StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {228 if (RegName == "sp") {229 HasSizeMismatch = RegSize != 64;230 return true;231 }232 if (RegName.starts_with("w"))233 HasSizeMismatch = RegSize != 32;234 else if (RegName.starts_with("x"))235 HasSizeMismatch = RegSize != 64;236 else237 return false;238 StringRef RegNum = RegName.drop_front();239 // Check if the register is reserved. See also240 // AArch64TargetLowering::getRegisterByName().241 return RegNum == "0" ||242 (RegNum == "18" &&243 llvm::AArch64::isX18ReservedByDefault(getTriple())) ||244 getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str());245}246 247bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,248 BranchProtectionInfo &BPI,249 const LangOptions &LO,250 StringRef &Err) const {251 llvm::ARM::ParsedBranchProtection PBP;252 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))253 return false;254 255 // GCS is currently untested with ptrauth-returns, but enabling this could be256 // allowed in future after testing with a suitable system.257 if (LO.PointerAuthReturns &&258 (PBP.Scope != "none" || PBP.BranchProtectionPAuthLR ||259 PBP.GuardedControlStack))260 return false;261 262 BPI.SignReturnAddr =263 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)264 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)265 .Case("all", LangOptions::SignReturnAddressScopeKind::All)266 .Default(LangOptions::SignReturnAddressScopeKind::None);267 268 if (PBP.Key == "a_key")269 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;270 else271 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;272 273 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;274 BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;275 BPI.GuardedControlStack = PBP.GuardedControlStack;276 return true;277}278 279bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {280 return llvm::AArch64::parseCpu(Name).has_value();281}282 283bool AArch64TargetInfo::setCPU(const std::string &Name) {284 return isValidCPUName(Name);285}286 287void AArch64TargetInfo::fillValidCPUList(288 SmallVectorImpl<StringRef> &Values) const {289 llvm::AArch64::fillValidCPUArchList(Values);290}291 292void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,293 MacroBuilder &Builder) const {294 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");295}296 297void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,298 MacroBuilder &Builder) const {299 // Also include the ARMv8.1 defines300 getTargetDefinesARMV81A(Opts, Builder);301}302 303void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,304 MacroBuilder &Builder) const {305 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");306 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");307 // Also include the Armv8.2 defines308 getTargetDefinesARMV82A(Opts, Builder);309}310 311void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,312 MacroBuilder &Builder) const {313 // Also include the Armv8.3 defines314 getTargetDefinesARMV83A(Opts, Builder);315}316 317void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,318 MacroBuilder &Builder) const {319 Builder.defineMacro("__ARM_FEATURE_FRINT", "1");320 // Also include the Armv8.4 defines321 getTargetDefinesARMV84A(Opts, Builder);322}323 324void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,325 MacroBuilder &Builder) const {326 // Also include the Armv8.5 defines327 // FIXME: Armv8.6 makes the following extensions mandatory:328 // - __ARM_FEATURE_BF16329 // - __ARM_FEATURE_MATMUL_INT8330 // Handle them here.331 getTargetDefinesARMV85A(Opts, Builder);332}333 334void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,335 MacroBuilder &Builder) const {336 // Also include the Armv8.6 defines337 getTargetDefinesARMV86A(Opts, Builder);338}339 340void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,341 MacroBuilder &Builder) const {342 // Also include the Armv8.7 defines343 getTargetDefinesARMV87A(Opts, Builder);344}345 346void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,347 MacroBuilder &Builder) const {348 // Also include the Armv8.8 defines349 getTargetDefinesARMV88A(Opts, Builder);350}351 352void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,353 MacroBuilder &Builder) const {354 // Armv9-A maps to Armv8.5-A355 getTargetDefinesARMV85A(Opts, Builder);356}357 358void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,359 MacroBuilder &Builder) const {360 // Armv9.1-A maps to Armv8.6-A361 getTargetDefinesARMV86A(Opts, Builder);362}363 364void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,365 MacroBuilder &Builder) const {366 // Armv9.2-A maps to Armv8.7-A367 getTargetDefinesARMV87A(Opts, Builder);368}369 370void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,371 MacroBuilder &Builder) const {372 // Armv9.3-A maps to Armv8.8-A373 getTargetDefinesARMV88A(Opts, Builder);374}375 376void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,377 MacroBuilder &Builder) const {378 // Armv9.4-A maps to Armv8.9-A379 getTargetDefinesARMV89A(Opts, Builder);380}381 382void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,383 MacroBuilder &Builder) const {384 // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.385 getTargetDefinesARMV94A(Opts, Builder);386}387 388void AArch64TargetInfo::getTargetDefinesARMV96A(const LangOptions &Opts,389 MacroBuilder &Builder) const {390 // Armv9.6-A does not have a v8.* equivalent, but is a superset of v9.5-A.391 getTargetDefinesARMV95A(Opts, Builder);392}393 394void AArch64TargetInfo::getTargetDefinesARMV97A(const LangOptions &Opts,395 MacroBuilder &Builder) const {396 // Armv9.7-A does not have a v8.* equivalent, but is a superset of v9.6-A.397 getTargetDefinesARMV96A(Opts, Builder);398}399 400void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,401 MacroBuilder &Builder) const {402 // Target identification.403 if (getTriple().isWindowsArm64EC()) {404 // Define the same set of macros as would be defined on x86_64 to ensure that405 // ARM64EC datatype layouts match those of x86_64 compiled code406 Builder.defineMacro("__amd64__");407 Builder.defineMacro("__amd64");408 Builder.defineMacro("__x86_64");409 Builder.defineMacro("__x86_64__");410 Builder.defineMacro("__arm64ec__");411 } else {412 Builder.defineMacro("__aarch64__");413 }414 415 // Inline assembly supports AArch64 flag outputs.416 Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");417 418 std::string CodeModel = getTargetOpts().CodeModel;419 if (CodeModel == "default")420 CodeModel = "small";421 for (char &c : CodeModel)422 c = toupper(c);423 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");424 425 // ACLE predefines. Many can only have one possible value on v8 AArch64.426 Builder.defineMacro("__ARM_ACLE_VERSION(year, quarter, patch)",427 "(100 * (year) + 10 * (quarter) + (patch))");428#define ARM_ACLE_VERSION(Y, Q, P) (100 * (Y) + 10 * (Q) + (P))429 Builder.defineMacro("__ARM_ACLE", Twine(ARM_ACLE_VERSION(2024, 2, 0)));430 Builder.defineMacro("__FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL",431 Twine(ARM_ACLE_VERSION(2024, 3, 0)));432#undef ARM_ACLE_VERSION433 Builder.defineMacro("__ARM_ARCH",434 std::to_string(ArchInfo->Version.getMajor()));435 Builder.defineMacro("__ARM_ARCH_PROFILE",436 std::string("'") + (char)ArchInfo->Profile + "'");437 438 Builder.defineMacro("__ARM_64BIT_STATE", "1");439 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");440 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");441 442 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");443 Builder.defineMacro("__ARM_FEATURE_FMA", "1");444 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");445 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE446 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility447 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");448 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");449 450 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");451 452 // These macros are set when Clang can parse declarations with these453 // attributes.454 Builder.defineMacro("__ARM_STATE_ZA", "1");455 Builder.defineMacro("__ARM_STATE_ZT0", "1");456 457 // 0xe implies support for half, single and double precision operations.458 if (FPU & FPUMode)459 Builder.defineMacro("__ARM_FP", "0xE");460 461 // PCS specifies this for SysV variants, which is all we support. Other ABIs462 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.463 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");464 Builder.defineMacro("__ARM_FP16_ARGS", "1");465 466 // Clang supports arm_neon_sve_bridge.h467 Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");468 469 if (Opts.UnsafeFPMath)470 Builder.defineMacro("__ARM_FP_FAST", "1");471 472 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",473 Twine(Opts.WCharSize ? Opts.WCharSize : 4));474 475 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");476 477 if (FPU & NeonMode) {478 Builder.defineMacro("__ARM_NEON", "1");479 // 64-bit NEON supports half, single and double precision operations.480 Builder.defineMacro("__ARM_NEON_FP", "0xE");481 }482 483 if (FPU & SveMode)484 Builder.defineMacro("__ARM_FEATURE_SVE", "1");485 486 if (HasSVE2)487 Builder.defineMacro("__ARM_FEATURE_SVE2", "1");488 489 if (HasSVE2p1)490 Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");491 492 if (HasSVE2 && HasSVEAES)493 Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");494 495 if (HasSVE2 && HasSVEBitPerm)496 Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");497 498 if (HasSVE2 && HasSVE2SHA3)499 Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");500 501 if (HasSVE2 && HasSVE2SM4)502 Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");503 504 if (HasSVEB16B16)505 Builder.defineMacro("__ARM_FEATURE_SVE_B16B16", "1");506 507 if (HasSME) {508 Builder.defineMacro("__ARM_FEATURE_SME");509 Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");510 }511 512 if (HasSME2)513 Builder.defineMacro("__ARM_FEATURE_SME2", "1");514 515 if (HasSME2p1)516 Builder.defineMacro("__ARM_FEATURE_SME2p1", "1");517 518 if (HasSMEF16F16)519 Builder.defineMacro("__ARM_FEATURE_SME_F16F16", "1");520 521 if (HasSMEB16B16)522 Builder.defineMacro("__ARM_FEATURE_SME_B16B16", "1");523 524 if (HasFP8)525 Builder.defineMacro("__ARM_FEATURE_FP8", "1");526 527 if (HasFP8FMA)528 Builder.defineMacro("__ARM_FEATURE_FP8FMA", "1");529 530 if (HasFP8DOT2)531 Builder.defineMacro("__ARM_FEATURE_FP8DOT2", "1");532 533 if (HasFP8DOT4)534 Builder.defineMacro("__ARM_FEATURE_FP8DOT4", "1");535 536 if (HasSSVE_FP8DOT2)537 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT2", "1");538 539 if (HasSSVE_FP8DOT4)540 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT4", "1");541 542 if (HasSSVE_FP8FMA)543 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8FMA", "1");544 545 if (HasSME_F8F32)546 Builder.defineMacro("__ARM_FEATURE_SME_F8F32", "1");547 548 if (HasSME_F8F16)549 Builder.defineMacro("__ARM_FEATURE_SME_F8F16", "1");550 551 if (HasCRC)552 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");553 554 if (HasCSSC)555 Builder.defineMacro("__ARM_FEATURE_CSSC", "1");556 557 if (HasRCPC3)558 Builder.defineMacro("__ARM_FEATURE_RCPC", "3");559 else if (HasRCPC)560 Builder.defineMacro("__ARM_FEATURE_RCPC", "1");561 562 if (HasFMV)563 Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");564 565 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature566 // macros for AES, SHA2, SHA3 and SM4567 if (HasAES && HasSHA2)568 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");569 570 if (HasAES)571 Builder.defineMacro("__ARM_FEATURE_AES", "1");572 573 if (HasSHA2)574 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");575 576 if (HasSHA3) {577 Builder.defineMacro("__ARM_FEATURE_SHA3", "1");578 Builder.defineMacro("__ARM_FEATURE_SHA512", "1");579 }580 581 if (HasSM4) {582 Builder.defineMacro("__ARM_FEATURE_SM3", "1");583 Builder.defineMacro("__ARM_FEATURE_SM4", "1");584 }585 586 if (HasPAuth)587 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");588 589 if (HasPAuthLR)590 Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");591 592 if (HasBTI)593 Builder.defineMacro("__ARM_FEATURE_BTI", "1");594 595 if (HasUnalignedAccess)596 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");597 598 if ((FPU & NeonMode) && HasFullFP16)599 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");600 if (HasFullFP16)601 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");602 603 if (HasDotProd)604 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");605 606 if (HasMTE)607 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");608 609 if (HasMatMul)610 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");611 612 if (HasLSE)613 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");614 615 if (HasBFloat16) {616 Builder.defineMacro("__ARM_FEATURE_BF16", "1");617 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");618 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");619 Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");620 }621 622 if ((FPU & SveMode) && HasBFloat16) {623 Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");624 }625 626 if ((FPU & SveMode) && HasMatmulFP64)627 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");628 629 if ((FPU & SveMode) && HasMatmulFP32)630 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");631 632 if ((FPU & SveMode) && HasMatMul)633 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");634 635 if ((FPU & NeonMode) && HasFP16FML)636 Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");637 638 if (Opts.hasSignReturnAddress()) {639 // Bitmask:640 // 0: Protection using the A key641 // 1: Protection using the B key642 // 2: Protection including leaf functions643 // 3: Protection using PC as a diversifier644 unsigned Value = 0;645 646 if (Opts.isSignReturnAddressWithAKey())647 Value |= (1 << 0);648 else649 Value |= (1 << 1);650 651 if (Opts.isSignReturnAddressScopeAll())652 Value |= (1 << 2);653 654 if (Opts.BranchProtectionPAuthLR)655 Value |= (1 << 3);656 657 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));658 }659 660 if (Opts.BranchTargetEnforcement)661 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");662 663 if (Opts.GuardedControlStack)664 Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");665 666 if (HasLS64)667 Builder.defineMacro("__ARM_FEATURE_LS64", "1");668 669 if (HasRandGen)670 Builder.defineMacro("__ARM_FEATURE_RNG", "1");671 672 if (HasMOPS)673 Builder.defineMacro("__ARM_FEATURE_MOPS", "1");674 675 if (HasD128)676 Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");677 678 if (HasGCS)679 Builder.defineMacro("__ARM_FEATURE_GCS", "1");680 681 if (*ArchInfo == llvm::AArch64::ARMV8_1A)682 getTargetDefinesARMV81A(Opts, Builder);683 else if (*ArchInfo == llvm::AArch64::ARMV8_2A)684 getTargetDefinesARMV82A(Opts, Builder);685 else if (*ArchInfo == llvm::AArch64::ARMV8_3A)686 getTargetDefinesARMV83A(Opts, Builder);687 else if (*ArchInfo == llvm::AArch64::ARMV8_4A)688 getTargetDefinesARMV84A(Opts, Builder);689 else if (*ArchInfo == llvm::AArch64::ARMV8_5A)690 getTargetDefinesARMV85A(Opts, Builder);691 else if (*ArchInfo == llvm::AArch64::ARMV8_6A)692 getTargetDefinesARMV86A(Opts, Builder);693 else if (*ArchInfo == llvm::AArch64::ARMV8_7A)694 getTargetDefinesARMV87A(Opts, Builder);695 else if (*ArchInfo == llvm::AArch64::ARMV8_8A)696 getTargetDefinesARMV88A(Opts, Builder);697 else if (*ArchInfo == llvm::AArch64::ARMV8_9A)698 getTargetDefinesARMV89A(Opts, Builder);699 else if (*ArchInfo == llvm::AArch64::ARMV9A)700 getTargetDefinesARMV9A(Opts, Builder);701 else if (*ArchInfo == llvm::AArch64::ARMV9_1A)702 getTargetDefinesARMV91A(Opts, Builder);703 else if (*ArchInfo == llvm::AArch64::ARMV9_2A)704 getTargetDefinesARMV92A(Opts, Builder);705 else if (*ArchInfo == llvm::AArch64::ARMV9_3A)706 getTargetDefinesARMV93A(Opts, Builder);707 else if (*ArchInfo == llvm::AArch64::ARMV9_4A)708 getTargetDefinesARMV94A(Opts, Builder);709 else if (*ArchInfo == llvm::AArch64::ARMV9_5A)710 getTargetDefinesARMV95A(Opts, Builder);711 else if (*ArchInfo == llvm::AArch64::ARMV9_6A)712 getTargetDefinesARMV96A(Opts, Builder);713 else if (*ArchInfo == llvm::AArch64::ARMV9_7A)714 getTargetDefinesARMV97A(Opts, Builder);715 716 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.717 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");718 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");719 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");720 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");721 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");722 723 // Allow detection of fast FMA support.724 Builder.defineMacro("__FP_FAST_FMA", "1");725 Builder.defineMacro("__FP_FAST_FMAF", "1");726 727 // C/C++ operators work on both VLS and VLA SVE types728 if (FPU & SveMode)729 Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");730 731 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {732 Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));733 }734}735 736llvm::SmallVector<Builtin::InfosShard>737AArch64TargetInfo::getTargetBuiltins() const {738 return {739 {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"},740 {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos,741 "__builtin_neon_"},742 {&SVE::BuiltinStrings, SVE::BuiltinInfos, "__builtin_sve_"},743 {&BuiltinSVENeonBridgeStrings, BuiltinSVENeonBridgeInfos},744 {&SME::BuiltinStrings, SME::BuiltinInfos, "__builtin_sme_"},745 {&BuiltinAArch64Strings, BuiltinAArch64Infos},746 };747}748 749std::optional<std::pair<unsigned, unsigned>>750AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts,751 ArmStreamingKind Mode,752 llvm::StringMap<bool> *FeatureMap) const {753 if (Mode == ArmStreamingKind::NotStreaming &&754 (LangOpts.VScaleMin || LangOpts.VScaleMax))755 return std::pair<unsigned, unsigned>(756 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,757 LangOpts.VScaleMax ? LangOpts.VScaleMax : 16);758 759 if (Mode == ArmStreamingKind::Streaming &&760 (LangOpts.VScaleStreamingMin || LangOpts.VScaleStreamingMax))761 return std::pair<unsigned, unsigned>(762 LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1,763 LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);764 765 if (Mode == ArmStreamingKind::StreamingCompatible &&766 ((LangOpts.VScaleMin && LangOpts.VScaleStreamingMin) ||767 (LangOpts.VScaleMax && LangOpts.VScaleStreamingMax))) {768 unsigned Min =769 std::min(LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,770 LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1);771 unsigned Max = std::max(772 LangOpts.VScaleMax ? LangOpts.VScaleMax : 16,773 LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);774 return std::pair(Min, Max);775 }776 777 if (hasFeature("sve") || (FeatureMap && (FeatureMap->lookup("sve"))))778 return std::pair<unsigned, unsigned>(1, 16);779 780 if (Mode == ArmStreamingKind::Streaming &&781 (hasFeature("sme") || (FeatureMap && (FeatureMap->lookup("sme")))))782 return std::pair<unsigned, unsigned>(1, 16);783 784 return std::nullopt;785}786 787llvm::APInt788AArch64TargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {789 return llvm::AArch64::getFMVPriority(Features);790}791 792bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {793 // FMV extensions which imply no backend features do not affect codegen.794 if (auto Ext = llvm::AArch64::parseFMVExtension(Name))795 return Ext->ID.has_value();796 return false;797}798 799bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {800 // CPU features might be separated by '+', extract them and check801 llvm::SmallVector<StringRef, 8> Features;802 FeatureStr.split(Features, "+");803 for (auto &Feature : Features)804 if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())805 return false;806 return true;807}808 809bool AArch64TargetInfo::hasFeature(StringRef Feature) const {810 return llvm::StringSwitch<bool>(Feature)811 .Cases({"aarch64", "arm64", "arm"}, true)812 .Case("fmv", HasFMV)813 .Case("fp", FPU & FPUMode)814 .Cases({"neon", "simd"}, FPU & NeonMode)815 .Case("jscvt", HasJSCVT)816 .Case("fcma", HasFCMA)817 .Case("rng", HasRandGen)818 .Case("flagm", HasFlagM)819 .Case("flagm2", HasAlternativeNZCV)820 .Case("fp16fml", HasFP16FML)821 .Case("dotprod", HasDotProd)822 .Case("sm4", HasSM4)823 .Case("rdm", HasRDM)824 .Case("lse", HasLSE)825 .Case("crc", HasCRC)826 .Case("cssc", HasCSSC)827 .Case("sha2", HasSHA2)828 .Case("sha3", HasSHA3)829 .Cases({"aes", "pmull"}, HasAES)830 .Cases({"fp16", "fullfp16"}, HasFullFP16)831 .Case("dit", HasDIT)832 .Case("dpb", HasCCPP)833 .Case("dpb2", HasCCDP)834 .Case("rcpc", HasRCPC)835 .Case("frintts", HasFRInt3264)836 .Case("i8mm", HasMatMul)837 .Case("bf16", HasBFloat16)838 .Case("sve", FPU & SveMode)839 .Case("sve-b16b16", HasSVEB16B16)840 .Case("f32mm", FPU & SveMode && HasMatmulFP32)841 .Case("f64mm", FPU & SveMode && HasMatmulFP64)842 .Case("sve2", FPU & SveMode && HasSVE2)843 .Case("sve-aes", HasSVEAES)844 .Case("sve-bitperm", FPU & HasSVEBitPerm)845 .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)846 .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)847 .Case("sve2p1", FPU & SveMode && HasSVE2p1)848 .Case("sme", HasSME)849 .Case("sme2", HasSME2)850 .Case("sme2p1", HasSME2p1)851 .Case("sme-f64f64", HasSMEF64F64)852 .Case("sme-i16i64", HasSMEI16I64)853 .Case("sme-fa64", HasSMEFA64)854 .Case("sme-f16f16", HasSMEF16F16)855 .Case("sme-b16b16", HasSMEB16B16)856 .Case("memtag", HasMTE)857 .Case("sb", HasSB)858 .Case("predres", HasPredRes)859 .Cases({"ssbs", "ssbs2"}, HasSSBS)860 .Case("bti", HasBTI)861 .Cases({"ls64", "ls64_v", "ls64_accdata"}, HasLS64)862 .Case("wfxt", HasWFxT)863 .Case("rcpc3", HasRCPC3)864 .Case("fp8", HasFP8)865 .Case("fp8fma", HasFP8FMA)866 .Case("fp8dot2", HasFP8DOT2)867 .Case("fp8dot4", HasFP8DOT4)868 .Case("ssve-fp8dot2", HasSSVE_FP8DOT2)869 .Case("ssve-fp8dot4", HasSSVE_FP8DOT4)870 .Case("ssve-fp8fma", HasSSVE_FP8FMA)871 .Case("sme-f8f32", HasSME_F8F32)872 .Case("sme-f8f16", HasSME_F8F16)873 .Default(false);874}875 876void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,877 StringRef Name, bool Enabled) const {878 Features[Name] = Enabled;879 // If the feature is an architecture feature (like v8.2a), add all previous880 // architecture versions and any dependant target features.881 const std::optional<llvm::AArch64::ArchInfo> ArchInfo =882 llvm::AArch64::ArchInfo::findBySubArch(Name);883 884 if (!ArchInfo)885 return; // Not an architecture, nothing more to do.886 887 // Disabling an architecture feature does not affect dependent features888 if (!Enabled)889 return;890 891 for (const auto *OtherArch : llvm::AArch64::ArchInfos)892 if (ArchInfo->implies(*OtherArch))893 Features[OtherArch->getSubArch()] = true;894 895 // Set any features implied by the architecture896 std::vector<StringRef> CPUFeats;897 if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {898 for (auto F : CPUFeats) {899 assert(F[0] == '+' && "Expected + in target feature!");900 Features[F.drop_front(1)] = true;901 }902 }903}904 905bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,906 DiagnosticsEngine &Diags) {907 for (const auto &Feature : Features) {908 if (Feature == "-fp-armv8")909 HasNoFP = true;910 if (Feature == "-neon")911 HasNoNeon = true;912 if (Feature == "-sve")913 HasNoSVE = true;914 915 if (Feature == "+neon" || Feature == "+fp-armv8")916 FPU |= NeonMode;917 if (Feature == "+jscvt") {918 HasJSCVT = true;919 FPU |= NeonMode;920 }921 if (Feature == "+fcma") {922 HasFCMA = true;923 FPU |= NeonMode;924 }925 926 if (Feature == "+sve") {927 FPU |= NeonMode;928 FPU |= SveMode;929 HasFullFP16 = true;930 }931 if (Feature == "+sve2") {932 FPU |= NeonMode;933 FPU |= SveMode;934 HasFullFP16 = true;935 HasSVE2 = true;936 }937 if (Feature == "+sve2p1") {938 FPU |= NeonMode;939 FPU |= SveMode;940 HasFullFP16 = true;941 HasSVE2 = true;942 HasSVE2p1 = true;943 }944 if (Feature == "+sve-aes") {945 FPU |= NeonMode;946 HasFullFP16 = true;947 HasSVEAES = true;948 }949 if (Feature == "+sve2-sha3") {950 FPU |= NeonMode;951 FPU |= SveMode;952 HasFullFP16 = true;953 HasSVE2 = true;954 HasSVE2SHA3 = true;955 }956 if (Feature == "+sve2-sm4") {957 FPU |= NeonMode;958 FPU |= SveMode;959 HasFullFP16 = true;960 HasSVE2 = true;961 HasSVE2SM4 = true;962 }963 if (Feature == "+sve-b16b16")964 HasSVEB16B16 = true;965 if (Feature == "+sve-bitperm") {966 FPU |= NeonMode;967 HasFullFP16 = true;968 HasSVEBitPerm = true;969 }970 if (Feature == "+f32mm") {971 FPU |= NeonMode;972 FPU |= SveMode;973 HasFullFP16 = true;974 HasMatmulFP32 = true;975 }976 if (Feature == "+f64mm") {977 FPU |= NeonMode;978 FPU |= SveMode;979 HasFullFP16 = true;980 HasMatmulFP64 = true;981 }982 if (Feature == "+sme") {983 HasSME = true;984 HasBFloat16 = true;985 HasFullFP16 = true;986 }987 if (Feature == "+sme2") {988 HasSME = true;989 HasSME2 = true;990 HasBFloat16 = true;991 HasFullFP16 = true;992 }993 if (Feature == "+sme2p1") {994 HasSME = true;995 HasSME2 = true;996 HasSME2p1 = true;997 HasBFloat16 = true;998 HasFullFP16 = true;999 }1000 if (Feature == "+sme-f64f64") {1001 HasSME = true;1002 HasSMEF64F64 = true;1003 HasBFloat16 = true;1004 HasFullFP16 = true;1005 }1006 if (Feature == "+sme-i16i64") {1007 HasSME = true;1008 HasSMEI16I64 = true;1009 HasBFloat16 = true;1010 HasFullFP16 = true;1011 }1012 if (Feature == "+sme-fa64") {1013 FPU |= NeonMode;1014 FPU |= SveMode;1015 HasSME = true;1016 HasSVE2 = true;1017 HasSMEFA64 = true;1018 }1019 if (Feature == "+sme-f16f16") {1020 HasSME = true;1021 HasSME2 = true;1022 HasBFloat16 = true;1023 HasFullFP16 = true;1024 HasSMEF16F16 = true;1025 }1026 if (Feature == "+sme-b16b16") {1027 HasSME = true;1028 HasSME2 = true;1029 HasBFloat16 = true;1030 HasFullFP16 = true;1031 HasSVEB16B16 = true;1032 HasSMEB16B16 = true;1033 }1034 1035 if (Feature == "+fp8")1036 HasFP8 = true;1037 if (Feature == "+fp8fma")1038 HasFP8FMA = true;1039 if (Feature == "+fp8dot2")1040 HasFP8DOT2 = true;1041 if (Feature == "+fp8dot4")1042 HasFP8DOT4 = true;1043 if (Feature == "+ssve-fp8dot2")1044 HasSSVE_FP8DOT2 = true;1045 if (Feature == "+ssve-fp8dot4")1046 HasSSVE_FP8DOT4 = true;1047 if (Feature == "+ssve-fp8fma")1048 HasSSVE_FP8FMA = true;1049 if (Feature == "+sme-f8f32")1050 HasSME_F8F32 = true;1051 if (Feature == "+sme-f8f16")1052 HasSME_F8F16 = true;1053 if (Feature == "+sb")1054 HasSB = true;1055 if (Feature == "+predres")1056 HasPredRes = true;1057 if (Feature == "+ssbs")1058 HasSSBS = true;1059 if (Feature == "+bti")1060 HasBTI = true;1061 if (Feature == "+wfxt")1062 HasWFxT = true;1063 if (Feature == "-fmv")1064 HasFMV = false;1065 if (Feature == "+crc")1066 HasCRC = true;1067 if (Feature == "+rcpc")1068 HasRCPC = true;1069 if (Feature == "+aes") {1070 FPU |= NeonMode;1071 HasAES = true;1072 }1073 if (Feature == "+sha2") {1074 FPU |= NeonMode;1075 HasSHA2 = true;1076 }1077 if (Feature == "+sha3") {1078 FPU |= NeonMode;1079 HasSHA2 = true;1080 HasSHA3 = true;1081 }1082 if (Feature == "+rdm") {1083 FPU |= NeonMode;1084 HasRDM = true;1085 }1086 if (Feature == "+dit")1087 HasDIT = true;1088 if (Feature == "+cccp")1089 HasCCPP = true;1090 if (Feature == "+ccdp") {1091 HasCCPP = true;1092 HasCCDP = true;1093 }1094 if (Feature == "+fptoint")1095 HasFRInt3264 = true;1096 if (Feature == "+sm4") {1097 FPU |= NeonMode;1098 HasSM4 = true;1099 }1100 if (Feature == "+strict-align")1101 HasUnalignedAccess = false;1102 1103 // All predecessor archs are added but select the latest one for ArchKind.1104 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)1105 ArchInfo = &llvm::AArch64::ARMV8A;1106 if (Feature == "+v8.1a" &&1107 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)1108 ArchInfo = &llvm::AArch64::ARMV8_1A;1109 if (Feature == "+v8.2a" &&1110 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)1111 ArchInfo = &llvm::AArch64::ARMV8_2A;1112 if (Feature == "+v8.3a" &&1113 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)1114 ArchInfo = &llvm::AArch64::ARMV8_3A;1115 if (Feature == "+v8.4a" &&1116 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)1117 ArchInfo = &llvm::AArch64::ARMV8_4A;1118 if (Feature == "+v8.5a" &&1119 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)1120 ArchInfo = &llvm::AArch64::ARMV8_5A;1121 if (Feature == "+v8.6a" &&1122 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)1123 ArchInfo = &llvm::AArch64::ARMV8_6A;1124 if (Feature == "+v8.7a" &&1125 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)1126 ArchInfo = &llvm::AArch64::ARMV8_7A;1127 if (Feature == "+v8.8a" &&1128 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)1129 ArchInfo = &llvm::AArch64::ARMV8_8A;1130 if (Feature == "+v8.9a" &&1131 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)1132 ArchInfo = &llvm::AArch64::ARMV8_9A;1133 if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)1134 ArchInfo = &llvm::AArch64::ARMV9A;1135 if (Feature == "+v9.1a" &&1136 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)1137 ArchInfo = &llvm::AArch64::ARMV9_1A;1138 if (Feature == "+v9.2a" &&1139 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)1140 ArchInfo = &llvm::AArch64::ARMV9_2A;1141 if (Feature == "+v9.3a" &&1142 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)1143 ArchInfo = &llvm::AArch64::ARMV9_3A;1144 if (Feature == "+v9.4a" &&1145 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)1146 ArchInfo = &llvm::AArch64::ARMV9_4A;1147 if (Feature == "+v9.5a" &&1148 ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)1149 ArchInfo = &llvm::AArch64::ARMV9_5A;1150 if (Feature == "+v9.6a" &&1151 ArchInfo->Version < llvm::AArch64::ARMV9_6A.Version)1152 ArchInfo = &llvm::AArch64::ARMV9_6A;1153 if (Feature == "+v9.7a" &&1154 ArchInfo->Version < llvm::AArch64::ARMV9_7A.Version)1155 ArchInfo = &llvm::AArch64::ARMV9_7A;1156 if (Feature == "+v8r")1157 ArchInfo = &llvm::AArch64::ARMV8R;1158 if (Feature == "+fullfp16") {1159 FPU |= NeonMode;1160 HasFullFP16 = true;1161 }1162 if (Feature == "+dotprod") {1163 FPU |= NeonMode;1164 HasDotProd = true;1165 }1166 if (Feature == "+fp16fml") {1167 FPU |= NeonMode;1168 HasFullFP16 = true;1169 HasFP16FML = true;1170 }1171 if (Feature == "+mte")1172 HasMTE = true;1173 if (Feature == "+pauth")1174 HasPAuth = true;1175 if (Feature == "+i8mm")1176 HasMatMul = true;1177 if (Feature == "+bf16")1178 HasBFloat16 = true;1179 if (Feature == "+lse")1180 HasLSE = true;1181 if (Feature == "+ls64")1182 HasLS64 = true;1183 if (Feature == "+rand")1184 HasRandGen = true;1185 if (Feature == "+flagm")1186 HasFlagM = true;1187 if (Feature == "+altnzcv") {1188 HasFlagM = true;1189 HasAlternativeNZCV = true;1190 }1191 if (Feature == "+mops")1192 HasMOPS = true;1193 if (Feature == "+d128")1194 HasD128 = true;1195 if (Feature == "+gcs")1196 HasGCS = true;1197 if (Feature == "+rcpc3")1198 HasRCPC3 = true;1199 if (Feature == "+pauth-lr") {1200 HasPAuthLR = true;1201 HasPAuth = true;1202 }1203 if (Feature == "+cssc")1204 HasCSSC = true;1205 }1206 1207 // Check features that are manually disabled by command line options.1208 // This needs to be checked after architecture-related features are handled,1209 // making sure they are properly disabled when required.1210 for (const auto &Feature : Features) {1211 if (Feature == "-d128")1212 HasD128 = false;1213 }1214 1215 setDataLayout();1216 1217 if (HasNoFP) {1218 FPU &= ~FPUMode;1219 FPU &= ~NeonMode;1220 FPU &= ~SveMode;1221 }1222 if (HasNoNeon) {1223 FPU &= ~NeonMode;1224 FPU &= ~SveMode;1225 }1226 if (HasNoSVE)1227 FPU &= ~SveMode;1228 1229 return true;1230}1231 1232// Parse AArch64 Target attributes, which are a comma separated list of:1233// "arch=<arch>" - parsed to features as per -march=..1234// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>1235// "tune=<cpu>" - TuneCPU set to <cpu>1236// "feature", "no-feature" - Add (or remove) feature.1237// "+feature", "+nofeature" - Add (or remove) feature.1238//1239// A feature may correspond to an Extension (anything with a corresponding1240// AEK_), in which case an ExtensionSet is used to parse it and expand its1241// dependencies. If the feature does not yield a successful parse then it1242// is passed through.1243ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {1244 ParsedTargetAttr Ret;1245 if (Features == "default")1246 return Ret;1247 SmallVector<StringRef, 1> AttrFeatures;1248 Features.split(AttrFeatures, ",");1249 bool FoundArch = false;1250 1251 auto SplitAndAddFeatures = [](StringRef FeatString,1252 std::vector<std::string> &Features,1253 llvm::AArch64::ExtensionSet &FeatureBits) {1254 SmallVector<StringRef, 8> SplitFeatures;1255 FeatString.split(SplitFeatures, StringRef("+"), -1, false);1256 for (StringRef Feature : SplitFeatures) {1257 if (FeatureBits.parseModifier(Feature))1258 continue;1259 // Pass through anything that failed to parse so that we can emit1260 // diagnostics, as well as valid internal feature names.1261 //1262 // FIXME: We should consider rejecting internal feature names like1263 // neon, v8a, etc.1264 // FIXME: We should consider emitting diagnostics here.1265 if (Feature.starts_with("no"))1266 Features.push_back("-" + Feature.drop_front(2).str());1267 else1268 Features.push_back("+" + Feature.str());1269 }1270 };1271 1272 llvm::AArch64::ExtensionSet FeatureBits;1273 // Reconstruct the bitset from the command line option features.1274 FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten,1275 Ret.Features);1276 1277 for (auto &Feature : AttrFeatures) {1278 Feature = Feature.trim();1279 if (Feature.starts_with("fpmath="))1280 continue;1281 1282 if (Feature.starts_with("branch-protection=")) {1283 Ret.BranchProtection = Feature.split('=').second.trim();1284 continue;1285 }1286 1287 if (Feature.starts_with("arch=")) {1288 if (FoundArch)1289 Ret.Duplicate = "arch=";1290 FoundArch = true;1291 std::pair<StringRef, StringRef> Split =1292 Feature.split("=").second.trim().split("+");1293 const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);1294 1295 // Parse the architecture version, adding the required features to1296 // Ret.Features.1297 if (!AI)1298 continue;1299 FeatureBits.addArchDefaults(*AI);1300 // Add any extra features, after the +1301 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);1302 } else if (Feature.starts_with("cpu=")) {1303 if (!Ret.CPU.empty())1304 Ret.Duplicate = "cpu=";1305 else {1306 // Split the cpu string into "cpu=", "cortex-a710" and any remaining1307 // "+feat" features.1308 std::pair<StringRef, StringRef> Split =1309 Feature.split("=").second.trim().split("+");1310 Ret.CPU = Split.first;1311 if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {1312 FeatureBits.addCPUDefaults(*CpuInfo);1313 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);1314 }1315 }1316 } else if (Feature.starts_with("tune=")) {1317 if (!Ret.Tune.empty())1318 Ret.Duplicate = "tune=";1319 else1320 Ret.Tune = Feature.split("=").second.trim();1321 } else if (Feature.starts_with("+")) {1322 SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);1323 } else {1324 if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))1325 continue;1326 // Pass through anything that failed to parse so that we can emit1327 // diagnostics, as well as valid internal feature names.1328 //1329 // FIXME: We should consider rejecting internal feature names like1330 // neon, v8a, etc.1331 // FIXME: We should consider emitting diagnostics here.1332 if (Feature.starts_with("no-"))1333 Ret.Features.push_back("-" + Feature.drop_front(3).str());1334 else1335 Ret.Features.push_back("+" + Feature.str());1336 }1337 }1338 FeatureBits.toLLVMFeatureList(Ret.Features);1339 return Ret;1340}1341 1342bool AArch64TargetInfo::hasBFloat16Type() const {1343 return true;1344}1345 1346TargetInfo::CallingConvCheckResult1347AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {1348 switch (CC) {1349 case CC_C:1350 case CC_Swift:1351 case CC_SwiftAsync:1352 case CC_PreserveMost:1353 case CC_PreserveAll:1354 case CC_PreserveNone:1355 case CC_DeviceKernel:1356 case CC_AArch64VectorCall:1357 case CC_AArch64SVEPCS:1358 case CC_Win64:1359 return CCCR_OK;1360 default:1361 return CCCR_Warning;1362 }1363}1364 1365bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }1366 1367TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {1368 return TargetInfo::AArch64ABIBuiltinVaList;1369}1370 1371const char *const AArch64TargetInfo::GCCRegNames[] = {1372 // clang-format off1373 1374 // 32-bit Integer registers1375 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",1376 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",1377 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",1378 1379 // 64-bit Integer registers1380 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",1381 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",1382 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",1383 1384 // 32-bit floating point regsisters1385 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",1386 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",1387 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",1388 1389 // 64-bit floating point regsisters1390 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",1391 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",1392 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",1393 1394 // Neon vector registers1395 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",1396 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",1397 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",1398 1399 // SVE vector registers1400 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",1401 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",1402 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",1403 1404 // SVE predicate registers1405 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",1406 "p11", "p12", "p13", "p14", "p15",1407 1408 // SVE predicate-as-counter registers1409 "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",1410 "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",1411 1412 // SME registers1413 "za", "zt0",1414 1415 // clang-format on1416};1417 1418ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {1419 return llvm::ArrayRef(GCCRegNames);1420}1421 1422const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {1423 {{"w31"}, "wsp"},1424 {{"x31"}, "sp"},1425 // GCC rN registers are aliases of xN registers.1426 {{"r0"}, "x0"},1427 {{"r1"}, "x1"},1428 {{"r2"}, "x2"},1429 {{"r3"}, "x3"},1430 {{"r4"}, "x4"},1431 {{"r5"}, "x5"},1432 {{"r6"}, "x6"},1433 {{"r7"}, "x7"},1434 {{"r8"}, "x8"},1435 {{"r9"}, "x9"},1436 {{"r10"}, "x10"},1437 {{"r11"}, "x11"},1438 {{"r12"}, "x12"},1439 {{"r13"}, "x13"},1440 {{"r14"}, "x14"},1441 {{"r15"}, "x15"},1442 {{"r16"}, "x16"},1443 {{"r17"}, "x17"},1444 {{"r18"}, "x18"},1445 {{"r19"}, "x19"},1446 {{"r20"}, "x20"},1447 {{"r21"}, "x21"},1448 {{"r22"}, "x22"},1449 {{"r23"}, "x23"},1450 {{"r24"}, "x24"},1451 {{"r25"}, "x25"},1452 {{"r26"}, "x26"},1453 {{"r27"}, "x27"},1454 {{"r28"}, "x28"},1455 {{"r29", "x29"}, "fp"},1456 {{"r30", "x30"}, "lr"},1457 // The S/D/Q and W/X registers overlap, but aren't really aliases; we1458 // don't want to substitute one of these for a different-sized one.1459};1460 1461ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {1462 return llvm::ArrayRef(GCCRegAliases);1463}1464 1465// Returns the length of cc constraint.1466static unsigned matchAsmCCConstraint(const char *Name) {1467 constexpr unsigned len = 5;1468 auto RV = llvm::StringSwitch<unsigned>(Name)1469 .Case("@cceq", len)1470 .Case("@ccne", len)1471 .Case("@cchs", len)1472 .Case("@cccs", len)1473 .Case("@cccc", len)1474 .Case("@cclo", len)1475 .Case("@ccmi", len)1476 .Case("@ccpl", len)1477 .Case("@ccvs", len)1478 .Case("@ccvc", len)1479 .Case("@cchi", len)1480 .Case("@ccls", len)1481 .Case("@ccge", len)1482 .Case("@cclt", len)1483 .Case("@ccgt", len)1484 .Case("@ccle", len)1485 .Default(0);1486 return RV;1487}1488 1489std::string1490AArch64TargetInfo::convertConstraint(const char *&Constraint) const {1491 std::string R;1492 switch (*Constraint) {1493 case 'U': // Three-character constraint; add "@3" hint for later parsing.1494 R = std::string("@3") + std::string(Constraint, 3);1495 Constraint += 2;1496 break;1497 case '@':1498 if (const unsigned Len = matchAsmCCConstraint(Constraint)) {1499 std::string Converted = "{" + std::string(Constraint, Len) + "}";1500 Constraint += Len - 1;1501 return Converted;1502 }1503 return std::string(1, *Constraint);1504 default:1505 R = TargetInfo::convertConstraint(Constraint);1506 break;1507 }1508 return R;1509}1510 1511bool AArch64TargetInfo::validateAsmConstraint(1512 const char *&Name, TargetInfo::ConstraintInfo &Info) const {1513 switch (*Name) {1514 default:1515 return false;1516 case 'w': // Floating point and SIMD registers (V0-V31)1517 Info.setAllowsRegister();1518 return true;1519 case 'I': // Constant that can be used with an ADD instruction1520 case 'J': // Constant that can be used with a SUB instruction1521 case 'K': // Constant that can be used with a 32-bit logical instruction1522 case 'L': // Constant that can be used with a 64-bit logical instruction1523 case 'M': // Constant that can be used as a 32-bit MOV immediate1524 case 'N': // Constant that can be used as a 64-bit MOV immediate1525 case 'Y': // Floating point constant zero1526 case 'Z': // Integer constant zero1527 return true;1528 case 'Q': // A memory reference with base register and no offset1529 Info.setAllowsMemory();1530 return true;1531 case 'S': // A symbolic address1532 Info.setAllowsRegister();1533 return true;1534 case 'U':1535 if (Name[1] == 'p' &&1536 (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {1537 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)1538 Info.setAllowsRegister();1539 Name += 2;1540 return true;1541 }1542 if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {1543 // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)1544 Info.setAllowsRegister();1545 Name += 2;1546 return true;1547 }1548 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.1549 // Utf: A memory address suitable for ldp/stp in TF mode.1550 // Usa: An absolute symbolic address.1551 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.1552 1553 // Better to return an error saying that it's an unrecognised constraint1554 // even if this is a valid constraint in gcc.1555 return false;1556 case 'z': // Zero register, wzr or xzr1557 Info.setAllowsRegister();1558 return true;1559 case 'x': // Floating point and SIMD registers (V0-V15)1560 Info.setAllowsRegister();1561 return true;1562 case 'y': // SVE registers (V0-V7)1563 Info.setAllowsRegister();1564 return true;1565 case '@':1566 // CC condition1567 if (const unsigned Len = matchAsmCCConstraint(Name)) {1568 Name += Len - 1;1569 Info.setAllowsRegister();1570 Info.setOutputOperandBounds(0, 2);1571 return true;1572 }1573 }1574 return false;1575}1576 1577bool AArch64TargetInfo::validateConstraintModifier(1578 StringRef Constraint, char Modifier, unsigned Size,1579 std::string &SuggestedModifier) const {1580 // Strip off constraint modifiers.1581 Constraint = Constraint.ltrim("=+&");1582 1583 switch (Constraint[0]) {1584 default:1585 return true;1586 case 'z':1587 case 'r': {1588 switch (Modifier) {1589 case 'x':1590 case 'w':1591 // For now assume that the person knows what they're1592 // doing with the modifier.1593 return true;1594 default:1595 // By default an 'r' constraint will be in the 'x'1596 // registers.1597 if (Size == 64)1598 return true;1599 1600 if (Size == 512)1601 return HasLS64;1602 1603 SuggestedModifier = "w";1604 return false;1605 }1606 }1607 }1608}1609 1610std::string_view AArch64TargetInfo::getClobbers() const { return ""; }1611 1612int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {1613 if (RegNo == 0)1614 return 0;1615 if (RegNo == 1)1616 return 1;1617 return -1;1618}1619 1620bool AArch64TargetInfo::validatePointerAuthKey(1621 const llvm::APSInt &value) const {1622 return 0 <= value && value <= 3;1623}1624 1625bool AArch64TargetInfo::hasInt128Type() const { return true; }1626 1627AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,1628 const TargetOptions &Opts)1629 : AArch64TargetInfo(Triple, Opts) {}1630 1631void AArch64leTargetInfo::setDataLayout() {1632 if (getTriple().isOSBinFormatMachO()) {1633 if(getTriple().isArch32Bit())1634 resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"1635 "i128:128-n32:64-S128-Fn32",1636 "_");1637 else1638 resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"1639 "n32:64-S128-Fn32",1640 "_");1641 } else1642 resetDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-"1643 "i64:64-i128:128-n32:64-S128-Fn32");1644}1645 1646void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,1647 MacroBuilder &Builder) const {1648 Builder.defineMacro("__AARCH64EL__");1649 AArch64TargetInfo::getTargetDefines(Opts, Builder);1650}1651 1652AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,1653 const TargetOptions &Opts)1654 : AArch64TargetInfo(Triple, Opts) {}1655 1656void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,1657 MacroBuilder &Builder) const {1658 Builder.defineMacro("__AARCH64EB__");1659 Builder.defineMacro("__AARCH_BIG_ENDIAN");1660 Builder.defineMacro("__ARM_BIG_ENDIAN");1661 AArch64TargetInfo::getTargetDefines(Opts, Builder);1662}1663 1664void AArch64beTargetInfo::setDataLayout() {1665 assert(!getTriple().isOSBinFormatMachO());1666 resetDataLayout("E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-"1667 "i64:64-i128:128-n32:64-S128-Fn32");1668}1669 1670WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,1671 const TargetOptions &Opts)1672 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {1673 1674 // This is an LLP64 platform.1675 // int:4, long:4, long long:8, long double:8.1676 IntWidth = IntAlign = 32;1677 LongWidth = LongAlign = 32;1678 DoubleAlign = LongLongAlign = 64;1679 LongDoubleWidth = LongDoubleAlign = 64;1680 LongDoubleFormat = &llvm::APFloat::IEEEdouble();1681 IntMaxType = SignedLongLong;1682 Int64Type = SignedLongLong;1683 SizeType = UnsignedLongLong;1684 PtrDiffType = SignedLongLong;1685 IntPtrType = SignedLongLong;1686}1687 1688void WindowsARM64TargetInfo::setDataLayout() {1689 resetDataLayout(Triple.isOSBinFormatMachO()1690 ? "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:"1691 "128-n32:64-S128-Fn32"1692 : "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-"1693 "i64:64-i128:128-n32:64-S128-Fn32",1694 Triple.isOSBinFormatMachO() ? "_" : "");1695}1696 1697TargetInfo::BuiltinVaListKind1698WindowsARM64TargetInfo::getBuiltinVaListKind() const {1699 return TargetInfo::CharPtrBuiltinVaList;1700}1701 1702TargetInfo::CallingConvCheckResult1703WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {1704 switch (CC) {1705 case CC_X86VectorCall:1706 if (getTriple().isWindowsArm64EC())1707 return CCCR_OK;1708 return CCCR_Ignore;1709 case CC_X86StdCall:1710 case CC_X86ThisCall:1711 case CC_X86FastCall:1712 return CCCR_Ignore;1713 case CC_C:1714 case CC_DeviceKernel:1715 case CC_PreserveMost:1716 case CC_PreserveAll:1717 case CC_PreserveNone:1718 case CC_Swift:1719 case CC_SwiftAsync:1720 case CC_Win64:1721 return CCCR_OK;1722 default:1723 return CCCR_Warning;1724 }1725}1726 1727MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,1728 const TargetOptions &Opts)1729 : WindowsARM64TargetInfo(Triple, Opts) {1730 TheCXXABI.set(TargetCXXABI::Microsoft);1731}1732 1733void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,1734 MacroBuilder &Builder) const {1735 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);1736 if (getTriple().isWindowsArm64EC()) {1737 Builder.defineMacro("_M_X64", "100");1738 Builder.defineMacro("_M_AMD64", "100");1739 Builder.defineMacro("_M_ARM64EC", "1");1740 } else {1741 Builder.defineMacro("_M_ARM64", "1");1742 }1743}1744 1745TargetInfo::CallingConvKind1746MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {1747 return CCK_MicrosoftWin64;1748}1749 1750unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,1751 bool HasNonWeakDef) const {1752 unsigned Align =1753 WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);1754 1755 // MSVC does size based alignment for arm64 based on alignment section in1756 // below document, replicate that to keep alignment consistent with object1757 // files compiled by MSVC.1758 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions1759 if (TypeSize >= 512) { // TypeSize >= 64 bytes1760 Align = std::max(Align, 128u); // align type at least 16 bytes1761 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes1762 Align = std::max(Align, 64u); // align type at least 8 butes1763 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes1764 Align = std::max(Align, 32u); // align type at least 4 bytes1765 }1766 return Align;1767}1768 1769MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,1770 const TargetOptions &Opts)1771 : WindowsARM64TargetInfo(Triple, Opts) {1772 TheCXXABI.set(TargetCXXABI::GenericAArch64);1773}1774 1775AppleMachOAArch64TargetInfo::AppleMachOAArch64TargetInfo(1776 const llvm::Triple &Triple, const TargetOptions &Opts)1777 : AppleMachOTargetInfo<AArch64leTargetInfo>(Triple, Opts) {}1778 1779DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,1780 const TargetOptions &Opts)1781 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {1782 Int64Type = SignedLongLong;1783 if (getTriple().isArch32Bit())1784 IntMaxType = SignedLongLong;1785 1786 WCharType = SignedInt;1787 UseSignedCharForObjCBool = false;1788 1789 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;1790 LongDoubleFormat = &llvm::APFloat::IEEEdouble();1791 1792 UseZeroLengthBitfieldAlignment = false;1793 1794 if (getTriple().isArch32Bit()) {1795 UseBitFieldTypeAlignment = false;1796 ZeroLengthBitfieldBoundary = 32;1797 UseZeroLengthBitfieldAlignment = true;1798 TheCXXABI.set(TargetCXXABI::WatchOS);1799 } else1800 TheCXXABI.set(TargetCXXABI::AppleARM64);1801}1802 1803void clang::targets::getAppleMachOAArch64Defines(MacroBuilder &Builder,1804 const LangOptions &Opts,1805 const llvm::Triple &Triple) {1806 Builder.defineMacro("__AARCH64_SIMD__");1807 if (Triple.isArch32Bit())1808 Builder.defineMacro("__ARM64_ARCH_8_32__");1809 else1810 Builder.defineMacro("__ARM64_ARCH_8__");1811 Builder.defineMacro("__ARM_NEON__");1812 Builder.defineMacro("__REGISTER_PREFIX__", "");1813 Builder.defineMacro("__arm64", "1");1814 Builder.defineMacro("__arm64__", "1");1815 1816 if (Triple.isArm64e())1817 Builder.defineMacro("__arm64e__", "1");1818}1819 1820void AppleMachOAArch64TargetInfo::getOSDefines(const LangOptions &Opts,1821 const llvm::Triple &Triple,1822 MacroBuilder &Builder) const {1823 getAppleMachOAArch64Defines(Builder, Opts, Triple);1824 AppleMachOTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple,1825 Builder);1826}1827 1828void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,1829 const llvm::Triple &Triple,1830 MacroBuilder &Builder) const {1831 getAppleMachOAArch64Defines(Builder, Opts, Triple);1832 DarwinTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple, Builder);1833}1834 1835TargetInfo::BuiltinVaListKind1836DarwinAArch64TargetInfo::getBuiltinVaListKind() const {1837 return TargetInfo::CharPtrBuiltinVaList;1838}1839