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