]> 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 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements AArch64 TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "AArch64.h"
14 #include "clang/Basic/TargetBuiltins.h"
15 #include "clang/Basic/TargetInfo.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringExtras.h"
18
19 using namespace clang;
20 using namespace clang::targets;
21
22 const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
23 #define BUILTIN(ID, TYPE, ATTRS)                                               \
24    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
25 #include "clang/Basic/BuiltinsNEON.def"
26
27 #define BUILTIN(ID, TYPE, ATTRS)                                               \
28    {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
29 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
30   {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
31 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
32   {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
33 #include "clang/Basic/BuiltinsAArch64.def"
34 };
35
36 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
37                                      const TargetOptions &Opts)
38     : TargetInfo(Triple), ABI("aapcs") {
39   if (getTriple().isOSOpenBSD()) {
40     Int64Type = SignedLongLong;
41     IntMaxType = SignedLongLong;
42   } else {
43     if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
44       WCharType = UnsignedInt;
45
46     Int64Type = SignedLong;
47     IntMaxType = SignedLong;
48   }
49
50   // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
51   HasLegalHalfType = true;
52   HasFloat16 = 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::getTargetDefinesARMV83A(const LangOptions &Opts,
122                                                 MacroBuilder &Builder) const {
123   Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
124   // Also include the Armv8.2 defines
125   getTargetDefinesARMV82A(Opts, Builder);
126 }
127
128 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
129                                                 MacroBuilder &Builder) const {
130   // Also include the Armv8.3 defines
131   // FIXME: Armv8.4 makes some extensions mandatory. Handle them here.
132   getTargetDefinesARMV83A(Opts, Builder);
133 }
134
135 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
136                                                 MacroBuilder &Builder) const {
137   // Also include the Armv8.4 defines
138   // FIXME: Armv8.5 makes some extensions mandatory. Handle them here.
139   getTargetDefinesARMV84A(Opts, Builder);
140 }
141
142
143 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
144                                          MacroBuilder &Builder) const {
145   // Target identification.
146   Builder.defineMacro("__aarch64__");
147   // For bare-metal.
148   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
149       getTriple().isOSBinFormatELF())
150     Builder.defineMacro("__ELF__");
151
152   // Target properties.
153   if (!getTriple().isOSWindows()) {
154     Builder.defineMacro("_LP64");
155     Builder.defineMacro("__LP64__");
156   }
157
158   // ACLE predefines. Many can only have one possible value on v8 AArch64.
159   Builder.defineMacro("__ARM_ACLE", "200");
160   Builder.defineMacro("__ARM_ARCH", "8");
161   Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
162
163   Builder.defineMacro("__ARM_64BIT_STATE", "1");
164   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
165   Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
166
167   Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
168   Builder.defineMacro("__ARM_FEATURE_FMA", "1");
169   Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
170   Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
171   Builder.defineMacro("__ARM_FEATURE_DIV");       // For backwards compatibility
172   Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
173   Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
174
175   Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
176
177   // 0xe implies support for half, single and double precision operations.
178   Builder.defineMacro("__ARM_FP", "0xE");
179
180   // PCS specifies this for SysV variants, which is all we support. Other ABIs
181   // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
182   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
183   Builder.defineMacro("__ARM_FP16_ARGS", "1");
184
185   if (Opts.UnsafeFPMath)
186     Builder.defineMacro("__ARM_FP_FAST", "1");
187
188   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
189                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
190
191   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
192
193   if (FPU & NeonMode) {
194     Builder.defineMacro("__ARM_NEON", "1");
195     // 64-bit NEON supports half, single and double precision operations.
196     Builder.defineMacro("__ARM_NEON_FP", "0xE");
197   }
198
199   if (HasCRC)
200     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
201
202   if (HasCrypto)
203     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
204
205   if (HasUnaligned)
206     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
207
208   if ((FPU & NeonMode) && HasFullFP16)
209     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
210   if (HasFullFP16)
211    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
212
213   if (HasDotProd)
214     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
215
216   if (HasMTE)
217     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
218
219   if ((FPU & NeonMode) && HasFP16FML)
220     Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
221
222   switch (ArchKind) {
223   default:
224     break;
225   case llvm::AArch64::ArchKind::ARMV8_1A:
226     getTargetDefinesARMV81A(Opts, Builder);
227     break;
228   case llvm::AArch64::ArchKind::ARMV8_2A:
229     getTargetDefinesARMV82A(Opts, Builder);
230     break;
231   case llvm::AArch64::ArchKind::ARMV8_3A:
232     getTargetDefinesARMV83A(Opts, Builder);
233     break;
234   case llvm::AArch64::ArchKind::ARMV8_4A:
235     getTargetDefinesARMV84A(Opts, Builder);
236     break;
237   case llvm::AArch64::ArchKind::ARMV8_5A:
238     getTargetDefinesARMV85A(Opts, Builder);
239     break;
240   }
241
242   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
243   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
244   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
245   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
246   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
247 }
248
249 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
250   return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
251                                              Builtin::FirstTSBuiltin);
252 }
253
254 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
255   return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
256          (Feature == "neon" && (FPU & NeonMode)) ||
257          (Feature == "sve" && (FPU & SveMode));
258 }
259
260 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
261                                              DiagnosticsEngine &Diags) {
262   FPU = FPUMode;
263   HasCRC = false;
264   HasCrypto = false;
265   HasUnaligned = true;
266   HasFullFP16 = false;
267   HasDotProd = false;
268   HasFP16FML = false;
269   HasMTE = false;
270   ArchKind = llvm::AArch64::ArchKind::ARMV8A;
271
272   for (const auto &Feature : Features) {
273     if (Feature == "+neon")
274       FPU |= NeonMode;
275     if (Feature == "+sve")
276       FPU |= SveMode;
277     if (Feature == "+crc")
278       HasCRC = true;
279     if (Feature == "+crypto")
280       HasCrypto = true;
281     if (Feature == "+strict-align")
282       HasUnaligned = false;
283     if (Feature == "+v8.1a")
284       ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
285     if (Feature == "+v8.2a")
286       ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
287     if (Feature == "+v8.3a")
288       ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
289     if (Feature == "+v8.4a")
290       ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
291     if (Feature == "+v8.5a")
292       ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
293     if (Feature == "+fullfp16")
294       HasFullFP16 = true;
295     if (Feature == "+dotprod")
296       HasDotProd = true;
297     if (Feature == "+fp16fml")
298       HasFP16FML = true;
299     if (Feature == "+mte")
300       HasMTE = true;
301   }
302
303   setDataLayout();
304
305   return true;
306 }
307
308 TargetInfo::CallingConvCheckResult
309 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
310   switch (CC) {
311   case CC_C:
312   case CC_Swift:
313   case CC_PreserveMost:
314   case CC_PreserveAll:
315   case CC_OpenCLKernel:
316   case CC_AArch64VectorCall:
317   case CC_Win64:
318     return CCCR_OK;
319   default:
320     return CCCR_Warning;
321   }
322 }
323
324 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
325
326 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
327   return TargetInfo::AArch64ABIBuiltinVaList;
328 }
329
330 const char *const AArch64TargetInfo::GCCRegNames[] = {
331     // 32-bit Integer registers
332     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
333     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
334     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
335
336     // 64-bit Integer registers
337     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
338     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
339     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
340
341     // 32-bit floating point regsisters
342     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
343     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
344     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
345
346     // 64-bit floating point regsisters
347     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
348     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
349     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
350
351     // Neon vector registers
352     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
353     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
354     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
355
356     // SVE vector registers
357     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
358     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
359     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
360
361     // SVE predicate registers
362     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
363     "p11", "p12", "p13", "p14", "p15"
364 };
365
366 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
367   return llvm::makeArrayRef(GCCRegNames);
368 }
369
370 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
371     {{"w31"}, "wsp"},
372     {{"x31"}, "sp"},
373     // GCC rN registers are aliases of xN registers.
374     {{"r0"}, "x0"},
375     {{"r1"}, "x1"},
376     {{"r2"}, "x2"},
377     {{"r3"}, "x3"},
378     {{"r4"}, "x4"},
379     {{"r5"}, "x5"},
380     {{"r6"}, "x6"},
381     {{"r7"}, "x7"},
382     {{"r8"}, "x8"},
383     {{"r9"}, "x9"},
384     {{"r10"}, "x10"},
385     {{"r11"}, "x11"},
386     {{"r12"}, "x12"},
387     {{"r13"}, "x13"},
388     {{"r14"}, "x14"},
389     {{"r15"}, "x15"},
390     {{"r16"}, "x16"},
391     {{"r17"}, "x17"},
392     {{"r18"}, "x18"},
393     {{"r19"}, "x19"},
394     {{"r20"}, "x20"},
395     {{"r21"}, "x21"},
396     {{"r22"}, "x22"},
397     {{"r23"}, "x23"},
398     {{"r24"}, "x24"},
399     {{"r25"}, "x25"},
400     {{"r26"}, "x26"},
401     {{"r27"}, "x27"},
402     {{"r28"}, "x28"},
403     {{"r29", "x29"}, "fp"},
404     {{"r30", "x30"}, "lr"},
405     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
406     // don't want to substitute one of these for a different-sized one.
407 };
408
409 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
410   return llvm::makeArrayRef(GCCRegAliases);
411 }
412
413 bool AArch64TargetInfo::validateAsmConstraint(
414     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
415   switch (*Name) {
416   default:
417     return false;
418   case 'w': // Floating point and SIMD registers (V0-V31)
419     Info.setAllowsRegister();
420     return true;
421   case 'I': // Constant that can be used with an ADD instruction
422   case 'J': // Constant that can be used with a SUB instruction
423   case 'K': // Constant that can be used with a 32-bit logical instruction
424   case 'L': // Constant that can be used with a 64-bit logical instruction
425   case 'M': // Constant that can be used as a 32-bit MOV immediate
426   case 'N': // Constant that can be used as a 64-bit MOV immediate
427   case 'Y': // Floating point constant zero
428   case 'Z': // Integer constant zero
429     return true;
430   case 'Q': // A memory reference with base register and no offset
431     Info.setAllowsMemory();
432     return true;
433   case 'S': // A symbolic address
434     Info.setAllowsRegister();
435     return true;
436   case 'U':
437     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
438     // Utf: A memory address suitable for ldp/stp in TF mode.
439     // Usa: An absolute symbolic address.
440     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
441     llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
442   case 'z': // Zero register, wzr or xzr
443     Info.setAllowsRegister();
444     return true;
445   case 'x': // Floating point and SIMD registers (V0-V15)
446     Info.setAllowsRegister();
447     return true;
448   }
449   return false;
450 }
451
452 bool AArch64TargetInfo::validateConstraintModifier(
453     StringRef Constraint, char Modifier, unsigned Size,
454     std::string &SuggestedModifier) const {
455   // Strip off constraint modifiers.
456   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
457     Constraint = Constraint.substr(1);
458
459   switch (Constraint[0]) {
460   default:
461     return true;
462   case 'z':
463   case 'r': {
464     switch (Modifier) {
465     case 'x':
466     case 'w':
467       // For now assume that the person knows what they're
468       // doing with the modifier.
469       return true;
470     default:
471       // By default an 'r' constraint will be in the 'x'
472       // registers.
473       if (Size == 64)
474         return true;
475
476       SuggestedModifier = "w";
477       return false;
478     }
479   }
480   }
481 }
482
483 const char *AArch64TargetInfo::getClobbers() const { return ""; }
484
485 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
486   if (RegNo == 0)
487     return 0;
488   if (RegNo == 1)
489     return 1;
490   return -1;
491 }
492
493 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
494                                          const TargetOptions &Opts)
495     : AArch64TargetInfo(Triple, Opts) {}
496
497 void AArch64leTargetInfo::setDataLayout() {
498   if (getTriple().isOSBinFormatMachO())
499     resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
500   else
501     resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
502 }
503
504 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
505                                            MacroBuilder &Builder) const {
506   Builder.defineMacro("__AARCH64EL__");
507   AArch64TargetInfo::getTargetDefines(Opts, Builder);
508 }
509
510 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
511                                          const TargetOptions &Opts)
512     : AArch64TargetInfo(Triple, Opts) {}
513
514 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
515                                            MacroBuilder &Builder) const {
516   Builder.defineMacro("__AARCH64EB__");
517   Builder.defineMacro("__AARCH_BIG_ENDIAN");
518   Builder.defineMacro("__ARM_BIG_ENDIAN");
519   AArch64TargetInfo::getTargetDefines(Opts, Builder);
520 }
521
522 void AArch64beTargetInfo::setDataLayout() {
523   assert(!getTriple().isOSBinFormatMachO());
524   resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
525 }
526
527 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
528                                                const TargetOptions &Opts)
529     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
530
531   // This is an LLP64 platform.
532   // int:4, long:4, long long:8, long double:8.
533   IntWidth = IntAlign = 32;
534   LongWidth = LongAlign = 32;
535   DoubleAlign = LongLongAlign = 64;
536   LongDoubleWidth = LongDoubleAlign = 64;
537   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
538   IntMaxType = SignedLongLong;
539   Int64Type = SignedLongLong;
540   SizeType = UnsignedLongLong;
541   PtrDiffType = SignedLongLong;
542   IntPtrType = SignedLongLong;
543 }
544
545 void WindowsARM64TargetInfo::setDataLayout() {
546   resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
547 }
548
549 TargetInfo::BuiltinVaListKind
550 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
551   return TargetInfo::CharPtrBuiltinVaList;
552 }
553
554 TargetInfo::CallingConvCheckResult
555 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
556   switch (CC) {
557   case CC_X86StdCall:
558   case CC_X86ThisCall:
559   case CC_X86FastCall:
560   case CC_X86VectorCall:
561     return CCCR_Ignore;
562   case CC_C:
563   case CC_OpenCLKernel:
564   case CC_PreserveMost:
565   case CC_PreserveAll:
566   case CC_Swift:
567   case CC_Win64:
568     return CCCR_OK;
569   default:
570     return CCCR_Warning;
571   }
572 }
573
574 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
575                                                    const TargetOptions &Opts)
576     : WindowsARM64TargetInfo(Triple, Opts) {
577   TheCXXABI.set(TargetCXXABI::Microsoft);
578 }
579
580 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
581                                                 MacroBuilder &Builder) const {
582   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
583   Builder.defineMacro("_M_ARM64", "1");
584 }
585
586 TargetInfo::CallingConvKind
587 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
588   return CCK_MicrosoftWin64;
589 }
590
591 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
592   unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
593
594   // MSVC does size based alignment for arm64 based on alignment section in
595   // below document, replicate that to keep alignment consistent with object
596   // files compiled by MSVC.
597   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
598   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
599     Align = std::max(Align, 128u);    // align type at least 16 bytes
600   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
601     Align = std::max(Align, 64u);     // align type at least 8 butes
602   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
603     Align = std::max(Align, 32u);     // align type at least 4 bytes
604   }
605   return Align;
606 }
607
608 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
609                                            const TargetOptions &Opts)
610     : WindowsARM64TargetInfo(Triple, Opts) {
611   TheCXXABI.set(TargetCXXABI::GenericAArch64);
612 }
613
614 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
615                                                  const TargetOptions &Opts)
616     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
617   Int64Type = SignedLongLong;
618   UseSignedCharForObjCBool = false;
619
620   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
621   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
622
623   TheCXXABI.set(TargetCXXABI::iOS64);
624 }
625
626 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
627                                            const llvm::Triple &Triple,
628                                            MacroBuilder &Builder) const {
629   Builder.defineMacro("__AARCH64_SIMD__");
630   Builder.defineMacro("__ARM64_ARCH_8__");
631   Builder.defineMacro("__ARM_NEON__");
632   Builder.defineMacro("__LITTLE_ENDIAN__");
633   Builder.defineMacro("__REGISTER_PREFIX__", "");
634   Builder.defineMacro("__arm64", "1");
635   Builder.defineMacro("__arm64__", "1");
636
637   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
638 }
639
640 TargetInfo::BuiltinVaListKind
641 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
642   return TargetInfo::CharPtrBuiltinVaList;
643 }
644
645 // 64-bit RenderScript is aarch64
646 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
647                                                    const TargetOptions &Opts)
648     : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
649                                        Triple.getOSName(),
650                                        Triple.getEnvironmentName()),
651                           Opts) {
652   IsRenderScriptTarget = true;
653 }
654
655 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
656                                                 MacroBuilder &Builder) const {
657   Builder.defineMacro("__RENDERSCRIPT__");
658   AArch64leTargetInfo::getTargetDefines(Opts, Builder);
659 }