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