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