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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements AArch64 TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "AArch64.h" 14 #include "clang/Basic/LangOptions.h" 15 #include "clang/Basic/TargetBuiltins.h" 16 #include "clang/Basic/TargetInfo.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/Support/AArch64TargetParser.h" 21 #include "llvm/Support/ARMTargetParserCommon.h" 22 #include <optional> 23 24 using namespace clang; 25 using namespace clang::targets; 26 27 static constexpr Builtin::Info BuiltinInfo[] = { 28 #define BUILTIN(ID, TYPE, ATTRS) \ 29 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 30 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 31 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 32 #include "clang/Basic/BuiltinsNEON.def" 33 34 #define BUILTIN(ID, TYPE, ATTRS) \ 35 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 36 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 37 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 38 #include "clang/Basic/BuiltinsSVE.def" 39 40 #define BUILTIN(ID, TYPE, ATTRS) \ 41 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 42 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 43 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, 44 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 45 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 46 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 47 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, 48 #include "clang/Basic/BuiltinsAArch64.def" 49 }; 50 51 void AArch64TargetInfo::setArchFeatures() { 52 if (*ArchInfo == llvm::AArch64::ARMV8R) { 53 HasDotProd = true; 54 HasDIT = true; 55 HasFlagM = true; 56 HasRCPC = true; 57 FPU |= NeonMode; 58 HasCCPP = true; 59 HasCRC = true; 60 HasLSE = true; 61 HasRDM = true; 62 } else if (ArchInfo->Version.getMajor() == 8) { 63 if (ArchInfo->Version.getMinor() >= 7u) { 64 HasWFxT = true; 65 } 66 if (ArchInfo->Version.getMinor() >= 6u) { 67 HasBFloat16 = true; 68 HasMatMul = true; 69 } 70 if (ArchInfo->Version.getMinor() >= 5u) { 71 HasAlternativeNZCV = true; 72 HasFRInt3264 = true; 73 HasSSBS = true; 74 HasSB = true; 75 HasPredRes = true; 76 HasBTI = true; 77 } 78 if (ArchInfo->Version.getMinor() >= 4u) { 79 HasDotProd = true; 80 HasDIT = true; 81 HasFlagM = true; 82 } 83 if (ArchInfo->Version.getMinor() >= 3u) { 84 HasRCPC = true; 85 FPU |= NeonMode; 86 } 87 if (ArchInfo->Version.getMinor() >= 2u) { 88 HasCCPP = true; 89 } 90 if (ArchInfo->Version.getMinor() >= 1u) { 91 HasCRC = true; 92 HasLSE = true; 93 HasRDM = true; 94 } 95 } else if (ArchInfo->Version.getMajor() == 9) { 96 if (ArchInfo->Version.getMinor() >= 2u) { 97 HasWFxT = true; 98 } 99 if (ArchInfo->Version.getMinor() >= 1u) { 100 HasBFloat16 = true; 101 HasMatMul = true; 102 } 103 FPU |= SveMode; 104 HasSVE2 = true; 105 HasFullFP16 = true; 106 HasAlternativeNZCV = true; 107 HasFRInt3264 = true; 108 HasSSBS = true; 109 HasSB = true; 110 HasPredRes = true; 111 HasBTI = true; 112 HasDotProd = true; 113 HasDIT = true; 114 HasFlagM = true; 115 HasRCPC = true; 116 FPU |= NeonMode; 117 HasCCPP = true; 118 HasCRC = true; 119 HasLSE = true; 120 HasRDM = true; 121 } 122 } 123 124 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, 125 const TargetOptions &Opts) 126 : TargetInfo(Triple), ABI("aapcs") { 127 if (getTriple().isOSOpenBSD()) { 128 Int64Type = SignedLongLong; 129 IntMaxType = SignedLongLong; 130 } else { 131 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD()) 132 WCharType = UnsignedInt; 133 134 Int64Type = SignedLong; 135 IntMaxType = SignedLong; 136 } 137 138 // All AArch64 implementations support ARMv8 FP, which makes half a legal type. 139 HasLegalHalfType = true; 140 HalfArgsAndReturns = true; 141 HasFloat16 = true; 142 HasStrictFP = true; 143 144 if (Triple.isArch64Bit()) 145 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 146 else 147 LongWidth = LongAlign = PointerWidth = PointerAlign = 32; 148 149 MaxVectorAlign = 128; 150 MaxAtomicInlineWidth = 128; 151 MaxAtomicPromoteWidth = 128; 152 153 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; 154 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 155 156 BFloat16Width = BFloat16Align = 16; 157 BFloat16Format = &llvm::APFloat::BFloat(); 158 159 // Make __builtin_ms_va_list available. 160 HasBuiltinMSVaList = true; 161 162 // Make the SVE types available. Note that this deliberately doesn't 163 // depend on SveMode, since in principle it should be possible to turn 164 // SVE on and off within a translation unit. It should also be possible 165 // to compile the global declaration: 166 // 167 // __SVInt8_t *ptr; 168 // 169 // even without SVE. 170 HasAArch64SVETypes = true; 171 172 // {} in inline assembly are neon specifiers, not assembly variant 173 // specifiers. 174 NoAsmVariants = true; 175 176 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type 177 // contributes to the alignment of the containing aggregate in the same way 178 // a plain (non bit-field) member of that type would, without exception for 179 // zero-sized or anonymous bit-fields." 180 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment"); 181 UseZeroLengthBitfieldAlignment = true; 182 183 // AArch64 targets default to using the ARM C++ ABI. 184 TheCXXABI.set(TargetCXXABI::GenericAArch64); 185 186 if (Triple.getOS() == llvm::Triple::Linux) 187 this->MCountName = "\01_mcount"; 188 else if (Triple.getOS() == llvm::Triple::UnknownOS) 189 this->MCountName = 190 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount"; 191 } 192 193 StringRef AArch64TargetInfo::getABI() const { return ABI; } 194 195 bool AArch64TargetInfo::setABI(const std::string &Name) { 196 if (Name != "aapcs" && Name != "darwinpcs") 197 return false; 198 199 ABI = Name; 200 return true; 201 } 202 203 bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, 204 BranchProtectionInfo &BPI, 205 StringRef &Err) const { 206 llvm::ARM::ParsedBranchProtection PBP; 207 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) 208 return false; 209 210 BPI.SignReturnAddr = 211 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) 212 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) 213 .Case("all", LangOptions::SignReturnAddressScopeKind::All) 214 .Default(LangOptions::SignReturnAddressScopeKind::None); 215 216 if (PBP.Key == "a_key") 217 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; 218 else 219 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; 220 221 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; 222 return true; 223 } 224 225 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { 226 return Name == "generic" || 227 llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID; 228 } 229 230 bool AArch64TargetInfo::setCPU(const std::string &Name) { 231 return isValidCPUName(Name); 232 } 233 234 void AArch64TargetInfo::fillValidCPUList( 235 SmallVectorImpl<StringRef> &Values) const { 236 llvm::AArch64::fillValidCPUArchList(Values); 237 } 238 239 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 240 MacroBuilder &Builder) const { 241 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 242 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); 243 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 244 } 245 246 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 247 MacroBuilder &Builder) const { 248 // Also include the ARMv8.1 defines 249 getTargetDefinesARMV81A(Opts, Builder); 250 } 251 252 void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 253 MacroBuilder &Builder) const { 254 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 255 Builder.defineMacro("__ARM_FEATURE_JCVT", "1"); 256 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); 257 // Also include the Armv8.2 defines 258 getTargetDefinesARMV82A(Opts, Builder); 259 } 260 261 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, 262 MacroBuilder &Builder) const { 263 // Also include the Armv8.3 defines 264 getTargetDefinesARMV83A(Opts, Builder); 265 } 266 267 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, 268 MacroBuilder &Builder) const { 269 Builder.defineMacro("__ARM_FEATURE_FRINT", "1"); 270 Builder.defineMacro("__ARM_FEATURE_BTI", "1"); 271 // Also include the Armv8.4 defines 272 getTargetDefinesARMV84A(Opts, Builder); 273 } 274 275 void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts, 276 MacroBuilder &Builder) const { 277 // Also include the Armv8.5 defines 278 // FIXME: Armv8.6 makes the following extensions mandatory: 279 // - __ARM_FEATURE_BF16 280 // - __ARM_FEATURE_MATMUL_INT8 281 // Handle them here. 282 getTargetDefinesARMV85A(Opts, Builder); 283 } 284 285 void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, 286 MacroBuilder &Builder) const { 287 // Also include the Armv8.6 defines 288 getTargetDefinesARMV86A(Opts, Builder); 289 } 290 291 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts, 292 MacroBuilder &Builder) const { 293 // Also include the Armv8.7 defines 294 getTargetDefinesARMV87A(Opts, Builder); 295 } 296 297 void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts, 298 MacroBuilder &Builder) const { 299 // Also include the Armv8.8 defines 300 getTargetDefinesARMV88A(Opts, Builder); 301 } 302 303 void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts, 304 MacroBuilder &Builder) const { 305 // Armv9-A maps to Armv8.5-A 306 getTargetDefinesARMV85A(Opts, Builder); 307 } 308 309 void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts, 310 MacroBuilder &Builder) const { 311 // Armv9.1-A maps to Armv8.6-A 312 getTargetDefinesARMV86A(Opts, Builder); 313 } 314 315 void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts, 316 MacroBuilder &Builder) const { 317 // Armv9.2-A maps to Armv8.7-A 318 getTargetDefinesARMV87A(Opts, Builder); 319 } 320 321 void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts, 322 MacroBuilder &Builder) const { 323 // Armv9.3-A maps to Armv8.8-A 324 getTargetDefinesARMV88A(Opts, Builder); 325 } 326 327 void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts, 328 MacroBuilder &Builder) const { 329 // Armv9.4-A maps to Armv8.9-A 330 getTargetDefinesARMV89A(Opts, Builder); 331 } 332 333 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, 334 MacroBuilder &Builder) const { 335 // Target identification. 336 Builder.defineMacro("__aarch64__"); 337 // For bare-metal. 338 if (getTriple().getOS() == llvm::Triple::UnknownOS && 339 getTriple().isOSBinFormatELF()) 340 Builder.defineMacro("__ELF__"); 341 342 // Target properties. 343 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) { 344 Builder.defineMacro("_LP64"); 345 Builder.defineMacro("__LP64__"); 346 } 347 348 std::string CodeModel = getTargetOpts().CodeModel; 349 if (CodeModel == "default") 350 CodeModel = "small"; 351 for (char &c : CodeModel) 352 c = toupper(c); 353 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__"); 354 355 // ACLE predefines. Many can only have one possible value on v8 AArch64. 356 Builder.defineMacro("__ARM_ACLE", "200"); 357 Builder.defineMacro("__ARM_ARCH", 358 std::to_string(ArchInfo->Version.getMajor())); 359 Builder.defineMacro("__ARM_ARCH_PROFILE", 360 std::string("'") + (char)ArchInfo->Profile + "'"); 361 362 Builder.defineMacro("__ARM_64BIT_STATE", "1"); 363 Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); 364 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1"); 365 366 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 367 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 368 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF"); 369 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE 370 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility 371 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 372 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 373 374 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); 375 376 // 0xe implies support for half, single and double precision operations. 377 Builder.defineMacro("__ARM_FP", "0xE"); 378 379 // PCS specifies this for SysV variants, which is all we support. Other ABIs 380 // may choose __ARM_FP16_FORMAT_ALTERNATIVE. 381 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 382 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 383 384 if (Opts.UnsafeFPMath) 385 Builder.defineMacro("__ARM_FP_FAST", "1"); 386 387 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 388 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 389 390 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 391 392 if (FPU & NeonMode) { 393 Builder.defineMacro("__ARM_NEON", "1"); 394 // 64-bit NEON supports half, single and double precision operations. 395 Builder.defineMacro("__ARM_NEON_FP", "0xE"); 396 } 397 398 if (FPU & SveMode) 399 Builder.defineMacro("__ARM_FEATURE_SVE", "1"); 400 401 if ((FPU & NeonMode) && (FPU & SveMode)) 402 Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1"); 403 404 if (HasSVE2) 405 Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); 406 407 if (HasSVE2 && HasSVE2AES) 408 Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); 409 410 if (HasSVE2 && HasSVE2BitPerm) 411 Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1"); 412 413 if (HasSVE2 && HasSVE2SHA3) 414 Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1"); 415 416 if (HasSVE2 && HasSVE2SM4) 417 Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); 418 419 if (HasCRC) 420 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 421 422 if (HasRCPC) 423 Builder.defineMacro("__ARM_FEATURE_RCPC", "1"); 424 425 if (HasFMV) 426 Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1"); 427 428 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature 429 // macros for AES, SHA2, SHA3 and SM4 430 if (HasAES && HasSHA2) 431 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 432 433 if (HasAES) 434 Builder.defineMacro("__ARM_FEATURE_AES", "1"); 435 436 if (HasSHA2) 437 Builder.defineMacro("__ARM_FEATURE_SHA2", "1"); 438 439 if (HasSHA3) { 440 Builder.defineMacro("__ARM_FEATURE_SHA3", "1"); 441 Builder.defineMacro("__ARM_FEATURE_SHA512", "1"); 442 } 443 444 if (HasSM4) { 445 Builder.defineMacro("__ARM_FEATURE_SM3", "1"); 446 Builder.defineMacro("__ARM_FEATURE_SM4", "1"); 447 } 448 449 if (HasPAuth) 450 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); 451 452 if (HasUnaligned) 453 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 454 455 if ((FPU & NeonMode) && HasFullFP16) 456 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 457 if (HasFullFP16) 458 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 459 460 if (HasDotProd) 461 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 462 463 if (HasMTE) 464 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1"); 465 466 if (HasTME) 467 Builder.defineMacro("__ARM_FEATURE_TME", "1"); 468 469 if (HasMatMul) 470 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 471 472 if (HasLSE) 473 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); 474 475 if (HasBFloat16) { 476 Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 477 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 478 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 479 Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1"); 480 } 481 482 if ((FPU & SveMode) && HasBFloat16) { 483 Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1"); 484 } 485 486 if ((FPU & SveMode) && HasMatmulFP64) 487 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1"); 488 489 if ((FPU & SveMode) && HasMatmulFP32) 490 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1"); 491 492 if ((FPU & SveMode) && HasMatMul) 493 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1"); 494 495 if ((FPU & NeonMode) && HasFP16FML) 496 Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1"); 497 498 if (Opts.hasSignReturnAddress()) { 499 // Bitmask: 500 // 0: Protection using the A key 501 // 1: Protection using the B key 502 // 2: Protection including leaf functions 503 unsigned Value = 0; 504 505 if (Opts.isSignReturnAddressWithAKey()) 506 Value |= (1 << 0); 507 else 508 Value |= (1 << 1); 509 510 if (Opts.isSignReturnAddressScopeAll()) 511 Value |= (1 << 2); 512 513 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); 514 } 515 516 if (Opts.BranchTargetEnforcement) 517 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); 518 519 if (HasLS64) 520 Builder.defineMacro("__ARM_FEATURE_LS64", "1"); 521 522 if (HasRandGen) 523 Builder.defineMacro("__ARM_FEATURE_RNG", "1"); 524 525 if (HasMOPS) 526 Builder.defineMacro("__ARM_FEATURE_MOPS", "1"); 527 528 if (HasD128) 529 Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1"); 530 531 if (*ArchInfo == llvm::AArch64::ARMV8_1A) 532 getTargetDefinesARMV81A(Opts, Builder); 533 else if (*ArchInfo == llvm::AArch64::ARMV8_2A) 534 getTargetDefinesARMV82A(Opts, Builder); 535 else if (*ArchInfo == llvm::AArch64::ARMV8_3A) 536 getTargetDefinesARMV83A(Opts, Builder); 537 else if (*ArchInfo == llvm::AArch64::ARMV8_4A) 538 getTargetDefinesARMV84A(Opts, Builder); 539 else if (*ArchInfo == llvm::AArch64::ARMV8_5A) 540 getTargetDefinesARMV85A(Opts, Builder); 541 else if (*ArchInfo == llvm::AArch64::ARMV8_6A) 542 getTargetDefinesARMV86A(Opts, Builder); 543 else if (*ArchInfo == llvm::AArch64::ARMV8_7A) 544 getTargetDefinesARMV87A(Opts, Builder); 545 else if (*ArchInfo == llvm::AArch64::ARMV8_8A) 546 getTargetDefinesARMV88A(Opts, Builder); 547 else if (*ArchInfo == llvm::AArch64::ARMV8_9A) 548 getTargetDefinesARMV89A(Opts, Builder); 549 else if (*ArchInfo == llvm::AArch64::ARMV9A) 550 getTargetDefinesARMV9A(Opts, Builder); 551 else if (*ArchInfo == llvm::AArch64::ARMV9_1A) 552 getTargetDefinesARMV91A(Opts, Builder); 553 else if (*ArchInfo == llvm::AArch64::ARMV9_2A) 554 getTargetDefinesARMV92A(Opts, Builder); 555 else if (*ArchInfo == llvm::AArch64::ARMV9_3A) 556 getTargetDefinesARMV93A(Opts, Builder); 557 else if (*ArchInfo == llvm::AArch64::ARMV9_4A) 558 getTargetDefinesARMV94A(Opts, Builder); 559 560 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. 561 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 562 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 563 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 564 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 565 566 // Allow detection of fast FMA support. 567 Builder.defineMacro("__FP_FAST_FMA", "1"); 568 Builder.defineMacro("__FP_FAST_FMAF", "1"); 569 570 // C/C++ operators work on both VLS and VLA SVE types 571 if (FPU & SveMode) 572 Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2"); 573 574 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) { 575 Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128)); 576 } 577 } 578 579 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { 580 return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - 581 Builtin::FirstTSBuiltin); 582 } 583 584 std::optional<std::pair<unsigned, unsigned>> 585 AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { 586 if (LangOpts.VScaleMin || LangOpts.VScaleMax) 587 return std::pair<unsigned, unsigned>( 588 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax); 589 590 if (hasFeature("sve")) 591 return std::pair<unsigned, unsigned>(1, 16); 592 593 return std::nullopt; 594 } 595 596 unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const { 597 if (Name == "default") 598 return 0; 599 for (const auto &E : llvm::AArch64::Extensions) 600 if (Name == E.Name) 601 return E.FmvPriority; 602 return 0; 603 } 604 605 unsigned AArch64TargetInfo::multiVersionFeatureCost() const { 606 // Take the maximum priority as per feature cost, so more features win. 607 return llvm::AArch64::ExtensionInfo::MaxFMVPriority; 608 } 609 610 bool AArch64TargetInfo::getFeatureDepOptions(StringRef Name, 611 std::string &FeatureVec) const { 612 FeatureVec = ""; 613 for (const auto &E : llvm::AArch64::Extensions) { 614 if (Name == E.Name) { 615 FeatureVec = E.DependentFeatures; 616 break; 617 } 618 } 619 return FeatureVec != ""; 620 } 621 622 bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const { 623 for (const auto &E : llvm::AArch64::Extensions) 624 if (FeatureStr == E.Name) 625 return true; 626 return false; 627 } 628 629 bool AArch64TargetInfo::hasFeature(StringRef Feature) const { 630 return llvm::StringSwitch<bool>(Feature) 631 .Cases("aarch64", "arm64", "arm", true) 632 .Case("fmv", HasFMV) 633 .Cases("neon", "fp", "simd", FPU & NeonMode) 634 .Case("jscvt", HasJSCVT) 635 .Case("fcma", HasFCMA) 636 .Case("rng", HasRandGen) 637 .Case("flagm", HasFlagM) 638 .Case("flagm2", HasAlternativeNZCV) 639 .Case("fp16fml", HasFP16FML) 640 .Case("dotprod", HasDotProd) 641 .Case("sm4", HasSM4) 642 .Case("rdm", HasRDM) 643 .Case("lse", HasLSE) 644 .Case("crc", HasCRC) 645 .Case("sha2", HasSHA2) 646 .Case("sha3", HasSHA3) 647 .Cases("aes", "pmull", HasAES) 648 .Cases("fp16", "fullfp16", HasFullFP16) 649 .Case("dit", HasDIT) 650 .Case("dpb", HasCCPP) 651 .Case("dpb2", HasCCDP) 652 .Case("rcpc", HasRCPC) 653 .Case("frintts", HasFRInt3264) 654 .Case("i8mm", HasMatMul) 655 .Case("bf16", HasBFloat16) 656 .Case("sve", FPU & SveMode) 657 .Case("sve-bf16", FPU & SveMode && HasBFloat16) 658 .Case("sve-i8mm", FPU & SveMode && HasMatMul) 659 .Case("f32mm", FPU & SveMode && HasMatmulFP32) 660 .Case("f64mm", FPU & SveMode && HasMatmulFP64) 661 .Case("sve2", FPU & SveMode && HasSVE2) 662 .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES) 663 .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm) 664 .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3) 665 .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4) 666 .Case("sme", HasSME) 667 .Case("sme-f64f64", HasSMEF64) 668 .Case("sme-i16i64", HasSMEI64) 669 .Cases("memtag", "memtag2", HasMTE) 670 .Case("sb", HasSB) 671 .Case("predres", HasPredRes) 672 .Cases("ssbs", "ssbs2", HasSSBS) 673 .Case("bti", HasBTI) 674 .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64) 675 .Case("wfxt", HasWFxT) 676 .Default(false); 677 } 678 679 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 680 StringRef Name, bool Enabled) const { 681 Features[Name] = Enabled; 682 // If the feature is an architecture feature (like v8.2a), add all previous 683 // architecture versions and any dependant target features. 684 const llvm::AArch64::ArchInfo &ArchInfo = 685 llvm::AArch64::ArchInfo::findBySubArch(Name); 686 687 if (ArchInfo == llvm::AArch64::INVALID) 688 return; // Not an architecure, nothing more to do. 689 690 // Disabling an architecture feature does not affect dependent features 691 if (!Enabled) 692 return; 693 694 for (const auto *OtherArch : llvm::AArch64::ArchInfos) 695 if (ArchInfo.implies(*OtherArch)) 696 Features[OtherArch->getSubArch()] = true; 697 698 // Set any features implied by the architecture 699 uint64_t Extensions = 700 llvm::AArch64::getDefaultExtensions("generic", ArchInfo); 701 std::vector<StringRef> CPUFeats; 702 if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) { 703 for (auto F : CPUFeats) { 704 assert(F[0] == '+' && "Expected + in target feature!"); 705 Features[F.drop_front(1)] = true; 706 } 707 } 708 } 709 710 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 711 DiagnosticsEngine &Diags) { 712 for (const auto &Feature : Features) { 713 if (Feature == "-neon") 714 HasNoNeon = true; 715 if (Feature == "-sve") 716 HasNoSVE = true; 717 718 if (Feature == "+neon" || Feature == "+fp-armv8") 719 FPU |= NeonMode; 720 if (Feature == "+jscvt") { 721 HasJSCVT = true; 722 FPU |= NeonMode; 723 } 724 if (Feature == "+fcma") { 725 HasFCMA = true; 726 FPU |= NeonMode; 727 } 728 729 if (Feature == "+sve") { 730 FPU |= NeonMode; 731 FPU |= SveMode; 732 HasFullFP16 = true; 733 } 734 if (Feature == "+sve2") { 735 FPU |= NeonMode; 736 FPU |= SveMode; 737 HasFullFP16 = true; 738 HasSVE2 = true; 739 } 740 if (Feature == "+sve2-aes") { 741 FPU |= NeonMode; 742 FPU |= SveMode; 743 HasFullFP16 = true; 744 HasSVE2 = true; 745 HasSVE2AES = true; 746 } 747 if (Feature == "+sve2-sha3") { 748 FPU |= NeonMode; 749 FPU |= SveMode; 750 HasFullFP16 = true; 751 HasSVE2 = true; 752 HasSVE2SHA3 = true; 753 } 754 if (Feature == "+sve2-sm4") { 755 FPU |= NeonMode; 756 FPU |= SveMode; 757 HasFullFP16 = true; 758 HasSVE2 = true; 759 HasSVE2SM4 = true; 760 } 761 if (Feature == "+sve2-bitperm") { 762 FPU |= NeonMode; 763 FPU |= SveMode; 764 HasFullFP16 = true; 765 HasSVE2 = true; 766 HasSVE2BitPerm = true; 767 } 768 if (Feature == "+f32mm") { 769 FPU |= NeonMode; 770 FPU |= SveMode; 771 HasFullFP16 = true; 772 HasMatmulFP32 = true; 773 } 774 if (Feature == "+f64mm") { 775 FPU |= NeonMode; 776 FPU |= SveMode; 777 HasFullFP16 = true; 778 HasMatmulFP64 = true; 779 } 780 if (Feature == "+sme") { 781 HasSME = true; 782 HasBFloat16 = true; 783 } 784 if (Feature == "+sme-f64f64") { 785 HasSME = true; 786 HasSMEF64 = true; 787 HasBFloat16 = true; 788 } 789 if (Feature == "+sme-i16i64") { 790 HasSME = true; 791 HasSMEI64 = true; 792 HasBFloat16 = true; 793 } 794 if (Feature == "+sb") 795 HasSB = true; 796 if (Feature == "+predres") 797 HasPredRes = true; 798 if (Feature == "+ssbs") 799 HasSSBS = true; 800 if (Feature == "+bti") 801 HasBTI = true; 802 if (Feature == "+wfxt") 803 HasWFxT = true; 804 if (Feature == "-fmv") 805 HasFMV = false; 806 if (Feature == "+crc") 807 HasCRC = true; 808 if (Feature == "+rcpc") 809 HasRCPC = true; 810 if (Feature == "+aes") { 811 FPU |= NeonMode; 812 HasAES = true; 813 } 814 if (Feature == "+sha2") { 815 FPU |= NeonMode; 816 HasSHA2 = true; 817 } 818 if (Feature == "+sha3") { 819 FPU |= NeonMode; 820 HasSHA2 = true; 821 HasSHA3 = true; 822 } 823 if (Feature == "+rdm") { 824 FPU |= NeonMode; 825 HasRDM = true; 826 } 827 if (Feature == "+dit") 828 HasDIT = true; 829 if (Feature == "+cccp") 830 HasCCPP = true; 831 if (Feature == "+ccdp") { 832 HasCCPP = true; 833 HasCCDP = true; 834 } 835 if (Feature == "+fptoint") 836 HasFRInt3264 = true; 837 if (Feature == "+sm4") { 838 FPU |= NeonMode; 839 HasSM4 = true; 840 } 841 if (Feature == "+strict-align") 842 HasUnaligned = false; 843 // All predecessor archs are added but select the latest one for ArchKind. 844 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version) 845 ArchInfo = &llvm::AArch64::ARMV8A; 846 if (Feature == "+v8.1a" && 847 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version) 848 ArchInfo = &llvm::AArch64::ARMV8_1A; 849 if (Feature == "+v8.2a" && 850 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version) 851 ArchInfo = &llvm::AArch64::ARMV8_2A; 852 if (Feature == "+v8.3a" && 853 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version) 854 ArchInfo = &llvm::AArch64::ARMV8_3A; 855 if (Feature == "+v8.4a" && 856 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version) 857 ArchInfo = &llvm::AArch64::ARMV8_4A; 858 if (Feature == "+v8.5a" && 859 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version) 860 ArchInfo = &llvm::AArch64::ARMV8_5A; 861 if (Feature == "+v8.6a" && 862 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version) 863 ArchInfo = &llvm::AArch64::ARMV8_6A; 864 if (Feature == "+v8.7a" && 865 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version) 866 ArchInfo = &llvm::AArch64::ARMV8_7A; 867 if (Feature == "+v8.8a" && 868 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version) 869 ArchInfo = &llvm::AArch64::ARMV8_8A; 870 if (Feature == "+v8.9a" && 871 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version) 872 ArchInfo = &llvm::AArch64::ARMV8_9A; 873 if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version) 874 ArchInfo = &llvm::AArch64::ARMV9A; 875 if (Feature == "+v9.1a" && 876 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version) 877 ArchInfo = &llvm::AArch64::ARMV9_1A; 878 if (Feature == "+v9.2a" && 879 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version) 880 ArchInfo = &llvm::AArch64::ARMV9_2A; 881 if (Feature == "+v9.3a" && 882 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version) 883 ArchInfo = &llvm::AArch64::ARMV9_3A; 884 if (Feature == "+v9.4a" && 885 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version) 886 ArchInfo = &llvm::AArch64::ARMV9_4A; 887 if (Feature == "+v8r") 888 ArchInfo = &llvm::AArch64::ARMV8R; 889 if (Feature == "+fullfp16") { 890 FPU |= NeonMode; 891 HasFullFP16 = true; 892 } 893 if (Feature == "+dotprod") { 894 FPU |= NeonMode; 895 HasDotProd = true; 896 } 897 if (Feature == "+fp16fml") { 898 FPU |= NeonMode; 899 HasFullFP16 = true; 900 HasFP16FML = true; 901 } 902 if (Feature == "+mte") 903 HasMTE = true; 904 if (Feature == "+tme") 905 HasTME = true; 906 if (Feature == "+pauth") 907 HasPAuth = true; 908 if (Feature == "+i8mm") 909 HasMatMul = true; 910 if (Feature == "+bf16") 911 HasBFloat16 = true; 912 if (Feature == "+lse") 913 HasLSE = true; 914 if (Feature == "+ls64") 915 HasLS64 = true; 916 if (Feature == "+rand") 917 HasRandGen = true; 918 if (Feature == "+flagm") 919 HasFlagM = true; 920 if (Feature == "+altnzcv") { 921 HasFlagM = true; 922 HasAlternativeNZCV = true; 923 } 924 if (Feature == "+mops") 925 HasMOPS = true; 926 if (Feature == "+d128") 927 HasD128 = true; 928 } 929 930 // Check features that are manually disabled by command line options. 931 // This needs to be checked after architecture-related features are handled, 932 // making sure they are properly disabled when required. 933 for (const auto &Feature : Features) { 934 if (Feature == "-d128") 935 HasD128 = false; 936 } 937 938 setDataLayout(); 939 setArchFeatures(); 940 941 if (HasNoNeon) { 942 FPU &= ~NeonMode; 943 FPU &= ~SveMode; 944 } 945 if (HasNoSVE) 946 FPU &= ~SveMode; 947 948 return true; 949 } 950 951 bool AArch64TargetInfo::initFeatureMap( 952 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 953 const std::vector<std::string> &FeaturesVec) const { 954 std::vector<std::string> UpdatedFeaturesVec; 955 // Parse the CPU and add any implied features. 956 const llvm::AArch64::ArchInfo &Arch = llvm::AArch64::parseCpu(CPU).Arch; 957 if (Arch != llvm::AArch64::INVALID) { 958 uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, Arch); 959 std::vector<StringRef> CPUFeats; 960 llvm::AArch64::getExtensionFeatures(Exts, CPUFeats); 961 for (auto F : CPUFeats) { 962 assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!"); 963 UpdatedFeaturesVec.push_back(F.str()); 964 } 965 } 966 967 // Process target and dependent features. This is done in two loops collecting 968 // them into UpdatedFeaturesVec: first to add dependent '+'features, 969 // second to add target '+/-'features that can later disable some of 970 // features added on the first loop. 971 for (const auto &Feature : FeaturesVec) 972 if ((Feature[0] == '?' || Feature[0] == '+')) { 973 std::string Options; 974 if (AArch64TargetInfo::getFeatureDepOptions(Feature.substr(1), Options)) { 975 SmallVector<StringRef, 1> AttrFeatures; 976 StringRef(Options).split(AttrFeatures, ","); 977 for (auto F : AttrFeatures) 978 UpdatedFeaturesVec.push_back(F.str()); 979 } 980 } 981 for (const auto &Feature : FeaturesVec) 982 if (Feature[0] == '+') { 983 std::string F; 984 llvm::AArch64::getFeatureOption(Feature, F); 985 UpdatedFeaturesVec.push_back(F); 986 } else if (Feature[0] != '?') 987 UpdatedFeaturesVec.push_back(Feature); 988 989 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); 990 } 991 992 // Parse AArch64 Target attributes, which are a comma separated list of: 993 // "arch=<arch>" - parsed to features as per -march=.. 994 // "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu> 995 // "tune=<cpu>" - TuneCPU set to <cpu> 996 // "feature", "no-feature" - Add (or remove) feature. 997 // "+feature", "+nofeature" - Add (or remove) feature. 998 ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { 999 ParsedTargetAttr Ret; 1000 if (Features == "default") 1001 return Ret; 1002 SmallVector<StringRef, 1> AttrFeatures; 1003 Features.split(AttrFeatures, ","); 1004 bool FoundArch = false; 1005 1006 auto SplitAndAddFeatures = [](StringRef FeatString, 1007 std::vector<std::string> &Features) { 1008 SmallVector<StringRef, 8> SplitFeatures; 1009 FeatString.split(SplitFeatures, StringRef("+"), -1, false); 1010 for (StringRef Feature : SplitFeatures) { 1011 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); 1012 if (!FeatureName.empty()) 1013 Features.push_back(FeatureName.str()); 1014 else 1015 // Pushing the original feature string to give a sema error later on 1016 // when they get checked. 1017 if (Feature.startswith("no")) 1018 Features.push_back("-" + Feature.drop_front(2).str()); 1019 else 1020 Features.push_back("+" + Feature.str()); 1021 } 1022 }; 1023 1024 for (auto &Feature : AttrFeatures) { 1025 Feature = Feature.trim(); 1026 if (Feature.startswith("fpmath=")) 1027 continue; 1028 1029 if (Feature.startswith("branch-protection=")) { 1030 Ret.BranchProtection = Feature.split('=').second.trim(); 1031 continue; 1032 } 1033 1034 if (Feature.startswith("arch=")) { 1035 if (FoundArch) 1036 Ret.Duplicate = "arch="; 1037 FoundArch = true; 1038 std::pair<StringRef, StringRef> Split = 1039 Feature.split("=").second.trim().split("+"); 1040 const llvm::AArch64::ArchInfo &AI = llvm::AArch64::parseArch(Split.first); 1041 1042 // Parse the architecture version, adding the required features to 1043 // Ret.Features. 1044 if (AI == llvm::AArch64::INVALID) 1045 continue; 1046 Ret.Features.push_back(AI.ArchFeature.str()); 1047 // Add any extra features, after the + 1048 SplitAndAddFeatures(Split.second, Ret.Features); 1049 } else if (Feature.startswith("cpu=")) { 1050 if (!Ret.CPU.empty()) 1051 Ret.Duplicate = "cpu="; 1052 else { 1053 // Split the cpu string into "cpu=", "cortex-a710" and any remaining 1054 // "+feat" features. 1055 std::pair<StringRef, StringRef> Split = 1056 Feature.split("=").second.trim().split("+"); 1057 Ret.CPU = Split.first; 1058 SplitAndAddFeatures(Split.second, Ret.Features); 1059 } 1060 } else if (Feature.startswith("tune=")) { 1061 if (!Ret.Tune.empty()) 1062 Ret.Duplicate = "tune="; 1063 else 1064 Ret.Tune = Feature.split("=").second.trim(); 1065 } else if (Feature.startswith("+")) { 1066 SplitAndAddFeatures(Feature, Ret.Features); 1067 } else if (Feature.startswith("no-")) { 1068 StringRef FeatureName = 1069 llvm::AArch64::getArchExtFeature(Feature.split("-").second); 1070 if (!FeatureName.empty()) 1071 Ret.Features.push_back("-" + FeatureName.drop_front(1).str()); 1072 else 1073 Ret.Features.push_back("-" + Feature.split("-").second.str()); 1074 } else { 1075 // Try parsing the string to the internal target feature name. If it is 1076 // invalid, add the original string (which could already be an internal 1077 // name). These should be checked later by isValidFeatureName. 1078 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); 1079 if (!FeatureName.empty()) 1080 Ret.Features.push_back(FeatureName.str()); 1081 else 1082 Ret.Features.push_back("+" + Feature.str()); 1083 } 1084 } 1085 return Ret; 1086 } 1087 1088 bool AArch64TargetInfo::hasBFloat16Type() const { 1089 return true; 1090 } 1091 1092 TargetInfo::CallingConvCheckResult 1093 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { 1094 switch (CC) { 1095 case CC_C: 1096 case CC_Swift: 1097 case CC_SwiftAsync: 1098 case CC_PreserveMost: 1099 case CC_PreserveAll: 1100 case CC_OpenCLKernel: 1101 case CC_AArch64VectorCall: 1102 case CC_AArch64SVEPCS: 1103 case CC_Win64: 1104 return CCCR_OK; 1105 default: 1106 return CCCR_Warning; 1107 } 1108 } 1109 1110 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } 1111 1112 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { 1113 return TargetInfo::AArch64ABIBuiltinVaList; 1114 } 1115 1116 const char *const AArch64TargetInfo::GCCRegNames[] = { 1117 // 32-bit Integer registers 1118 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", 1119 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", 1120 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", 1121 1122 // 64-bit Integer registers 1123 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", 1124 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", 1125 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", 1126 1127 // 32-bit floating point regsisters 1128 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 1129 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 1130 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 1131 1132 // 64-bit floating point regsisters 1133 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 1134 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 1135 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 1136 1137 // Neon vector registers 1138 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", 1139 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", 1140 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 1141 1142 // SVE vector registers 1143 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", 1144 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", 1145 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31", 1146 1147 // SVE predicate registers 1148 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", 1149 "p11", "p12", "p13", "p14", "p15" 1150 }; 1151 1152 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { 1153 return llvm::ArrayRef(GCCRegNames); 1154 } 1155 1156 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 1157 {{"w31"}, "wsp"}, 1158 {{"x31"}, "sp"}, 1159 // GCC rN registers are aliases of xN registers. 1160 {{"r0"}, "x0"}, 1161 {{"r1"}, "x1"}, 1162 {{"r2"}, "x2"}, 1163 {{"r3"}, "x3"}, 1164 {{"r4"}, "x4"}, 1165 {{"r5"}, "x5"}, 1166 {{"r6"}, "x6"}, 1167 {{"r7"}, "x7"}, 1168 {{"r8"}, "x8"}, 1169 {{"r9"}, "x9"}, 1170 {{"r10"}, "x10"}, 1171 {{"r11"}, "x11"}, 1172 {{"r12"}, "x12"}, 1173 {{"r13"}, "x13"}, 1174 {{"r14"}, "x14"}, 1175 {{"r15"}, "x15"}, 1176 {{"r16"}, "x16"}, 1177 {{"r17"}, "x17"}, 1178 {{"r18"}, "x18"}, 1179 {{"r19"}, "x19"}, 1180 {{"r20"}, "x20"}, 1181 {{"r21"}, "x21"}, 1182 {{"r22"}, "x22"}, 1183 {{"r23"}, "x23"}, 1184 {{"r24"}, "x24"}, 1185 {{"r25"}, "x25"}, 1186 {{"r26"}, "x26"}, 1187 {{"r27"}, "x27"}, 1188 {{"r28"}, "x28"}, 1189 {{"r29", "x29"}, "fp"}, 1190 {{"r30", "x30"}, "lr"}, 1191 // The S/D/Q and W/X registers overlap, but aren't really aliases; we 1192 // don't want to substitute one of these for a different-sized one. 1193 }; 1194 1195 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { 1196 return llvm::ArrayRef(GCCRegAliases); 1197 } 1198 1199 bool AArch64TargetInfo::validateAsmConstraint( 1200 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1201 switch (*Name) { 1202 default: 1203 return false; 1204 case 'w': // Floating point and SIMD registers (V0-V31) 1205 Info.setAllowsRegister(); 1206 return true; 1207 case 'I': // Constant that can be used with an ADD instruction 1208 case 'J': // Constant that can be used with a SUB instruction 1209 case 'K': // Constant that can be used with a 32-bit logical instruction 1210 case 'L': // Constant that can be used with a 64-bit logical instruction 1211 case 'M': // Constant that can be used as a 32-bit MOV immediate 1212 case 'N': // Constant that can be used as a 64-bit MOV immediate 1213 case 'Y': // Floating point constant zero 1214 case 'Z': // Integer constant zero 1215 return true; 1216 case 'Q': // A memory reference with base register and no offset 1217 Info.setAllowsMemory(); 1218 return true; 1219 case 'S': // A symbolic address 1220 Info.setAllowsRegister(); 1221 return true; 1222 case 'U': 1223 if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) { 1224 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7) 1225 Info.setAllowsRegister(); 1226 Name += 2; 1227 return true; 1228 } 1229 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. 1230 // Utf: A memory address suitable for ldp/stp in TF mode. 1231 // Usa: An absolute symbolic address. 1232 // Ush: The high part (bits 32:12) of a pc-relative symbolic address. 1233 1234 // Better to return an error saying that it's an unrecognised constraint 1235 // even if this is a valid constraint in gcc. 1236 return false; 1237 case 'z': // Zero register, wzr or xzr 1238 Info.setAllowsRegister(); 1239 return true; 1240 case 'x': // Floating point and SIMD registers (V0-V15) 1241 Info.setAllowsRegister(); 1242 return true; 1243 case 'y': // SVE registers (V0-V7) 1244 Info.setAllowsRegister(); 1245 return true; 1246 } 1247 return false; 1248 } 1249 1250 bool AArch64TargetInfo::validateConstraintModifier( 1251 StringRef Constraint, char Modifier, unsigned Size, 1252 std::string &SuggestedModifier) const { 1253 // Strip off constraint modifiers. 1254 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1255 Constraint = Constraint.substr(1); 1256 1257 switch (Constraint[0]) { 1258 default: 1259 return true; 1260 case 'z': 1261 case 'r': { 1262 switch (Modifier) { 1263 case 'x': 1264 case 'w': 1265 // For now assume that the person knows what they're 1266 // doing with the modifier. 1267 return true; 1268 default: 1269 // By default an 'r' constraint will be in the 'x' 1270 // registers. 1271 if (Size == 64) 1272 return true; 1273 1274 if (Size == 512) 1275 return HasLS64; 1276 1277 SuggestedModifier = "w"; 1278 return false; 1279 } 1280 } 1281 } 1282 } 1283 1284 const char *AArch64TargetInfo::getClobbers() const { return ""; } 1285 1286 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1287 if (RegNo == 0) 1288 return 0; 1289 if (RegNo == 1) 1290 return 1; 1291 return -1; 1292 } 1293 1294 bool AArch64TargetInfo::hasInt128Type() const { return true; } 1295 1296 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, 1297 const TargetOptions &Opts) 1298 : AArch64TargetInfo(Triple, Opts) {} 1299 1300 void AArch64leTargetInfo::setDataLayout() { 1301 if (getTriple().isOSBinFormatMachO()) { 1302 if(getTriple().isArch32Bit()) 1303 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_"); 1304 else 1305 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_"); 1306 } else 1307 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 1308 } 1309 1310 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, 1311 MacroBuilder &Builder) const { 1312 Builder.defineMacro("__AARCH64EL__"); 1313 AArch64TargetInfo::getTargetDefines(Opts, Builder); 1314 } 1315 1316 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, 1317 const TargetOptions &Opts) 1318 : AArch64TargetInfo(Triple, Opts) {} 1319 1320 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, 1321 MacroBuilder &Builder) const { 1322 Builder.defineMacro("__AARCH64EB__"); 1323 Builder.defineMacro("__AARCH_BIG_ENDIAN"); 1324 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1325 AArch64TargetInfo::getTargetDefines(Opts, Builder); 1326 } 1327 1328 void AArch64beTargetInfo::setDataLayout() { 1329 assert(!getTriple().isOSBinFormatMachO()); 1330 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 1331 } 1332 1333 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, 1334 const TargetOptions &Opts) 1335 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { 1336 1337 // This is an LLP64 platform. 1338 // int:4, long:4, long long:8, long double:8. 1339 IntWidth = IntAlign = 32; 1340 LongWidth = LongAlign = 32; 1341 DoubleAlign = LongLongAlign = 64; 1342 LongDoubleWidth = LongDoubleAlign = 64; 1343 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 1344 IntMaxType = SignedLongLong; 1345 Int64Type = SignedLongLong; 1346 SizeType = UnsignedLongLong; 1347 PtrDiffType = SignedLongLong; 1348 IntPtrType = SignedLongLong; 1349 } 1350 1351 void WindowsARM64TargetInfo::setDataLayout() { 1352 resetDataLayout(Triple.isOSBinFormatMachO() 1353 ? "e-m:o-i64:64-i128:128-n32:64-S128" 1354 : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128", 1355 Triple.isOSBinFormatMachO() ? "_" : ""); 1356 } 1357 1358 TargetInfo::BuiltinVaListKind 1359 WindowsARM64TargetInfo::getBuiltinVaListKind() const { 1360 return TargetInfo::CharPtrBuiltinVaList; 1361 } 1362 1363 TargetInfo::CallingConvCheckResult 1364 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { 1365 switch (CC) { 1366 case CC_X86StdCall: 1367 case CC_X86ThisCall: 1368 case CC_X86FastCall: 1369 case CC_X86VectorCall: 1370 return CCCR_Ignore; 1371 case CC_C: 1372 case CC_OpenCLKernel: 1373 case CC_PreserveMost: 1374 case CC_PreserveAll: 1375 case CC_Swift: 1376 case CC_SwiftAsync: 1377 case CC_Win64: 1378 return CCCR_OK; 1379 default: 1380 return CCCR_Warning; 1381 } 1382 } 1383 1384 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, 1385 const TargetOptions &Opts) 1386 : WindowsARM64TargetInfo(Triple, Opts) { 1387 TheCXXABI.set(TargetCXXABI::Microsoft); 1388 } 1389 1390 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, 1391 MacroBuilder &Builder) const { 1392 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder); 1393 Builder.defineMacro("_M_ARM64", "1"); 1394 } 1395 1396 TargetInfo::CallingConvKind 1397 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { 1398 return CCK_MicrosoftWin64; 1399 } 1400 1401 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const { 1402 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize); 1403 1404 // MSVC does size based alignment for arm64 based on alignment section in 1405 // below document, replicate that to keep alignment consistent with object 1406 // files compiled by MSVC. 1407 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions 1408 if (TypeSize >= 512) { // TypeSize >= 64 bytes 1409 Align = std::max(Align, 128u); // align type at least 16 bytes 1410 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes 1411 Align = std::max(Align, 64u); // align type at least 8 butes 1412 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes 1413 Align = std::max(Align, 32u); // align type at least 4 bytes 1414 } 1415 return Align; 1416 } 1417 1418 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, 1419 const TargetOptions &Opts) 1420 : WindowsARM64TargetInfo(Triple, Opts) { 1421 TheCXXABI.set(TargetCXXABI::GenericAArch64); 1422 } 1423 1424 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, 1425 const TargetOptions &Opts) 1426 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { 1427 Int64Type = SignedLongLong; 1428 if (getTriple().isArch32Bit()) 1429 IntMaxType = SignedLongLong; 1430 1431 WCharType = SignedInt; 1432 UseSignedCharForObjCBool = false; 1433 1434 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; 1435 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 1436 1437 UseZeroLengthBitfieldAlignment = false; 1438 1439 if (getTriple().isArch32Bit()) { 1440 UseBitFieldTypeAlignment = false; 1441 ZeroLengthBitfieldBoundary = 32; 1442 UseZeroLengthBitfieldAlignment = true; 1443 TheCXXABI.set(TargetCXXABI::WatchOS); 1444 } else 1445 TheCXXABI.set(TargetCXXABI::AppleARM64); 1446 } 1447 1448 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, 1449 const llvm::Triple &Triple, 1450 MacroBuilder &Builder) const { 1451 Builder.defineMacro("__AARCH64_SIMD__"); 1452 if (Triple.isArch32Bit()) 1453 Builder.defineMacro("__ARM64_ARCH_8_32__"); 1454 else 1455 Builder.defineMacro("__ARM64_ARCH_8__"); 1456 Builder.defineMacro("__ARM_NEON__"); 1457 Builder.defineMacro("__LITTLE_ENDIAN__"); 1458 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1459 Builder.defineMacro("__arm64", "1"); 1460 Builder.defineMacro("__arm64__", "1"); 1461 1462 if (Triple.isArm64e()) 1463 Builder.defineMacro("__arm64e__", "1"); 1464 1465 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1466 } 1467 1468 TargetInfo::BuiltinVaListKind 1469 DarwinAArch64TargetInfo::getBuiltinVaListKind() const { 1470 return TargetInfo::CharPtrBuiltinVaList; 1471 } 1472 1473 // 64-bit RenderScript is aarch64 1474 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, 1475 const TargetOptions &Opts) 1476 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), 1477 Triple.getOSName(), 1478 Triple.getEnvironmentName()), 1479 Opts) { 1480 IsRenderScriptTarget = true; 1481 } 1482 1483 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, 1484 MacroBuilder &Builder) const { 1485 Builder.defineMacro("__RENDERSCRIPT__"); 1486 AArch64leTargetInfo::getTargetDefines(Opts, Builder); 1487 } 1488