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