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