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