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