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