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