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 switch (ArchKind) { 198 default: 199 break; 200 case llvm::AArch64::ArchKind::ARMV8_1A: 201 getTargetDefinesARMV81A(Opts, Builder); 202 break; 203 case llvm::AArch64::ArchKind::ARMV8_2A: 204 getTargetDefinesARMV82A(Opts, Builder); 205 break; 206 } 207 208 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. 209 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 210 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 211 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 212 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 213 } 214 215 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { 216 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - 217 Builtin::FirstTSBuiltin); 218 } 219 220 bool AArch64TargetInfo::hasFeature(StringRef Feature) const { 221 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" || 222 (Feature == "neon" && (FPU & NeonMode)) || 223 (Feature == "sve" && (FPU & SveMode)); 224 } 225 226 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 227 DiagnosticsEngine &Diags) { 228 FPU = FPUMode; 229 CRC = 0; 230 Crypto = 0; 231 Unaligned = 1; 232 HasFullFP16 = 0; 233 HasDotProd = 0; 234 ArchKind = llvm::AArch64::ArchKind::ARMV8A; 235 236 for (const auto &Feature : Features) { 237 if (Feature == "+neon") 238 FPU |= NeonMode; 239 if (Feature == "+sve") 240 FPU |= SveMode; 241 if (Feature == "+crc") 242 CRC = 1; 243 if (Feature == "+crypto") 244 Crypto = 1; 245 if (Feature == "+strict-align") 246 Unaligned = 0; 247 if (Feature == "+v8.1a") 248 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; 249 if (Feature == "+v8.2a") 250 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; 251 if (Feature == "+fullfp16") 252 HasFullFP16 = 1; 253 if (Feature == "+dotprod") 254 HasDotProd = 1; 255 } 256 257 setDataLayout(); 258 259 return true; 260 } 261 262 TargetInfo::CallingConvCheckResult 263 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { 264 switch (CC) { 265 case CC_C: 266 case CC_Swift: 267 case CC_PreserveMost: 268 case CC_PreserveAll: 269 case CC_OpenCLKernel: 270 case CC_Win64: 271 return CCCR_OK; 272 default: 273 return CCCR_Warning; 274 } 275 } 276 277 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } 278 279 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { 280 return TargetInfo::AArch64ABIBuiltinVaList; 281 } 282 283 const char *const AArch64TargetInfo::GCCRegNames[] = { 284 // 32-bit Integer registers 285 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", 286 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", 287 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", 288 289 // 64-bit Integer registers 290 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", 291 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", 292 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", 293 294 // 32-bit floating point regsisters 295 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 296 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 297 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 298 299 // 64-bit floating point regsisters 300 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 301 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 302 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 303 304 // Vector registers 305 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", 306 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", 307 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" 308 }; 309 310 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { 311 return llvm::makeArrayRef(GCCRegNames); 312 } 313 314 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { 315 {{"w31"}, "wsp"}, 316 {{"x31"}, "sp"}, 317 // GCC rN registers are aliases of xN registers. 318 {{"r0"}, "x0"}, 319 {{"r1"}, "x1"}, 320 {{"r2"}, "x2"}, 321 {{"r3"}, "x3"}, 322 {{"r4"}, "x4"}, 323 {{"r5"}, "x5"}, 324 {{"r6"}, "x6"}, 325 {{"r7"}, "x7"}, 326 {{"r8"}, "x8"}, 327 {{"r9"}, "x9"}, 328 {{"r10"}, "x10"}, 329 {{"r11"}, "x11"}, 330 {{"r12"}, "x12"}, 331 {{"r13"}, "x13"}, 332 {{"r14"}, "x14"}, 333 {{"r15"}, "x15"}, 334 {{"r16"}, "x16"}, 335 {{"r17"}, "x17"}, 336 {{"r18"}, "x18"}, 337 {{"r19"}, "x19"}, 338 {{"r20"}, "x20"}, 339 {{"r21"}, "x21"}, 340 {{"r22"}, "x22"}, 341 {{"r23"}, "x23"}, 342 {{"r24"}, "x24"}, 343 {{"r25"}, "x25"}, 344 {{"r26"}, "x26"}, 345 {{"r27"}, "x27"}, 346 {{"r28"}, "x28"}, 347 {{"r29", "x29"}, "fp"}, 348 {{"r30", "x30"}, "lr"}, 349 // The S/D/Q and W/X registers overlap, but aren't really aliases; we 350 // don't want to substitute one of these for a different-sized one. 351 }; 352 353 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { 354 return llvm::makeArrayRef(GCCRegAliases); 355 } 356 357 bool AArch64TargetInfo::validateAsmConstraint( 358 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 359 switch (*Name) { 360 default: 361 return false; 362 case 'w': // Floating point and SIMD registers (V0-V31) 363 Info.setAllowsRegister(); 364 return true; 365 case 'I': // Constant that can be used with an ADD instruction 366 case 'J': // Constant that can be used with a SUB instruction 367 case 'K': // Constant that can be used with a 32-bit logical instruction 368 case 'L': // Constant that can be used with a 64-bit logical instruction 369 case 'M': // Constant that can be used as a 32-bit MOV immediate 370 case 'N': // Constant that can be used as a 64-bit MOV immediate 371 case 'Y': // Floating point constant zero 372 case 'Z': // Integer constant zero 373 return true; 374 case 'Q': // A memory reference with base register and no offset 375 Info.setAllowsMemory(); 376 return true; 377 case 'S': // A symbolic address 378 Info.setAllowsRegister(); 379 return true; 380 case 'U': 381 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. 382 // Utf: A memory address suitable for ldp/stp in TF mode. 383 // Usa: An absolute symbolic address. 384 // Ush: The high part (bits 32:12) of a pc-relative symbolic address. 385 llvm_unreachable("FIXME: Unimplemented support for U* constraints."); 386 case 'z': // Zero register, wzr or xzr 387 Info.setAllowsRegister(); 388 return true; 389 case 'x': // Floating point and SIMD registers (V0-V15) 390 Info.setAllowsRegister(); 391 return true; 392 } 393 return false; 394 } 395 396 bool AArch64TargetInfo::validateConstraintModifier( 397 StringRef Constraint, char Modifier, unsigned Size, 398 std::string &SuggestedModifier) const { 399 // Strip off constraint modifiers. 400 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 401 Constraint = Constraint.substr(1); 402 403 switch (Constraint[0]) { 404 default: 405 return true; 406 case 'z': 407 case 'r': { 408 switch (Modifier) { 409 case 'x': 410 case 'w': 411 // For now assume that the person knows what they're 412 // doing with the modifier. 413 return true; 414 default: 415 // By default an 'r' constraint will be in the 'x' 416 // registers. 417 if (Size == 64) 418 return true; 419 420 SuggestedModifier = "w"; 421 return false; 422 } 423 } 424 } 425 } 426 427 const char *AArch64TargetInfo::getClobbers() const { return ""; } 428 429 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 430 if (RegNo == 0) 431 return 0; 432 if (RegNo == 1) 433 return 1; 434 return -1; 435 } 436 437 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, 438 const TargetOptions &Opts) 439 : AArch64TargetInfo(Triple, Opts) {} 440 441 void AArch64leTargetInfo::setDataLayout() { 442 if (getTriple().isOSBinFormatMachO()) 443 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"); 444 else 445 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 446 } 447 448 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, 449 MacroBuilder &Builder) const { 450 Builder.defineMacro("__AARCH64EL__"); 451 AArch64TargetInfo::getTargetDefines(Opts, Builder); 452 } 453 454 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, 455 const TargetOptions &Opts) 456 : AArch64TargetInfo(Triple, Opts) {} 457 458 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, 459 MacroBuilder &Builder) const { 460 Builder.defineMacro("__AARCH64EB__"); 461 Builder.defineMacro("__AARCH_BIG_ENDIAN"); 462 Builder.defineMacro("__ARM_BIG_ENDIAN"); 463 AArch64TargetInfo::getTargetDefines(Opts, Builder); 464 } 465 466 void AArch64beTargetInfo::setDataLayout() { 467 assert(!getTriple().isOSBinFormatMachO()); 468 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); 469 } 470 471 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, 472 const TargetOptions &Opts) 473 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { 474 475 // This is an LLP64 platform. 476 // int:4, long:4, long long:8, long double:8. 477 IntWidth = IntAlign = 32; 478 LongWidth = LongAlign = 32; 479 DoubleAlign = LongLongAlign = 64; 480 LongDoubleWidth = LongDoubleAlign = 64; 481 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 482 IntMaxType = SignedLongLong; 483 Int64Type = SignedLongLong; 484 SizeType = UnsignedLongLong; 485 PtrDiffType = SignedLongLong; 486 IntPtrType = SignedLongLong; 487 } 488 489 void WindowsARM64TargetInfo::setDataLayout() { 490 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"); 491 } 492 493 TargetInfo::BuiltinVaListKind 494 WindowsARM64TargetInfo::getBuiltinVaListKind() const { 495 return TargetInfo::CharPtrBuiltinVaList; 496 } 497 498 TargetInfo::CallingConvCheckResult 499 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { 500 switch (CC) { 501 case CC_X86StdCall: 502 case CC_X86ThisCall: 503 case CC_X86FastCall: 504 case CC_X86VectorCall: 505 return CCCR_Ignore; 506 case CC_C: 507 case CC_OpenCLKernel: 508 case CC_PreserveMost: 509 case CC_PreserveAll: 510 case CC_Win64: 511 return CCCR_OK; 512 default: 513 return CCCR_Warning; 514 } 515 } 516 517 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, 518 const TargetOptions &Opts) 519 : WindowsARM64TargetInfo(Triple, Opts) { 520 TheCXXABI.set(TargetCXXABI::Microsoft); 521 } 522 523 void MicrosoftARM64TargetInfo::getVisualStudioDefines( 524 const LangOptions &Opts, MacroBuilder &Builder) const { 525 WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts, Builder); 526 Builder.defineMacro("_M_ARM64", "1"); 527 } 528 529 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, 530 MacroBuilder &Builder) const { 531 WindowsTargetInfo::getTargetDefines(Opts, Builder); 532 getVisualStudioDefines(Opts, Builder); 533 } 534 535 TargetInfo::CallingConvKind 536 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { 537 return CCK_MicrosoftWin64; 538 } 539 540 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, 541 const TargetOptions &Opts) 542 : WindowsARM64TargetInfo(Triple, Opts) { 543 TheCXXABI.set(TargetCXXABI::GenericAArch64); 544 } 545 546 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, 547 const TargetOptions &Opts) 548 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { 549 Int64Type = SignedLongLong; 550 UseSignedCharForObjCBool = false; 551 552 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; 553 LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 554 555 TheCXXABI.set(TargetCXXABI::iOS64); 556 } 557 558 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, 559 const llvm::Triple &Triple, 560 MacroBuilder &Builder) const { 561 Builder.defineMacro("__AARCH64_SIMD__"); 562 Builder.defineMacro("__ARM64_ARCH_8__"); 563 Builder.defineMacro("__ARM_NEON__"); 564 Builder.defineMacro("__LITTLE_ENDIAN__"); 565 Builder.defineMacro("__REGISTER_PREFIX__", ""); 566 Builder.defineMacro("__arm64", "1"); 567 Builder.defineMacro("__arm64__", "1"); 568 569 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 570 } 571 572 TargetInfo::BuiltinVaListKind 573 DarwinAArch64TargetInfo::getBuiltinVaListKind() const { 574 return TargetInfo::CharPtrBuiltinVaList; 575 } 576 577 // 64-bit RenderScript is aarch64 578 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, 579 const TargetOptions &Opts) 580 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), 581 Triple.getOSName(), 582 Triple.getEnvironmentName()), 583 Opts) { 584 IsRenderScriptTarget = true; 585 } 586 587 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, 588 MacroBuilder &Builder) const { 589 Builder.defineMacro("__RENDERSCRIPT__"); 590 AArch64leTargetInfo::getTargetDefines(Opts, Builder); 591 } 592