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 llvm::StringSwitch<bool>(Feature)
515     .Cases("aarch64", "arm64", "arm", true)
516     .Case("neon", FPU & NeonMode)
517     .Cases("sve", "sve2", "sve2-bitperm", "sve2-aes", "sve2-sha3", "sve2-sm4", "f64mm", "f32mm", "i8mm", "bf16", FPU & SveMode)
518     .Case("ls64", HasLS64)
519     .Default(false);
520 }
521 
522 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
523                                              DiagnosticsEngine &Diags) {
524   FPU = FPUMode;
525   HasCRC = false;
526   HasAES = false;
527   HasSHA2 = false;
528   HasSHA3 = false;
529   HasSM4 = false;
530   HasUnaligned = true;
531   HasFullFP16 = false;
532   HasDotProd = false;
533   HasFP16FML = false;
534   HasMTE = false;
535   HasTME = false;
536   HasLS64 = false;
537   HasRandGen = false;
538   HasMatMul = false;
539   HasBFloat16 = false;
540   HasSVE2 = false;
541   HasSVE2AES = false;
542   HasSVE2SHA3 = false;
543   HasSVE2SM4 = false;
544   HasSVE2BitPerm = false;
545   HasMatmulFP64 = false;
546   HasMatmulFP32 = false;
547   HasLSE = false;
548   HasMOPS = false;
549 
550   ArchKind = llvm::AArch64::ArchKind::INVALID;
551 
552   for (const auto &Feature : Features) {
553     if (Feature == "+neon")
554       FPU |= NeonMode;
555     if (Feature == "+sve") {
556       FPU |= SveMode;
557       HasFullFP16 = true;
558     }
559     if (Feature == "+sve2") {
560       FPU |= SveMode;
561       HasFullFP16 = true;
562       HasSVE2 = true;
563     }
564     if (Feature == "+sve2-aes") {
565       FPU |= SveMode;
566       HasFullFP16 = true;
567       HasSVE2 = true;
568       HasSVE2AES = true;
569     }
570     if (Feature == "+sve2-sha3") {
571       FPU |= SveMode;
572       HasFullFP16 = true;
573       HasSVE2 = true;
574       HasSVE2SHA3 = true;
575     }
576     if (Feature == "+sve2-sm4") {
577       FPU |= SveMode;
578       HasFullFP16 = true;
579       HasSVE2 = true;
580       HasSVE2SM4 = true;
581     }
582     if (Feature == "+sve2-bitperm") {
583       FPU |= SveMode;
584       HasFullFP16 = true;
585       HasSVE2 = true;
586       HasSVE2BitPerm = true;
587     }
588     if (Feature == "+f32mm") {
589       FPU |= SveMode;
590       HasMatmulFP32 = true;
591     }
592     if (Feature == "+f64mm") {
593       FPU |= SveMode;
594       HasMatmulFP64 = true;
595     }
596     if (Feature == "+crc")
597       HasCRC = true;
598     if (Feature == "+aes")
599       HasAES = true;
600     if (Feature == "+sha2")
601       HasSHA2 = true;
602     if (Feature == "+sha3") {
603       HasSHA2 = true;
604       HasSHA3 = true;
605     }
606     if (Feature == "+sm4")
607       HasSM4 = true;
608     if (Feature == "+strict-align")
609       HasUnaligned = false;
610     if (Feature == "+v8a")
611       ArchKind = llvm::AArch64::ArchKind::ARMV8A;
612     if (Feature == "+v8.1a")
613       ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
614     if (Feature == "+v8.2a")
615       ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
616     if (Feature == "+v8.3a")
617       ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
618     if (Feature == "+v8.4a")
619       ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
620     if (Feature == "+v8.5a")
621       ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
622     if (Feature == "+v8.6a")
623       ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
624     if (Feature == "+v8.7a")
625       ArchKind = llvm::AArch64::ArchKind::ARMV8_7A;
626     if (Feature == "+v8.8a")
627       ArchKind = llvm::AArch64::ArchKind::ARMV8_8A;
628     if (Feature == "+v9a")
629       ArchKind = llvm::AArch64::ArchKind::ARMV9A;
630     if (Feature == "+v9.1a")
631       ArchKind = llvm::AArch64::ArchKind::ARMV9_1A;
632     if (Feature == "+v9.2a")
633       ArchKind = llvm::AArch64::ArchKind::ARMV9_2A;
634     if (Feature == "+v9.3a")
635       ArchKind = llvm::AArch64::ArchKind::ARMV9_3A;
636     if (Feature == "+v8r")
637       ArchKind = llvm::AArch64::ArchKind::ARMV8R;
638     if (Feature == "+fullfp16")
639       HasFullFP16 = true;
640     if (Feature == "+dotprod")
641       HasDotProd = true;
642     if (Feature == "+fp16fml")
643       HasFP16FML = true;
644     if (Feature == "+mte")
645       HasMTE = true;
646     if (Feature == "+tme")
647       HasTME = true;
648     if (Feature == "+pauth")
649       HasPAuth = true;
650     if (Feature == "+i8mm")
651       HasMatMul = true;
652     if (Feature == "+bf16")
653       HasBFloat16 = true;
654     if (Feature == "+lse")
655       HasLSE = true;
656     if (Feature == "+ls64")
657       HasLS64 = true;
658     if (Feature == "+rand")
659       HasRandGen = true;
660     if (Feature == "+flagm")
661       HasFlagM = true;
662     if (Feature == "+mops")
663       HasMOPS = true;
664   }
665 
666   setDataLayout();
667 
668   return true;
669 }
670 
671 TargetInfo::CallingConvCheckResult
672 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
673   switch (CC) {
674   case CC_C:
675   case CC_Swift:
676   case CC_SwiftAsync:
677   case CC_PreserveMost:
678   case CC_PreserveAll:
679   case CC_OpenCLKernel:
680   case CC_AArch64VectorCall:
681   case CC_Win64:
682     return CCCR_OK;
683   default:
684     return CCCR_Warning;
685   }
686 }
687 
688 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
689 
690 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
691   return TargetInfo::AArch64ABIBuiltinVaList;
692 }
693 
694 const char *const AArch64TargetInfo::GCCRegNames[] = {
695     // 32-bit Integer registers
696     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
697     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
698     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
699 
700     // 64-bit Integer registers
701     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
702     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
703     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
704 
705     // 32-bit floating point regsisters
706     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
707     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
708     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
709 
710     // 64-bit floating point regsisters
711     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
712     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
713     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
714 
715     // Neon vector registers
716     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
717     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
718     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
719 
720     // SVE vector registers
721     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
722     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
723     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
724 
725     // SVE predicate registers
726     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
727     "p11", "p12", "p13", "p14", "p15"
728 };
729 
730 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
731   return llvm::makeArrayRef(GCCRegNames);
732 }
733 
734 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
735     {{"w31"}, "wsp"},
736     {{"x31"}, "sp"},
737     // GCC rN registers are aliases of xN registers.
738     {{"r0"}, "x0"},
739     {{"r1"}, "x1"},
740     {{"r2"}, "x2"},
741     {{"r3"}, "x3"},
742     {{"r4"}, "x4"},
743     {{"r5"}, "x5"},
744     {{"r6"}, "x6"},
745     {{"r7"}, "x7"},
746     {{"r8"}, "x8"},
747     {{"r9"}, "x9"},
748     {{"r10"}, "x10"},
749     {{"r11"}, "x11"},
750     {{"r12"}, "x12"},
751     {{"r13"}, "x13"},
752     {{"r14"}, "x14"},
753     {{"r15"}, "x15"},
754     {{"r16"}, "x16"},
755     {{"r17"}, "x17"},
756     {{"r18"}, "x18"},
757     {{"r19"}, "x19"},
758     {{"r20"}, "x20"},
759     {{"r21"}, "x21"},
760     {{"r22"}, "x22"},
761     {{"r23"}, "x23"},
762     {{"r24"}, "x24"},
763     {{"r25"}, "x25"},
764     {{"r26"}, "x26"},
765     {{"r27"}, "x27"},
766     {{"r28"}, "x28"},
767     {{"r29", "x29"}, "fp"},
768     {{"r30", "x30"}, "lr"},
769     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
770     // don't want to substitute one of these for a different-sized one.
771 };
772 
773 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
774   return llvm::makeArrayRef(GCCRegAliases);
775 }
776 
777 bool AArch64TargetInfo::validateAsmConstraint(
778     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
779   switch (*Name) {
780   default:
781     return false;
782   case 'w': // Floating point and SIMD registers (V0-V31)
783     Info.setAllowsRegister();
784     return true;
785   case 'I': // Constant that can be used with an ADD instruction
786   case 'J': // Constant that can be used with a SUB instruction
787   case 'K': // Constant that can be used with a 32-bit logical instruction
788   case 'L': // Constant that can be used with a 64-bit logical instruction
789   case 'M': // Constant that can be used as a 32-bit MOV immediate
790   case 'N': // Constant that can be used as a 64-bit MOV immediate
791   case 'Y': // Floating point constant zero
792   case 'Z': // Integer constant zero
793     return true;
794   case 'Q': // A memory reference with base register and no offset
795     Info.setAllowsMemory();
796     return true;
797   case 'S': // A symbolic address
798     Info.setAllowsRegister();
799     return true;
800   case 'U':
801     if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) {
802       // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7)
803       Info.setAllowsRegister();
804       Name += 2;
805       return true;
806     }
807     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
808     // Utf: A memory address suitable for ldp/stp in TF mode.
809     // Usa: An absolute symbolic address.
810     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
811 
812     // Better to return an error saying that it's an unrecognised constraint
813     // even if this is a valid constraint in gcc.
814     return false;
815   case 'z': // Zero register, wzr or xzr
816     Info.setAllowsRegister();
817     return true;
818   case 'x': // Floating point and SIMD registers (V0-V15)
819     Info.setAllowsRegister();
820     return true;
821   case 'y': // SVE registers (V0-V7)
822     Info.setAllowsRegister();
823     return true;
824   }
825   return false;
826 }
827 
828 bool AArch64TargetInfo::validateConstraintModifier(
829     StringRef Constraint, char Modifier, unsigned Size,
830     std::string &SuggestedModifier) const {
831   // Strip off constraint modifiers.
832   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
833     Constraint = Constraint.substr(1);
834 
835   switch (Constraint[0]) {
836   default:
837     return true;
838   case 'z':
839   case 'r': {
840     switch (Modifier) {
841     case 'x':
842     case 'w':
843       // For now assume that the person knows what they're
844       // doing with the modifier.
845       return true;
846     default:
847       // By default an 'r' constraint will be in the 'x'
848       // registers.
849       if (Size == 64)
850         return true;
851 
852       if (Size == 512)
853         return HasLS64;
854 
855       SuggestedModifier = "w";
856       return false;
857     }
858   }
859   }
860 }
861 
862 const char *AArch64TargetInfo::getClobbers() const { return ""; }
863 
864 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
865   if (RegNo == 0)
866     return 0;
867   if (RegNo == 1)
868     return 1;
869   return -1;
870 }
871 
872 bool AArch64TargetInfo::hasInt128Type() const { return true; }
873 
874 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
875                                          const TargetOptions &Opts)
876     : AArch64TargetInfo(Triple, Opts) {}
877 
878 void AArch64leTargetInfo::setDataLayout() {
879   if (getTriple().isOSBinFormatMachO()) {
880     if(getTriple().isArch32Bit())
881       resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_");
882     else
883       resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_");
884   } else
885     resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
886 }
887 
888 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
889                                            MacroBuilder &Builder) const {
890   Builder.defineMacro("__AARCH64EL__");
891   AArch64TargetInfo::getTargetDefines(Opts, Builder);
892 }
893 
894 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
895                                          const TargetOptions &Opts)
896     : AArch64TargetInfo(Triple, Opts) {}
897 
898 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
899                                            MacroBuilder &Builder) const {
900   Builder.defineMacro("__AARCH64EB__");
901   Builder.defineMacro("__AARCH_BIG_ENDIAN");
902   Builder.defineMacro("__ARM_BIG_ENDIAN");
903   AArch64TargetInfo::getTargetDefines(Opts, Builder);
904 }
905 
906 void AArch64beTargetInfo::setDataLayout() {
907   assert(!getTriple().isOSBinFormatMachO());
908   resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
909 }
910 
911 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
912                                                const TargetOptions &Opts)
913     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
914 
915   // This is an LLP64 platform.
916   // int:4, long:4, long long:8, long double:8.
917   IntWidth = IntAlign = 32;
918   LongWidth = LongAlign = 32;
919   DoubleAlign = LongLongAlign = 64;
920   LongDoubleWidth = LongDoubleAlign = 64;
921   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
922   IntMaxType = SignedLongLong;
923   Int64Type = SignedLongLong;
924   SizeType = UnsignedLongLong;
925   PtrDiffType = SignedLongLong;
926   IntPtrType = SignedLongLong;
927 }
928 
929 void WindowsARM64TargetInfo::setDataLayout() {
930   resetDataLayout(Triple.isOSBinFormatMachO()
931                       ? "e-m:o-i64:64-i128:128-n32:64-S128"
932                       : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128",
933                   Triple.isOSBinFormatMachO() ? "_" : "");
934 }
935 
936 TargetInfo::BuiltinVaListKind
937 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
938   return TargetInfo::CharPtrBuiltinVaList;
939 }
940 
941 TargetInfo::CallingConvCheckResult
942 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
943   switch (CC) {
944   case CC_X86StdCall:
945   case CC_X86ThisCall:
946   case CC_X86FastCall:
947   case CC_X86VectorCall:
948     return CCCR_Ignore;
949   case CC_C:
950   case CC_OpenCLKernel:
951   case CC_PreserveMost:
952   case CC_PreserveAll:
953   case CC_Swift:
954   case CC_SwiftAsync:
955   case CC_Win64:
956     return CCCR_OK;
957   default:
958     return CCCR_Warning;
959   }
960 }
961 
962 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
963                                                    const TargetOptions &Opts)
964     : WindowsARM64TargetInfo(Triple, Opts) {
965   TheCXXABI.set(TargetCXXABI::Microsoft);
966 }
967 
968 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
969                                                 MacroBuilder &Builder) const {
970   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
971   Builder.defineMacro("_M_ARM64", "1");
972 }
973 
974 TargetInfo::CallingConvKind
975 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
976   return CCK_MicrosoftWin64;
977 }
978 
979 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
980   unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
981 
982   // MSVC does size based alignment for arm64 based on alignment section in
983   // below document, replicate that to keep alignment consistent with object
984   // files compiled by MSVC.
985   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
986   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
987     Align = std::max(Align, 128u);    // align type at least 16 bytes
988   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
989     Align = std::max(Align, 64u);     // align type at least 8 butes
990   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
991     Align = std::max(Align, 32u);     // align type at least 4 bytes
992   }
993   return Align;
994 }
995 
996 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
997                                            const TargetOptions &Opts)
998     : WindowsARM64TargetInfo(Triple, Opts) {
999   TheCXXABI.set(TargetCXXABI::GenericAArch64);
1000 }
1001 
1002 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1003                                                  const TargetOptions &Opts)
1004     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1005   Int64Type = SignedLongLong;
1006   if (getTriple().isArch32Bit())
1007     IntMaxType = SignedLongLong;
1008 
1009   WCharType = SignedInt;
1010   UseSignedCharForObjCBool = false;
1011 
1012   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1013   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1014 
1015   UseZeroLengthBitfieldAlignment = false;
1016 
1017   if (getTriple().isArch32Bit()) {
1018     UseBitFieldTypeAlignment = false;
1019     ZeroLengthBitfieldBoundary = 32;
1020     UseZeroLengthBitfieldAlignment = true;
1021     TheCXXABI.set(TargetCXXABI::WatchOS);
1022   } else
1023     TheCXXABI.set(TargetCXXABI::AppleARM64);
1024 }
1025 
1026 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1027                                            const llvm::Triple &Triple,
1028                                            MacroBuilder &Builder) const {
1029   Builder.defineMacro("__AARCH64_SIMD__");
1030   if (Triple.isArch32Bit())
1031     Builder.defineMacro("__ARM64_ARCH_8_32__");
1032   else
1033     Builder.defineMacro("__ARM64_ARCH_8__");
1034   Builder.defineMacro("__ARM_NEON__");
1035   Builder.defineMacro("__LITTLE_ENDIAN__");
1036   Builder.defineMacro("__REGISTER_PREFIX__", "");
1037   Builder.defineMacro("__arm64", "1");
1038   Builder.defineMacro("__arm64__", "1");
1039 
1040   if (Triple.isArm64e())
1041     Builder.defineMacro("__arm64e__", "1");
1042 
1043   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1044 }
1045 
1046 TargetInfo::BuiltinVaListKind
1047 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1048   return TargetInfo::CharPtrBuiltinVaList;
1049 }
1050 
1051 // 64-bit RenderScript is aarch64
1052 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
1053                                                    const TargetOptions &Opts)
1054     : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
1055                                        Triple.getOSName(),
1056                                        Triple.getEnvironmentName()),
1057                           Opts) {
1058   IsRenderScriptTarget = true;
1059 }
1060 
1061 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
1062                                                 MacroBuilder &Builder) const {
1063   Builder.defineMacro("__RENDERSCRIPT__");
1064   AArch64leTargetInfo::getTargetDefines(Opts, Builder);
1065 }
1066