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