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