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