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