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