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