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