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