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