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