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 22 using namespace clang; 23 using namespace clang::targets; 24 25 const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { 26 #define BUILTIN(ID, TYPE, ATTRS) \ 27 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 28 #include "clang/Basic/BuiltinsNEON.def" 29 30 #define BUILTIN(ID, TYPE, ATTRS) \ 31 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 32 #include "clang/Basic/BuiltinsSVE.def" 33 34 #define BUILTIN(ID, TYPE, ATTRS) \ 35 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 36 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 37 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 38 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 39 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 40 #include "clang/Basic/BuiltinsAArch64.def" 41 }; 42 43 static StringRef getArchVersionString(llvm::AArch64::ArchKind Kind) { 44 switch (Kind) { 45 case llvm::AArch64::ArchKind::ARMV9A: 46 case llvm::AArch64::ArchKind::ARMV9_1A: 47 case llvm::AArch64::ArchKind::ARMV9_2A: 48 case llvm::AArch64::ArchKind::ARMV9_3A: 49 return "9"; 50 default: 51 return "8"; 52 } 53 } 54 55 StringRef AArch64TargetInfo::getArchProfile() const { 56 switch (ArchKind) { 57 case llvm::AArch64::ArchKind::ARMV8R: 58 return "R"; 59 default: 60 return "A"; 61 } 62 } 63 64 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, 65 const TargetOptions &Opts) 66 : TargetInfo(Triple), ABI("aapcs") { 67 if (getTriple().isOSOpenBSD()) { 68 Int64Type = SignedLongLong; 69 IntMaxType = SignedLongLong; 70 } else { 71 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD()) 72 WCharType = UnsignedInt; 73 74 Int64Type = SignedLong; 75 IntMaxType = SignedLong; 76 } 77 78 // All AArch64 implementations support ARMv8 FP, which makes half a legal type. 79 HasLegalHalfType = true; 80 HasFloat16 = true; 81 82 if (Triple.isArch64Bit()) 83 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 84 else 85 LongWidth = LongAlign = PointerWidth = PointerAlign = 32; 86 87 MaxVectorAlign = 128; 88 MaxAtomicInlineWidth = 128; 89 MaxAtomicPromoteWidth = 128; 90 91 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; 92 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 93 94 BFloat16Width = BFloat16Align = 16; 95 BFloat16Format = &llvm::APFloat::BFloat(); 96 97 // Make __builtin_ms_va_list available. 98 HasBuiltinMSVaList = true; 99 100 // Make the SVE types available. Note that this deliberately doesn't 101 // depend on SveMode, since in principle it should be possible to turn 102 // SVE on and off within a translation unit. It should also be possible 103 // to compile the global declaration: 104 // 105 // __SVInt8_t *ptr; 106 // 107 // even without SVE. 108 HasAArch64SVETypes = true; 109 110 // {} in inline assembly are neon specifiers, not assembly variant 111 // specifiers. 112 NoAsmVariants = true; 113 114 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type 115 // contributes to the alignment of the containing aggregate in the same way 116 // a plain (non bit-field) member of that type would, without exception for 117 // zero-sized or anonymous bit-fields." 118 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment"); 119 UseZeroLengthBitfieldAlignment = true; 120 121 // AArch64 targets default to using the ARM C++ ABI. 122 TheCXXABI.set(TargetCXXABI::GenericAArch64); 123 124 if (Triple.getOS() == llvm::Triple::Linux) 125 this->MCountName = "\01_mcount"; 126 else if (Triple.getOS() == llvm::Triple::UnknownOS) 127 this->MCountName = 128 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount"; 129 } 130 131 StringRef AArch64TargetInfo::getABI() const { return ABI; } 132 133 bool AArch64TargetInfo::setABI(const std::string &Name) { 134 if (Name != "aapcs" && Name != "darwinpcs") 135 return false; 136 137 ABI = Name; 138 return true; 139 } 140 141 bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, 142 BranchProtectionInfo &BPI, 143 StringRef &Err) const { 144 llvm::ARM::ParsedBranchProtection PBP; 145 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) 146 return false; 147 148 BPI.SignReturnAddr = 149 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) 150 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) 151 .Case("all", LangOptions::SignReturnAddressScopeKind::All) 152 .Default(LangOptions::SignReturnAddressScopeKind::None); 153 154 if (PBP.Key == "a_key") 155 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; 156 else 157 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; 158 159 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; 160 return true; 161 } 162 163 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { 164 return Name == "generic" || 165 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID; 166 } 167 168 bool AArch64TargetInfo::setCPU(const std::string &Name) { 169 return isValidCPUName(Name); 170 } 171 172 void AArch64TargetInfo::fillValidCPUList( 173 SmallVectorImpl<StringRef> &Values) const { 174 llvm::AArch64::fillValidCPUArchList(Values); 175 } 176 177 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 178 MacroBuilder &Builder) const { 179 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 180 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); 181 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 182 } 183 184 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 185 MacroBuilder &Builder) const { 186 // Also include the ARMv8.1 defines 187 getTargetDefinesARMV81A(Opts, Builder); 188 } 189 190 void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 191 MacroBuilder &Builder) const { 192 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 193 Builder.defineMacro("__ARM_FEATURE_JCVT", "1"); 194 // Also include the Armv8.2 defines 195 getTargetDefinesARMV82A(Opts, Builder); 196 } 197 198 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, 199 MacroBuilder &Builder) const { 200 // Also include the Armv8.3 defines 201 getTargetDefinesARMV83A(Opts, Builder); 202 } 203 204 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, 205 MacroBuilder &Builder) const { 206 Builder.defineMacro("__ARM_FEATURE_FRINT", "1"); 207 // Also include the Armv8.4 defines 208 getTargetDefinesARMV84A(Opts, Builder); 209 } 210 211 void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts, 212 MacroBuilder &Builder) const { 213 // Also include the Armv8.5 defines 214 // FIXME: Armv8.6 makes the following extensions mandatory: 215 // - __ARM_FEATURE_BF16 216 // - __ARM_FEATURE_MATMUL_INT8 217 // Handle them here. 218 getTargetDefinesARMV85A(Opts, Builder); 219 } 220 221 void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, 222 MacroBuilder &Builder) const { 223 // Also include the Armv8.6 defines 224 getTargetDefinesARMV86A(Opts, Builder); 225 } 226 227 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts, 228 MacroBuilder &Builder) const { 229 // Also include the Armv8.7 defines 230 getTargetDefinesARMV87A(Opts, Builder); 231 } 232 233 void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts, 234 MacroBuilder &Builder) const { 235 // Armv9-A maps to Armv8.5-A 236 getTargetDefinesARMV85A(Opts, Builder); 237 } 238 239 void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts, 240 MacroBuilder &Builder) const { 241 // Armv9.1-A maps to Armv8.6-A 242 getTargetDefinesARMV86A(Opts, Builder); 243 } 244 245 void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts, 246 MacroBuilder &Builder) const { 247 // Armv9.2-A maps to Armv8.7-A 248 getTargetDefinesARMV87A(Opts, Builder); 249 } 250 251 void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts, 252 MacroBuilder &Builder) const { 253 // Armv9.3-A maps to Armv8.8-A 254 getTargetDefinesARMV88A(Opts, Builder); 255 } 256 257 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, 258 MacroBuilder &Builder) const { 259 // Target identification. 260 Builder.defineMacro("__aarch64__"); 261 // For bare-metal. 262 if (getTriple().getOS() == llvm::Triple::UnknownOS && 263 getTriple().isOSBinFormatELF()) 264 Builder.defineMacro("__ELF__"); 265 266 // Target properties. 267 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) { 268 Builder.defineMacro("_LP64"); 269 Builder.defineMacro("__LP64__"); 270 } 271 272 std::string CodeModel = getTargetOpts().CodeModel; 273 if (CodeModel == "default") 274 CodeModel = "small"; 275 for (char &c : CodeModel) 276 c = toupper(c); 277 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__"); 278 279 // ACLE predefines. Many can only have one possible value on v8 AArch64. 280 Builder.defineMacro("__ARM_ACLE", "200"); 281 Builder.defineMacro("__ARM_ARCH", getArchVersionString(ArchKind)); 282 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + getArchProfile() + "'"); 283 284 Builder.defineMacro("__ARM_64BIT_STATE", "1"); 285 Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); 286 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1"); 287 288 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 289 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 290 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF"); 291 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE 292 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility 293 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 294 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 295 296 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); 297 298 // 0xe implies support for half, single and double precision operations. 299 Builder.defineMacro("__ARM_FP", "0xE"); 300 301 // PCS specifies this for SysV variants, which is all we support. Other ABIs 302 // may choose __ARM_FP16_FORMAT_ALTERNATIVE. 303 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 304 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 305 306 if (Opts.UnsafeFPMath) 307 Builder.defineMacro("__ARM_FP_FAST", "1"); 308 309 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 310 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 311 312 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 313 314 if (FPU & NeonMode) { 315 Builder.defineMacro("__ARM_NEON", "1"); 316 // 64-bit NEON supports half, single and double precision operations. 317 Builder.defineMacro("__ARM_NEON_FP", "0xE"); 318 } 319 320 if (FPU & SveMode) 321 Builder.defineMacro("__ARM_FEATURE_SVE", "1"); 322 323 if ((FPU & NeonMode) && (FPU & SveMode)) 324 Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1"); 325 326 if (HasSVE2) 327 Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); 328 329 if (HasSVE2 && HasSVE2AES) 330 Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); 331 332 if (HasSVE2 && HasSVE2BitPerm) 333 Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1"); 334 335 if (HasSVE2 && HasSVE2SHA3) 336 Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1"); 337 338 if (HasSVE2 && HasSVE2SM4) 339 Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); 340 341 if (HasCRC) 342 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 343 344 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature 345 // macros for AES, SHA2, SHA3 and SM4 346 if (HasAES && HasSHA2) 347 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 348 349 if (HasAES) 350 Builder.defineMacro("__ARM_FEATURE_AES", "1"); 351 352 if (HasSHA2) 353 Builder.defineMacro("__ARM_FEATURE_SHA2", "1"); 354 355 if (HasSHA3) { 356 Builder.defineMacro("__ARM_FEATURE_SHA3", "1"); 357 Builder.defineMacro("__ARM_FEATURE_SHA512", "1"); 358 } 359 360 if (HasSM4) { 361 Builder.defineMacro("__ARM_FEATURE_SM3", "1"); 362 Builder.defineMacro("__ARM_FEATURE_SM4", "1"); 363 } 364 365 if (HasUnaligned) 366 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 367 368 if ((FPU & NeonMode) && HasFullFP16) 369 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 370 if (HasFullFP16) 371 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 372 373 if (HasDotProd) 374 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 375 376 if (HasMTE) 377 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1"); 378 379 if (HasTME) 380 Builder.defineMacro("__ARM_FEATURE_TME", "1"); 381 382 if (HasMatMul) 383 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 384 385 if (HasLSE) 386 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); 387 388 if (HasBFloat16) { 389 Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 390 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 391 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 392 Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1"); 393 } 394 395 if ((FPU & SveMode) && HasBFloat16) { 396 Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1"); 397 } 398 399 if ((FPU & SveMode) && HasMatmulFP64) 400 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1"); 401 402 if ((FPU & SveMode) && HasMatmulFP32) 403 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1"); 404 405 if ((FPU & SveMode) && HasMatMul) 406 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1"); 407 408 if ((FPU & NeonMode) && HasFP16FML) 409 Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1"); 410 411 if (Opts.hasSignReturnAddress()) { 412 // Bitmask: 413 // 0: Protection using the A key 414 // 1: Protection using the B key 415 // 2: Protection including leaf functions 416 unsigned Value = 0; 417 418 if (Opts.isSignReturnAddressWithAKey()) 419 Value |= (1 << 0); 420 else 421 Value |= (1 << 1); 422 423 if (Opts.isSignReturnAddressScopeAll()) 424 Value |= (1 << 2); 425 426 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); 427 } 428 429 if (Opts.BranchTargetEnforcement) 430 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); 431 432 if (HasLS64) 433 Builder.defineMacro("__ARM_FEATURE_LS64", "1"); 434 435 if (HasRandGen) 436 Builder.defineMacro("__ARM_FEATURE_RNG", "1"); 437 438 switch (ArchKind) { 439 default: 440 break; 441 case llvm::AArch64::ArchKind::ARMV8_1A: 442 getTargetDefinesARMV81A(Opts, Builder); 443 break; 444 case llvm::AArch64::ArchKind::ARMV8_2A: 445 getTargetDefinesARMV82A(Opts, Builder); 446 break; 447 case llvm::AArch64::ArchKind::ARMV8_3A: 448 getTargetDefinesARMV83A(Opts, Builder); 449 break; 450 case llvm::AArch64::ArchKind::ARMV8_4A: 451 getTargetDefinesARMV84A(Opts, Builder); 452 break; 453 case llvm::AArch64::ArchKind::ARMV8_5A: 454 getTargetDefinesARMV85A(Opts, Builder); 455 break; 456 case llvm::AArch64::ArchKind::ARMV8_6A: 457 getTargetDefinesARMV86A(Opts, Builder); 458 break; 459 case llvm::AArch64::ArchKind::ARMV8_7A: 460 getTargetDefinesARMV87A(Opts, Builder); 461 break; 462 case llvm::AArch64::ArchKind::ARMV8_8A: 463 getTargetDefinesARMV88A(Opts, Builder); 464 break; 465 case llvm::AArch64::ArchKind::ARMV9A: 466 getTargetDefinesARMV9A(Opts, Builder); 467 break; 468 case llvm::AArch64::ArchKind::ARMV9_1A: 469 getTargetDefinesARMV91A(Opts, Builder); 470 break; 471 case llvm::AArch64::ArchKind::ARMV9_2A: 472 getTargetDefinesARMV92A(Opts, Builder); 473 break; 474 case llvm::AArch64::ArchKind::ARMV9_3A: 475 getTargetDefinesARMV93A(Opts, Builder); 476 break; 477 } 478 479 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. 480 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 481 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 482 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 483 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 484 485 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) { 486 Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128)); 487 Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS"); 488 } 489 } 490 491 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { 492 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - 493 Builtin::FirstTSBuiltin); 494 } 495 496 Optional<std::pair<unsigned, unsigned>> 497 AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { 498 if (LangOpts.VScaleMin || LangOpts.VScaleMax) 499 return std::pair<unsigned, unsigned>( 500 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax); 501 502 if (hasFeature("sve")) 503 return std::pair<unsigned, unsigned>(1, 16); 504 505 return None; 506 } 507 508 bool AArch64TargetInfo::hasFeature(StringRef Feature) const { 509 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || 510 (Feature == "neon" && (FPU & NeonMode)) || 511 ((Feature == "sve" || Feature == "sve2" || Feature == "sve2-bitperm" || 512 Feature == "sve2-aes" || Feature == "sve2-sha3" || 513 Feature == "sve2-sm4" || Feature == "f64mm" || Feature == "f32mm" || 514 Feature == "i8mm" || Feature == "bf16") && 515 (FPU & SveMode)) || 516 (Feature == "ls64" && HasLS64); 517 } 518 519 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 520 DiagnosticsEngine &Diags) { 521 FPU = FPUMode; 522 HasCRC = false; 523 HasCrypto = false; 524 HasAES = false; 525 HasSHA2 = false; 526 HasSHA3 = false; 527 HasSM4 = false; 528 HasUnaligned = true; 529 HasFullFP16 = false; 530 HasDotProd = false; 531 HasFP16FML = false; 532 HasMTE = false; 533 HasTME = false; 534 HasLS64 = false; 535 HasRandGen = false; 536 HasMatMul = false; 537 HasBFloat16 = false; 538 HasSVE2 = false; 539 HasSVE2AES = false; 540 HasSVE2SHA3 = false; 541 HasSVE2SM4 = false; 542 HasSVE2BitPerm = false; 543 HasMatmulFP64 = false; 544 HasMatmulFP32 = false; 545 HasLSE = false; 546 547 ArchKind = llvm::AArch64::ArchKind::INVALID; 548 549 for (const auto &Feature : Features) { 550 if (Feature == "+neon") 551 FPU |= NeonMode; 552 if (Feature == "+sve") { 553 FPU |= SveMode; 554 HasFullFP16 = true; 555 } 556 if (Feature == "+sve2") { 557 FPU |= SveMode; 558 HasFullFP16 = true; 559 HasSVE2 = true; 560 } 561 if (Feature == "+sve2-aes") { 562 FPU |= SveMode; 563 HasFullFP16 = true; 564 HasSVE2 = true; 565 HasSVE2AES = true; 566 } 567 if (Feature == "+sve2-sha3") { 568 FPU |= SveMode; 569 HasFullFP16 = true; 570 HasSVE2 = true; 571 HasSVE2SHA3 = true; 572 } 573 if (Feature == "+sve2-sm4") { 574 FPU |= SveMode; 575 HasFullFP16 = true; 576 HasSVE2 = true; 577 HasSVE2SM4 = true; 578 } 579 if (Feature == "+sve2-bitperm") { 580 FPU |= SveMode; 581 HasFullFP16 = true; 582 HasSVE2 = true; 583 HasSVE2BitPerm = true; 584 } 585 if (Feature == "+f32mm") { 586 FPU |= SveMode; 587 HasMatmulFP32 = true; 588 } 589 if (Feature == "+f64mm") { 590 FPU |= SveMode; 591 HasMatmulFP64 = true; 592 } 593 if (Feature == "+crc") 594 HasCRC = true; 595 if (Feature == "+crypto") 596 HasCrypto = true; 597 if (Feature == "+aes") 598 HasAES = true; 599 if (Feature == "+sha2") 600 HasSHA2 = true; 601 if (Feature == "+sha3") { 602 HasSHA2 = true; 603 HasSHA3 = true; 604 } 605 if (Feature == "+sm4") 606 HasSM4 = true; 607 if (Feature == "+strict-align") 608 HasUnaligned = false; 609 if (Feature == "+v8a") 610 ArchKind = llvm::AArch64::ArchKind::ARMV8A; 611 if (Feature == "+v8.1a") 612 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; 613 if (Feature == "+v8.2a") 614 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; 615 if (Feature == "+v8.3a") 616 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A; 617 if (Feature == "+v8.4a") 618 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A; 619 if (Feature == "+v8.5a") 620 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A; 621 if (Feature == "+v8.6a") 622 ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; 623 if (Feature == "+v8.7a") 624 ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; 625 if (Feature == "+v8.8a") 626 ArchKind = llvm::AArch64::ArchKind::ARMV8_8A; 627 if (Feature == "+v9a") 628 ArchKind = llvm::AArch64::ArchKind::ARMV9A; 629 if (Feature == "+v9.1a") 630 ArchKind = llvm::AArch64::ArchKind::ARMV9_1A; 631 if (Feature == "+v9.2a") 632 ArchKind = llvm::AArch64::ArchKind::ARMV9_2A; 633 if (Feature == "+v9.3a") 634 ArchKind = llvm::AArch64::ArchKind::ARMV9_3A; 635 if (Feature == "+v8r") 636 ArchKind = llvm::AArch64::ArchKind::ARMV8R; 637 if (Feature == "+fullfp16") 638 HasFullFP16 = true; 639 if (Feature == "+dotprod") 640 HasDotProd = true; 641 if (Feature == "+fp16fml") 642 HasFP16FML = true; 643 if (Feature == "+mte") 644 HasMTE = true; 645 if (Feature == "+tme") 646 HasTME = true; 647 if (Feature == "+pauth") 648 HasPAuth = true; 649 if (Feature == "+i8mm") 650 HasMatMul = true; 651 if (Feature == "+bf16") 652 HasBFloat16 = true; 653 if (Feature == "+lse") 654 HasLSE = true; 655 if (Feature == "+ls64") 656 HasLS64 = true; 657 if (Feature == "+rand") 658 HasRandGen = true; 659 if (Feature == "+flagm") 660 HasFlagM = true; 661 } 662 663 setDataLayout(); 664 665 return true; 666 } 667 668 TargetInfo::CallingConvCheckResult 669 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { 670 switch (CC) { 671 case CC_C: 672 case CC_Swift: 673 case CC_SwiftAsync: 674 case CC_PreserveMost: 675 case CC_PreserveAll: 676 case CC_OpenCLKernel: 677 case CC_AArch64VectorCall: 678 case CC_Win64: 679 return CCCR_OK; 680 default: 681 return CCCR_Warning; 682 } 683 } 684 685 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } 686 687 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { 688 return TargetInfo::AArch64ABIBuiltinVaList; 689 } 690 691 const char *const AArch64TargetInfo::GCCRegNames[] = { 692 // 32-bit Integer registers 693 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", 694 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", 695 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", 696 697 // 64-bit Integer registers 698 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", 699 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", 700 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", 701 702 // 32-bit floating point regsisters 703 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 704 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 705 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 706 707 // 64-bit floating point regsisters 708 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 709 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 710 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 711 712 // Neon vector registers 713 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", 714 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", 715 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", 716 717 // SVE vector registers 718 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", 719 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", 720 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31", 721 722 // SVE predicate registers 723 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", 724 "p11", "p12", "p13", "p14", "p15" 725 }; 726 727 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { 728 return llvm::makeArrayRef(GCCRegNames); 729 } 730 731 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 732 {{"w31"}, "wsp"}, 733 {{"x31"}, "sp"}, 734 // GCC rN registers are aliases of xN registers. 735 {{"r0"}, "x0"}, 736 {{"r1"}, "x1"}, 737 {{"r2"}, "x2"}, 738 {{"r3"}, "x3"}, 739 {{"r4"}, "x4"}, 740 {{"r5"}, "x5"}, 741 {{"r6"}, "x6"}, 742 {{"r7"}, "x7"}, 743 {{"r8"}, "x8"}, 744 {{"r9"}, "x9"}, 745 {{"r10"}, "x10"}, 746 {{"r11"}, "x11"}, 747 {{"r12"}, "x12"}, 748 {{"r13"}, "x13"}, 749 {{"r14"}, "x14"}, 750 {{"r15"}, "x15"}, 751 {{"r16"}, "x16"}, 752 {{"r17"}, "x17"}, 753 {{"r18"}, "x18"}, 754 {{"r19"}, "x19"}, 755 {{"r20"}, "x20"}, 756 {{"r21"}, "x21"}, 757 {{"r22"}, "x22"}, 758 {{"r23"}, "x23"}, 759 {{"r24"}, "x24"}, 760 {{"r25"}, "x25"}, 761 {{"r26"}, "x26"}, 762 {{"r27"}, "x27"}, 763 {{"r28"}, "x28"}, 764 {{"r29", "x29"}, "fp"}, 765 {{"r30", "x30"}, "lr"}, 766 // The S/D/Q and W/X registers overlap, but aren't really aliases; we 767 // don't want to substitute one of these for a different-sized one. 768 }; 769 770 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { 771 return llvm::makeArrayRef(GCCRegAliases); 772 } 773 774 bool AArch64TargetInfo::validateAsmConstraint( 775 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 776 switch (*Name) { 777 default: 778 return false; 779 case 'w': // Floating point and SIMD registers (V0-V31) 780 Info.setAllowsRegister(); 781 return true; 782 case 'I': // Constant that can be used with an ADD instruction 783 case 'J': // Constant that can be used with a SUB instruction 784 case 'K': // Constant that can be used with a 32-bit logical instruction 785 case 'L': // Constant that can be used with a 64-bit logical instruction 786 case 'M': // Constant that can be used as a 32-bit MOV immediate 787 case 'N': // Constant that can be used as a 64-bit MOV immediate 788 case 'Y': // Floating point constant zero 789 case 'Z': // Integer constant zero 790 return true; 791 case 'Q': // A memory reference with base register and no offset 792 Info.setAllowsMemory(); 793 return true; 794 case 'S': // A symbolic address 795 Info.setAllowsRegister(); 796 return true; 797 case 'U': 798 if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) { 799 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7) 800 Info.setAllowsRegister(); 801 Name += 2; 802 return true; 803 } 804 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. 805 // Utf: A memory address suitable for ldp/stp in TF mode. 806 // Usa: An absolute symbolic address. 807 // Ush: The high part (bits 32:12) of a pc-relative symbolic address. 808 809 // Better to return an error saying that it's an unrecognised constraint 810 // even if this is a valid constraint in gcc. 811 return false; 812 case 'z': // Zero register, wzr or xzr 813 Info.setAllowsRegister(); 814 return true; 815 case 'x': // Floating point and SIMD registers (V0-V15) 816 Info.setAllowsRegister(); 817 return true; 818 case 'y': // SVE registers (V0-V7) 819 Info.setAllowsRegister(); 820 return true; 821 } 822 return false; 823 } 824 825 bool AArch64TargetInfo::validateConstraintModifier( 826 StringRef Constraint, char Modifier, unsigned Size, 827 std::string &SuggestedModifier) const { 828 // Strip off constraint modifiers. 829 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 830 Constraint = Constraint.substr(1); 831 832 switch (Constraint[0]) { 833 default: 834 return true; 835 case 'z': 836 case 'r': { 837 switch (Modifier) { 838 case 'x': 839 case 'w': 840 // For now assume that the person knows what they're 841 // doing with the modifier. 842 return true; 843 default: 844 // By default an 'r' constraint will be in the 'x' 845 // registers. 846 if (Size == 64) 847 return true; 848 849 if (Size == 512) 850 return HasLS64; 851 852 SuggestedModifier = "w"; 853 return false; 854 } 855 } 856 } 857 } 858 859 const char *AArch64TargetInfo::getClobbers() const { return ""; } 860 861 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 862 if (RegNo == 0) 863 return 0; 864 if (RegNo == 1) 865 return 1; 866 return -1; 867 } 868 869 bool AArch64TargetInfo::hasInt128Type() const { return true; } 870 871 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, 872 const TargetOptions &Opts) 873 : AArch64TargetInfo(Triple, Opts) {} 874 875 void AArch64leTargetInfo::setDataLayout() { 876 if (getTriple().isOSBinFormatMachO()) { 877 if(getTriple().isArch32Bit()) 878 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_"); 879 else 880 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_"); 881 } else 882 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 883 } 884 885 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, 886 MacroBuilder &Builder) const { 887 Builder.defineMacro("__AARCH64EL__"); 888 AArch64TargetInfo::getTargetDefines(Opts, Builder); 889 } 890 891 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, 892 const TargetOptions &Opts) 893 : AArch64TargetInfo(Triple, Opts) {} 894 895 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, 896 MacroBuilder &Builder) const { 897 Builder.defineMacro("__AARCH64EB__"); 898 Builder.defineMacro("__AARCH_BIG_ENDIAN"); 899 Builder.defineMacro("__ARM_BIG_ENDIAN"); 900 AArch64TargetInfo::getTargetDefines(Opts, Builder); 901 } 902 903 void AArch64beTargetInfo::setDataLayout() { 904 assert(!getTriple().isOSBinFormatMachO()); 905 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 906 } 907 908 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, 909 const TargetOptions &Opts) 910 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { 911 912 // This is an LLP64 platform. 913 // int:4, long:4, long long:8, long double:8. 914 IntWidth = IntAlign = 32; 915 LongWidth = LongAlign = 32; 916 DoubleAlign = LongLongAlign = 64; 917 LongDoubleWidth = LongDoubleAlign = 64; 918 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 919 IntMaxType = SignedLongLong; 920 Int64Type = SignedLongLong; 921 SizeType = UnsignedLongLong; 922 PtrDiffType = SignedLongLong; 923 IntPtrType = SignedLongLong; 924 } 925 926 void WindowsARM64TargetInfo::setDataLayout() { 927 resetDataLayout(Triple.isOSBinFormatMachO() 928 ? "e-m:o-i64:64-i128:128-n32:64-S128" 929 : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128", 930 Triple.isOSBinFormatMachO() ? "_" : ""); 931 } 932 933 TargetInfo::BuiltinVaListKind 934 WindowsARM64TargetInfo::getBuiltinVaListKind() const { 935 return TargetInfo::CharPtrBuiltinVaList; 936 } 937 938 TargetInfo::CallingConvCheckResult 939 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { 940 switch (CC) { 941 case CC_X86StdCall: 942 case CC_X86ThisCall: 943 case CC_X86FastCall: 944 case CC_X86VectorCall: 945 return CCCR_Ignore; 946 case CC_C: 947 case CC_OpenCLKernel: 948 case CC_PreserveMost: 949 case CC_PreserveAll: 950 case CC_Swift: 951 case CC_SwiftAsync: 952 case CC_Win64: 953 return CCCR_OK; 954 default: 955 return CCCR_Warning; 956 } 957 } 958 959 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, 960 const TargetOptions &Opts) 961 : WindowsARM64TargetInfo(Triple, Opts) { 962 TheCXXABI.set(TargetCXXABI::Microsoft); 963 } 964 965 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, 966 MacroBuilder &Builder) const { 967 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder); 968 Builder.defineMacro("_M_ARM64", "1"); 969 } 970 971 TargetInfo::CallingConvKind 972 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { 973 return CCK_MicrosoftWin64; 974 } 975 976 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const { 977 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize); 978 979 // MSVC does size based alignment for arm64 based on alignment section in 980 // below document, replicate that to keep alignment consistent with object 981 // files compiled by MSVC. 982 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions 983 if (TypeSize >= 512) { // TypeSize >= 64 bytes 984 Align = std::max(Align, 128u); // align type at least 16 bytes 985 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes 986 Align = std::max(Align, 64u); // align type at least 8 butes 987 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes 988 Align = std::max(Align, 32u); // align type at least 4 bytes 989 } 990 return Align; 991 } 992 993 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, 994 const TargetOptions &Opts) 995 : WindowsARM64TargetInfo(Triple, Opts) { 996 TheCXXABI.set(TargetCXXABI::GenericAArch64); 997 } 998 999 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, 1000 const TargetOptions &Opts) 1001 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { 1002 Int64Type = SignedLongLong; 1003 if (getTriple().isArch32Bit()) 1004 IntMaxType = SignedLongLong; 1005 1006 WCharType = SignedInt; 1007 UseSignedCharForObjCBool = false; 1008 1009 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; 1010 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 1011 1012 UseZeroLengthBitfieldAlignment = false; 1013 1014 if (getTriple().isArch32Bit()) { 1015 UseBitFieldTypeAlignment = false; 1016 ZeroLengthBitfieldBoundary = 32; 1017 UseZeroLengthBitfieldAlignment = true; 1018 TheCXXABI.set(TargetCXXABI::WatchOS); 1019 } else 1020 TheCXXABI.set(TargetCXXABI::AppleARM64); 1021 } 1022 1023 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, 1024 const llvm::Triple &Triple, 1025 MacroBuilder &Builder) const { 1026 Builder.defineMacro("__AARCH64_SIMD__"); 1027 if (Triple.isArch32Bit()) 1028 Builder.defineMacro("__ARM64_ARCH_8_32__"); 1029 else 1030 Builder.defineMacro("__ARM64_ARCH_8__"); 1031 Builder.defineMacro("__ARM_NEON__"); 1032 Builder.defineMacro("__LITTLE_ENDIAN__"); 1033 Builder.defineMacro("__REGISTER_PREFIX__", ""); 1034 Builder.defineMacro("__arm64", "1"); 1035 Builder.defineMacro("__arm64__", "1"); 1036 1037 if (Triple.isArm64e()) 1038 Builder.defineMacro("__arm64e__", "1"); 1039 1040 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1041 } 1042 1043 TargetInfo::BuiltinVaListKind 1044 DarwinAArch64TargetInfo::getBuiltinVaListKind() const { 1045 return TargetInfo::CharPtrBuiltinVaList; 1046 } 1047 1048 // 64-bit RenderScript is aarch64 1049 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, 1050 const TargetOptions &Opts) 1051 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), 1052 Triple.getOSName(), 1053 Triple.getEnvironmentName()), 1054 Opts) { 1055 IsRenderScriptTarget = true; 1056 } 1057 1058 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, 1059 MacroBuilder &Builder) const { 1060 Builder.defineMacro("__RENDERSCRIPT__"); 1061 AArch64leTargetInfo::getTargetDefines(Opts, Builder); 1062 } 1063