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