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