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