1 //===--- AArch64.cpp - Implement AArch64 target feature support -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements AArch64 TargetInfo objects. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AArch64.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 20 using namespace clang; 21 using namespace clang::targets; 22 23 const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { 24 #define BUILTIN(ID, TYPE, ATTRS) \ 25 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 26 #include "clang/Basic/BuiltinsNEON.def" 27 28 #define BUILTIN(ID, TYPE, ATTRS) \ 29 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 30 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 31 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, 32 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 33 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 34 #include "clang/Basic/BuiltinsAArch64.def" 35 }; 36 37 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, 38 const TargetOptions &Opts) 39 : TargetInfo(Triple), ABI("aapcs") { 40 if (getTriple().getOS() == llvm::Triple::OpenBSD) { 41 Int64Type = SignedLongLong; 42 IntMaxType = SignedLongLong; 43 } else { 44 if (!getTriple().isOSDarwin() && getTriple().getOS() != llvm::Triple::NetBSD) 45 WCharType = UnsignedInt; 46 47 Int64Type = SignedLong; 48 IntMaxType = SignedLong; 49 } 50 51 // All AArch64 implementations support ARMv8 FP, which makes half a legal type. 52 HasLegalHalfType = 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_Win64: 277 return CCCR_OK; 278 default: 279 return CCCR_Warning; 280 } 281 } 282 283 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } 284 285 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { 286 return TargetInfo::AArch64ABIBuiltinVaList; 287 } 288 289 const char *const AArch64TargetInfo::GCCRegNames[] = { 290 // 32-bit Integer registers 291 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", 292 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", 293 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", 294 295 // 64-bit Integer registers 296 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", 297 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", 298 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", 299 300 // 32-bit floating point regsisters 301 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 302 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 303 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 304 305 // 64-bit floating point regsisters 306 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 307 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 308 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 309 310 // Vector registers 311 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", 312 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", 313 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" 314 }; 315 316 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { 317 return llvm::makeArrayRef(GCCRegNames); 318 } 319 320 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 321 {{"w31"}, "wsp"}, 322 {{"x31"}, "sp"}, 323 // GCC rN registers are aliases of xN registers. 324 {{"r0"}, "x0"}, 325 {{"r1"}, "x1"}, 326 {{"r2"}, "x2"}, 327 {{"r3"}, "x3"}, 328 {{"r4"}, "x4"}, 329 {{"r5"}, "x5"}, 330 {{"r6"}, "x6"}, 331 {{"r7"}, "x7"}, 332 {{"r8"}, "x8"}, 333 {{"r9"}, "x9"}, 334 {{"r10"}, "x10"}, 335 {{"r11"}, "x11"}, 336 {{"r12"}, "x12"}, 337 {{"r13"}, "x13"}, 338 {{"r14"}, "x14"}, 339 {{"r15"}, "x15"}, 340 {{"r16"}, "x16"}, 341 {{"r17"}, "x17"}, 342 {{"r18"}, "x18"}, 343 {{"r19"}, "x19"}, 344 {{"r20"}, "x20"}, 345 {{"r21"}, "x21"}, 346 {{"r22"}, "x22"}, 347 {{"r23"}, "x23"}, 348 {{"r24"}, "x24"}, 349 {{"r25"}, "x25"}, 350 {{"r26"}, "x26"}, 351 {{"r27"}, "x27"}, 352 {{"r28"}, "x28"}, 353 {{"r29", "x29"}, "fp"}, 354 {{"r30", "x30"}, "lr"}, 355 // The S/D/Q and W/X registers overlap, but aren't really aliases; we 356 // don't want to substitute one of these for a different-sized one. 357 }; 358 359 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { 360 return llvm::makeArrayRef(GCCRegAliases); 361 } 362 363 bool AArch64TargetInfo::validateAsmConstraint( 364 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 365 switch (*Name) { 366 default: 367 return false; 368 case 'w': // Floating point and SIMD registers (V0-V31) 369 Info.setAllowsRegister(); 370 return true; 371 case 'I': // Constant that can be used with an ADD instruction 372 case 'J': // Constant that can be used with a SUB instruction 373 case 'K': // Constant that can be used with a 32-bit logical instruction 374 case 'L': // Constant that can be used with a 64-bit logical instruction 375 case 'M': // Constant that can be used as a 32-bit MOV immediate 376 case 'N': // Constant that can be used as a 64-bit MOV immediate 377 case 'Y': // Floating point constant zero 378 case 'Z': // Integer constant zero 379 return true; 380 case 'Q': // A memory reference with base register and no offset 381 Info.setAllowsMemory(); 382 return true; 383 case 'S': // A symbolic address 384 Info.setAllowsRegister(); 385 return true; 386 case 'U': 387 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. 388 // Utf: A memory address suitable for ldp/stp in TF mode. 389 // Usa: An absolute symbolic address. 390 // Ush: The high part (bits 32:12) of a pc-relative symbolic address. 391 llvm_unreachable("FIXME: Unimplemented support for U* constraints."); 392 case 'z': // Zero register, wzr or xzr 393 Info.setAllowsRegister(); 394 return true; 395 case 'x': // Floating point and SIMD registers (V0-V15) 396 Info.setAllowsRegister(); 397 return true; 398 } 399 return false; 400 } 401 402 bool AArch64TargetInfo::validateConstraintModifier( 403 StringRef Constraint, char Modifier, unsigned Size, 404 std::string &SuggestedModifier) const { 405 // Strip off constraint modifiers. 406 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 407 Constraint = Constraint.substr(1); 408 409 switch (Constraint[0]) { 410 default: 411 return true; 412 case 'z': 413 case 'r': { 414 switch (Modifier) { 415 case 'x': 416 case 'w': 417 // For now assume that the person knows what they're 418 // doing with the modifier. 419 return true; 420 default: 421 // By default an 'r' constraint will be in the 'x' 422 // registers. 423 if (Size == 64) 424 return true; 425 426 SuggestedModifier = "w"; 427 return false; 428 } 429 } 430 } 431 } 432 433 const char *AArch64TargetInfo::getClobbers() const { return ""; } 434 435 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 436 if (RegNo == 0) 437 return 0; 438 if (RegNo == 1) 439 return 1; 440 return -1; 441 } 442 443 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, 444 const TargetOptions &Opts) 445 : AArch64TargetInfo(Triple, Opts) {} 446 447 void AArch64leTargetInfo::setDataLayout() { 448 if (getTriple().isOSBinFormatMachO()) 449 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"); 450 else 451 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 452 } 453 454 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, 455 MacroBuilder &Builder) const { 456 Builder.defineMacro("__AARCH64EL__"); 457 AArch64TargetInfo::getTargetDefines(Opts, Builder); 458 } 459 460 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, 461 const TargetOptions &Opts) 462 : AArch64TargetInfo(Triple, Opts) {} 463 464 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, 465 MacroBuilder &Builder) const { 466 Builder.defineMacro("__AARCH64EB__"); 467 Builder.defineMacro("__AARCH_BIG_ENDIAN"); 468 Builder.defineMacro("__ARM_BIG_ENDIAN"); 469 AArch64TargetInfo::getTargetDefines(Opts, Builder); 470 } 471 472 void AArch64beTargetInfo::setDataLayout() { 473 assert(!getTriple().isOSBinFormatMachO()); 474 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 475 } 476 477 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, 478 const TargetOptions &Opts) 479 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { 480 481 // This is an LLP64 platform. 482 // int:4, long:4, long long:8, long double:8. 483 IntWidth = IntAlign = 32; 484 LongWidth = LongAlign = 32; 485 DoubleAlign = LongLongAlign = 64; 486 LongDoubleWidth = LongDoubleAlign = 64; 487 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 488 IntMaxType = SignedLongLong; 489 Int64Type = SignedLongLong; 490 SizeType = UnsignedLongLong; 491 PtrDiffType = SignedLongLong; 492 IntPtrType = SignedLongLong; 493 } 494 495 void WindowsARM64TargetInfo::setDataLayout() { 496 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"); 497 } 498 499 TargetInfo::BuiltinVaListKind 500 WindowsARM64TargetInfo::getBuiltinVaListKind() const { 501 return TargetInfo::CharPtrBuiltinVaList; 502 } 503 504 TargetInfo::CallingConvCheckResult 505 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { 506 switch (CC) { 507 case CC_X86StdCall: 508 case CC_X86ThisCall: 509 case CC_X86FastCall: 510 case CC_X86VectorCall: 511 return CCCR_Ignore; 512 case CC_C: 513 case CC_OpenCLKernel: 514 case CC_PreserveMost: 515 case CC_PreserveAll: 516 case CC_Win64: 517 return CCCR_OK; 518 default: 519 return CCCR_Warning; 520 } 521 } 522 523 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, 524 const TargetOptions &Opts) 525 : WindowsARM64TargetInfo(Triple, Opts) { 526 TheCXXABI.set(TargetCXXABI::Microsoft); 527 } 528 529 void MicrosoftARM64TargetInfo::getVisualStudioDefines( 530 const LangOptions &Opts, MacroBuilder &Builder) const { 531 WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts, Builder); 532 Builder.defineMacro("_M_ARM64", "1"); 533 } 534 535 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, 536 MacroBuilder &Builder) const { 537 WindowsTargetInfo::getTargetDefines(Opts, Builder); 538 getVisualStudioDefines(Opts, Builder); 539 } 540 541 TargetInfo::CallingConvKind 542 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { 543 return CCK_MicrosoftWin64; 544 } 545 546 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, 547 const TargetOptions &Opts) 548 : WindowsARM64TargetInfo(Triple, Opts) { 549 TheCXXABI.set(TargetCXXABI::GenericAArch64); 550 } 551 552 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, 553 const TargetOptions &Opts) 554 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { 555 Int64Type = SignedLongLong; 556 UseSignedCharForObjCBool = false; 557 558 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; 559 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 560 561 TheCXXABI.set(TargetCXXABI::iOS64); 562 } 563 564 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, 565 const llvm::Triple &Triple, 566 MacroBuilder &Builder) const { 567 Builder.defineMacro("__AARCH64_SIMD__"); 568 Builder.defineMacro("__ARM64_ARCH_8__"); 569 Builder.defineMacro("__ARM_NEON__"); 570 Builder.defineMacro("__LITTLE_ENDIAN__"); 571 Builder.defineMacro("__REGISTER_PREFIX__", ""); 572 Builder.defineMacro("__arm64", "1"); 573 Builder.defineMacro("__arm64__", "1"); 574 575 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 576 } 577 578 TargetInfo::BuiltinVaListKind 579 DarwinAArch64TargetInfo::getBuiltinVaListKind() const { 580 return TargetInfo::CharPtrBuiltinVaList; 581 } 582 583 // 64-bit RenderScript is aarch64 584 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, 585 const TargetOptions &Opts) 586 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), 587 Triple.getOSName(), 588 Triple.getEnvironmentName()), 589 Opts) { 590 IsRenderScriptTarget = true; 591 } 592 593 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, 594 MacroBuilder &Builder) const { 595 Builder.defineMacro("__RENDERSCRIPT__"); 596 AArch64leTargetInfo::getTargetDefines(Opts, Builder); 597 } 598