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