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