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