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