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