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