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