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