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/TargetBuiltins.h" 15 #include "clang/Basic/TargetInfo.h" 16 #include "llvm/ADT/ArrayRef.h" 17 #include "llvm/ADT/StringExtras.h" 18 19 using namespace clang; 20 using namespace clang::targets; 21 22 const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { 23 #define BUILTIN(ID, TYPE, ATTRS) \ 24 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 25 #include "clang/Basic/BuiltinsNEON.def" 26 27 #define BUILTIN(ID, TYPE, ATTRS) \ 28 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 29 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 30 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 31 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 32 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 33 #include "clang/Basic/BuiltinsAArch64.def" 34 }; 35 36 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, 37 const TargetOptions &Opts) 38 : TargetInfo(Triple), ABI("aapcs") { 39 if (getTriple().isOSOpenBSD()) { 40 Int64Type = SignedLongLong; 41 IntMaxType = SignedLongLong; 42 } else { 43 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD()) 44 WCharType = UnsignedInt; 45 46 Int64Type = SignedLong; 47 IntMaxType = SignedLong; 48 } 49 50 // All AArch64 implementations support ARMv8 FP, which makes half a legal type. 51 HasLegalHalfType = true; 52 HasFloat16 = true; 53 54 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 55 MaxVectorAlign = 128; 56 MaxAtomicInlineWidth = 128; 57 MaxAtomicPromoteWidth = 128; 58 59 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; 60 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 61 62 // Make __builtin_ms_va_list available. 63 HasBuiltinMSVaList = true; 64 65 // {} in inline assembly are neon specifiers, not assembly variant 66 // specifiers. 67 NoAsmVariants = true; 68 69 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type 70 // contributes to the alignment of the containing aggregate in the same way 71 // a plain (non bit-field) member of that type would, without exception for 72 // zero-sized or anonymous bit-fields." 73 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment"); 74 UseZeroLengthBitfieldAlignment = true; 75 76 // AArch64 targets default to using the ARM C++ ABI. 77 TheCXXABI.set(TargetCXXABI::GenericAArch64); 78 79 if (Triple.getOS() == llvm::Triple::Linux) 80 this->MCountName = "\01_mcount"; 81 else if (Triple.getOS() == llvm::Triple::UnknownOS) 82 this->MCountName = 83 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount"; 84 } 85 86 StringRef AArch64TargetInfo::getABI() const { return ABI; } 87 88 bool AArch64TargetInfo::setABI(const std::string &Name) { 89 if (Name != "aapcs" && Name != "darwinpcs") 90 return false; 91 92 ABI = Name; 93 return true; 94 } 95 96 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { 97 return Name == "generic" || 98 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID; 99 } 100 101 bool AArch64TargetInfo::setCPU(const std::string &Name) { 102 return isValidCPUName(Name); 103 } 104 105 void AArch64TargetInfo::fillValidCPUList( 106 SmallVectorImpl<StringRef> &Values) const { 107 llvm::AArch64::fillValidCPUArchList(Values); 108 } 109 110 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 111 MacroBuilder &Builder) const { 112 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 113 } 114 115 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 116 MacroBuilder &Builder) const { 117 // Also include the ARMv8.1 defines 118 getTargetDefinesARMV81A(Opts, Builder); 119 } 120 121 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, 122 MacroBuilder &Builder) const { 123 // Target identification. 124 Builder.defineMacro("__aarch64__"); 125 // For bare-metal. 126 if (getTriple().getOS() == llvm::Triple::UnknownOS && 127 getTriple().isOSBinFormatELF()) 128 Builder.defineMacro("__ELF__"); 129 130 // Target properties. 131 if (!getTriple().isOSWindows()) { 132 Builder.defineMacro("_LP64"); 133 Builder.defineMacro("__LP64__"); 134 } 135 136 // ACLE predefines. Many can only have one possible value on v8 AArch64. 137 Builder.defineMacro("__ARM_ACLE", "200"); 138 Builder.defineMacro("__ARM_ARCH", "8"); 139 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'"); 140 141 Builder.defineMacro("__ARM_64BIT_STATE", "1"); 142 Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); 143 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1"); 144 145 Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 146 Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 147 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF"); 148 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE 149 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility 150 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 151 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 152 153 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); 154 155 // 0xe implies support for half, single and double precision operations. 156 Builder.defineMacro("__ARM_FP", "0xE"); 157 158 // PCS specifies this for SysV variants, which is all we support. Other ABIs 159 // may choose __ARM_FP16_FORMAT_ALTERNATIVE. 160 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 161 Builder.defineMacro("__ARM_FP16_ARGS", "1"); 162 163 if (Opts.UnsafeFPMath) 164 Builder.defineMacro("__ARM_FP_FAST", "1"); 165 166 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 167 Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 168 169 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 170 171 if (FPU & NeonMode) { 172 Builder.defineMacro("__ARM_NEON", "1"); 173 // 64-bit NEON supports half, single and double precision operations. 174 Builder.defineMacro("__ARM_NEON_FP", "0xE"); 175 } 176 177 if (FPU & SveMode) 178 Builder.defineMacro("__ARM_FEATURE_SVE", "1"); 179 180 if (CRC) 181 Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 182 183 if (Crypto) 184 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 185 186 if (Unaligned) 187 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 188 189 if ((FPU & NeonMode) && HasFullFP16) 190 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 191 if (HasFullFP16) 192 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 193 194 if (HasDotProd) 195 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 196 197 if ((FPU & NeonMode) && HasFP16FML) 198 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1"); 199 200 switch (ArchKind) { 201 default: 202 break; 203 case llvm::AArch64::ArchKind::ARMV8_1A: 204 getTargetDefinesARMV81A(Opts, Builder); 205 break; 206 case llvm::AArch64::ArchKind::ARMV8_2A: 207 getTargetDefinesARMV82A(Opts, Builder); 208 break; 209 } 210 211 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. 212 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 213 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 214 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 215 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 216 } 217 218 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { 219 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - 220 Builtin::FirstTSBuiltin); 221 } 222 223 bool AArch64TargetInfo::hasFeature(StringRef Feature) const { 224 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || 225 (Feature == "neon" && (FPU & NeonMode)) || 226 (Feature == "sve" && (FPU & SveMode)); 227 } 228 229 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 230 DiagnosticsEngine &Diags) { 231 FPU = FPUMode; 232 CRC = 0; 233 Crypto = 0; 234 Unaligned = 1; 235 HasFullFP16 = 0; 236 HasDotProd = 0; 237 HasFP16FML = 0; 238 ArchKind = llvm::AArch64::ArchKind::ARMV8A; 239 240 for (const auto &Feature : Features) { 241 if (Feature == "+neon") 242 FPU |= NeonMode; 243 if (Feature == "+sve") 244 FPU |= SveMode; 245 if (Feature == "+crc") 246 CRC = 1; 247 if (Feature == "+crypto") 248 Crypto = 1; 249 if (Feature == "+strict-align") 250 Unaligned = 0; 251 if (Feature == "+v8.1a") 252 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; 253 if (Feature == "+v8.2a") 254 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; 255 if (Feature == "+fullfp16") 256 HasFullFP16 = 1; 257 if (Feature == "+dotprod") 258 HasDotProd = 1; 259 if (Feature == "+fp16fml") 260 HasFP16FML = 1; 261 } 262 263 setDataLayout(); 264 265 return true; 266 } 267 268 TargetInfo::CallingConvCheckResult 269 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { 270 switch (CC) { 271 case CC_C: 272 case CC_Swift: 273 case CC_PreserveMost: 274 case CC_PreserveAll: 275 case CC_OpenCLKernel: 276 case CC_AArch64VectorCall: 277 case CC_Win64: 278 return CCCR_OK; 279 default: 280 return CCCR_Warning; 281 } 282 } 283 284 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } 285 286 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { 287 return TargetInfo::AArch64ABIBuiltinVaList; 288 } 289 290 const char *const AArch64TargetInfo::GCCRegNames[] = { 291 // 32-bit Integer registers 292 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", 293 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", 294 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", 295 296 // 64-bit Integer registers 297 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", 298 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", 299 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", 300 301 // 32-bit floating point regsisters 302 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 303 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 304 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 305 306 // 64-bit floating point regsisters 307 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 308 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 309 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 310 311 // Vector registers 312 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", 313 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", 314 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" 315 }; 316 317 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { 318 return llvm::makeArrayRef(GCCRegNames); 319 } 320 321 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 322 {{"w31"}, "wsp"}, 323 {{"x31"}, "sp"}, 324 // GCC rN registers are aliases of xN registers. 325 {{"r0"}, "x0"}, 326 {{"r1"}, "x1"}, 327 {{"r2"}, "x2"}, 328 {{"r3"}, "x3"}, 329 {{"r4"}, "x4"}, 330 {{"r5"}, "x5"}, 331 {{"r6"}, "x6"}, 332 {{"r7"}, "x7"}, 333 {{"r8"}, "x8"}, 334 {{"r9"}, "x9"}, 335 {{"r10"}, "x10"}, 336 {{"r11"}, "x11"}, 337 {{"r12"}, "x12"}, 338 {{"r13"}, "x13"}, 339 {{"r14"}, "x14"}, 340 {{"r15"}, "x15"}, 341 {{"r16"}, "x16"}, 342 {{"r17"}, "x17"}, 343 {{"r18"}, "x18"}, 344 {{"r19"}, "x19"}, 345 {{"r20"}, "x20"}, 346 {{"r21"}, "x21"}, 347 {{"r22"}, "x22"}, 348 {{"r23"}, "x23"}, 349 {{"r24"}, "x24"}, 350 {{"r25"}, "x25"}, 351 {{"r26"}, "x26"}, 352 {{"r27"}, "x27"}, 353 {{"r28"}, "x28"}, 354 {{"r29", "x29"}, "fp"}, 355 {{"r30", "x30"}, "lr"}, 356 // The S/D/Q and W/X registers overlap, but aren't really aliases; we 357 // don't want to substitute one of these for a different-sized one. 358 }; 359 360 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { 361 return llvm::makeArrayRef(GCCRegAliases); 362 } 363 364 bool AArch64TargetInfo::validateAsmConstraint( 365 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 366 switch (*Name) { 367 default: 368 return false; 369 case 'w': // Floating point and SIMD registers (V0-V31) 370 Info.setAllowsRegister(); 371 return true; 372 case 'I': // Constant that can be used with an ADD instruction 373 case 'J': // Constant that can be used with a SUB instruction 374 case 'K': // Constant that can be used with a 32-bit logical instruction 375 case 'L': // Constant that can be used with a 64-bit logical instruction 376 case 'M': // Constant that can be used as a 32-bit MOV immediate 377 case 'N': // Constant that can be used as a 64-bit MOV immediate 378 case 'Y': // Floating point constant zero 379 case 'Z': // Integer constant zero 380 return true; 381 case 'Q': // A memory reference with base register and no offset 382 Info.setAllowsMemory(); 383 return true; 384 case 'S': // A symbolic address 385 Info.setAllowsRegister(); 386 return true; 387 case 'U': 388 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. 389 // Utf: A memory address suitable for ldp/stp in TF mode. 390 // Usa: An absolute symbolic address. 391 // Ush: The high part (bits 32:12) of a pc-relative symbolic address. 392 llvm_unreachable("FIXME: Unimplemented support for U* constraints."); 393 case 'z': // Zero register, wzr or xzr 394 Info.setAllowsRegister(); 395 return true; 396 case 'x': // Floating point and SIMD registers (V0-V15) 397 Info.setAllowsRegister(); 398 return true; 399 } 400 return false; 401 } 402 403 bool AArch64TargetInfo::validateConstraintModifier( 404 StringRef Constraint, char Modifier, unsigned Size, 405 std::string &SuggestedModifier) const { 406 // Strip off constraint modifiers. 407 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 408 Constraint = Constraint.substr(1); 409 410 switch (Constraint[0]) { 411 default: 412 return true; 413 case 'z': 414 case 'r': { 415 switch (Modifier) { 416 case 'x': 417 case 'w': 418 // For now assume that the person knows what they're 419 // doing with the modifier. 420 return true; 421 default: 422 // By default an 'r' constraint will be in the 'x' 423 // registers. 424 if (Size == 64) 425 return true; 426 427 SuggestedModifier = "w"; 428 return false; 429 } 430 } 431 } 432 } 433 434 const char *AArch64TargetInfo::getClobbers() const { return ""; } 435 436 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 437 if (RegNo == 0) 438 return 0; 439 if (RegNo == 1) 440 return 1; 441 return -1; 442 } 443 444 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, 445 const TargetOptions &Opts) 446 : AArch64TargetInfo(Triple, Opts) {} 447 448 void AArch64leTargetInfo::setDataLayout() { 449 if (getTriple().isOSBinFormatMachO()) 450 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"); 451 else 452 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 453 } 454 455 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, 456 MacroBuilder &Builder) const { 457 Builder.defineMacro("__AARCH64EL__"); 458 AArch64TargetInfo::getTargetDefines(Opts, Builder); 459 } 460 461 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, 462 const TargetOptions &Opts) 463 : AArch64TargetInfo(Triple, Opts) {} 464 465 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, 466 MacroBuilder &Builder) const { 467 Builder.defineMacro("__AARCH64EB__"); 468 Builder.defineMacro("__AARCH_BIG_ENDIAN"); 469 Builder.defineMacro("__ARM_BIG_ENDIAN"); 470 AArch64TargetInfo::getTargetDefines(Opts, Builder); 471 } 472 473 void AArch64beTargetInfo::setDataLayout() { 474 assert(!getTriple().isOSBinFormatMachO()); 475 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 476 } 477 478 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, 479 const TargetOptions &Opts) 480 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { 481 482 // This is an LLP64 platform. 483 // int:4, long:4, long long:8, long double:8. 484 IntWidth = IntAlign = 32; 485 LongWidth = LongAlign = 32; 486 DoubleAlign = LongLongAlign = 64; 487 LongDoubleWidth = LongDoubleAlign = 64; 488 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 489 IntMaxType = SignedLongLong; 490 Int64Type = SignedLongLong; 491 SizeType = UnsignedLongLong; 492 PtrDiffType = SignedLongLong; 493 IntPtrType = SignedLongLong; 494 } 495 496 void WindowsARM64TargetInfo::setDataLayout() { 497 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"); 498 } 499 500 TargetInfo::BuiltinVaListKind 501 WindowsARM64TargetInfo::getBuiltinVaListKind() const { 502 return TargetInfo::CharPtrBuiltinVaList; 503 } 504 505 TargetInfo::CallingConvCheckResult 506 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { 507 switch (CC) { 508 case CC_X86StdCall: 509 case CC_X86ThisCall: 510 case CC_X86FastCall: 511 case CC_X86VectorCall: 512 return CCCR_Ignore; 513 case CC_C: 514 case CC_OpenCLKernel: 515 case CC_PreserveMost: 516 case CC_PreserveAll: 517 case CC_Swift: 518 case CC_Win64: 519 return CCCR_OK; 520 default: 521 return CCCR_Warning; 522 } 523 } 524 525 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, 526 const TargetOptions &Opts) 527 : WindowsARM64TargetInfo(Triple, Opts) { 528 TheCXXABI.set(TargetCXXABI::Microsoft); 529 } 530 531 void MicrosoftARM64TargetInfo::getVisualStudioDefines( 532 const LangOptions &Opts, MacroBuilder &Builder) const { 533 WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts, Builder); 534 Builder.defineMacro("_M_ARM64", "1"); 535 } 536 537 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, 538 MacroBuilder &Builder) const { 539 WindowsTargetInfo::getTargetDefines(Opts, Builder); 540 getVisualStudioDefines(Opts, Builder); 541 } 542 543 TargetInfo::CallingConvKind 544 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { 545 return CCK_MicrosoftWin64; 546 } 547 548 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, 549 const TargetOptions &Opts) 550 : WindowsARM64TargetInfo(Triple, Opts) { 551 TheCXXABI.set(TargetCXXABI::GenericAArch64); 552 } 553 554 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, 555 const TargetOptions &Opts) 556 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { 557 Int64Type = SignedLongLong; 558 UseSignedCharForObjCBool = false; 559 560 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; 561 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 562 563 TheCXXABI.set(TargetCXXABI::iOS64); 564 } 565 566 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, 567 const llvm::Triple &Triple, 568 MacroBuilder &Builder) const { 569 Builder.defineMacro("__AARCH64_SIMD__"); 570 Builder.defineMacro("__ARM64_ARCH_8__"); 571 Builder.defineMacro("__ARM_NEON__"); 572 Builder.defineMacro("__LITTLE_ENDIAN__"); 573 Builder.defineMacro("__REGISTER_PREFIX__", ""); 574 Builder.defineMacro("__arm64", "1"); 575 Builder.defineMacro("__arm64__", "1"); 576 577 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 578 } 579 580 TargetInfo::BuiltinVaListKind 581 DarwinAArch64TargetInfo::getBuiltinVaListKind() const { 582 return TargetInfo::CharPtrBuiltinVaList; 583 } 584 585 // 64-bit RenderScript is aarch64 586 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, 587 const TargetOptions &Opts) 588 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), 589 Triple.getOSName(), 590 Triple.getEnvironmentName()), 591 Opts) { 592 IsRenderScriptTarget = true; 593 } 594 595 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, 596 MacroBuilder &Builder) const { 597 Builder.defineMacro("__RENDERSCRIPT__"); 598 AArch64leTargetInfo::getTargetDefines(Opts, Builder); 599 } 600