]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.cpp
Merge clang 7.0.1 and several follow-up changes
[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().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 }