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