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