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