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