xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp (revision 9c77fb6aaa366cbabc80ee1b834bcfe4df135491)
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/Diagnostic.h"
15 #include "clang/Basic/LangOptions.h"
16 #include "clang/Basic/TargetBuiltins.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "llvm/ADT/APSInt.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/TargetParser/AArch64TargetParser.h"
22 #include "llvm/TargetParser/ARMTargetParserCommon.h"
23 #include <optional>
24 
25 using namespace clang;
26 using namespace clang::targets;
27 
28 static constexpr int NumNeonBuiltins =
29     NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin;
30 static constexpr int NumFp16Builtins =
31     NEON::FirstTSBuiltin - NEON::FirstFp16Builtin;
32 static constexpr int NumSVEBuiltins =
33     SVE::FirstNeonBridgeBuiltin - NEON::FirstTSBuiltin;
34 static constexpr int NumSVENeonBridgeBuiltins =
35     SVE::FirstTSBuiltin - SVE::FirstNeonBridgeBuiltin;
36 static constexpr int NumSMEBuiltins = SME::FirstTSBuiltin - SVE::FirstTSBuiltin;
37 static constexpr int NumAArch64Builtins =
38     AArch64::LastTSBuiltin - SME::FirstTSBuiltin;
39 static constexpr int NumBuiltins =
40     AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
41 static_assert(NumBuiltins ==
42               (NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins +
43                NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins));
44 
45 namespace clang {
46 namespace NEON {
47 #define GET_NEON_BUILTIN_STR_TABLE
48 #include "clang/Basic/arm_neon.inc"
49 #undef GET_NEON_BUILTIN_STR_TABLE
50 
51 static constexpr std::array<Builtin::Info, NumNeonBuiltins> BuiltinInfos = {
52 #define GET_NEON_BUILTIN_INFOS
53 #include "clang/Basic/arm_neon.inc"
54 #undef GET_NEON_BUILTIN_INFOS
55 };
56 
57 namespace FP16 {
58 #define GET_NEON_BUILTIN_STR_TABLE
59 #include "clang/Basic/arm_fp16.inc"
60 #undef GET_NEON_BUILTIN_STR_TABLE
61 
62 static constexpr std::array<Builtin::Info, NumFp16Builtins> BuiltinInfos = {
63 #define GET_NEON_BUILTIN_INFOS
64 #include "clang/Basic/arm_fp16.inc"
65 #undef GET_NEON_BUILTIN_INFOS
66 };
67 } // namespace FP16
68 } // namespace NEON
69 
70 namespace SVE {
71 #define GET_SVE_BUILTIN_STR_TABLE
72 #include "clang/Basic/arm_sve_builtins.inc"
73 #undef GET_SVE_BUILTIN_STR_TABLE
74 
75 static constexpr std::array<Builtin::Info, NumSVEBuiltins> BuiltinInfos = {
76 #define GET_SVE_BUILTIN_INFOS
77 #include "clang/Basic/arm_sve_builtins.inc"
78 #undef GET_SVE_BUILTIN_INFOS
79 };
80 } // namespace SVE
81 
82 namespace SME {
83 #define GET_SME_BUILTIN_STR_TABLE
84 #include "clang/Basic/arm_sme_builtins.inc"
85 #undef GET_SME_BUILTIN_STR_TABLE
86 
87 static constexpr std::array<Builtin::Info, NumSMEBuiltins> BuiltinInfos = {
88 #define GET_SME_BUILTIN_INFOS
89 #include "clang/Basic/arm_sme_builtins.inc"
90 #undef GET_SME_BUILTIN_INFOS
91 };
92 } // namespace SME
93 } // namespace clang
94 
95 static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings =
96     CLANG_BUILTIN_STR_TABLE_START
97 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
98 #define GET_SVE_BUILTINS
99 #include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
100 #undef GET_SVE_BUILTINS
101 #undef TARGET_BUILTIN
102     ;
103 static constexpr llvm::StringTable BuiltinAArch64Strings =
104     CLANG_BUILTIN_STR_TABLE_START
105 #define BUILTIN CLANG_BUILTIN_STR_TABLE
106 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
107 #define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
108 #include "clang/Basic/BuiltinsAArch64.def"
109     ;
110 
111 static constexpr auto BuiltinSVENeonBridgeInfos =
112     Builtin::MakeInfos<NumSVENeonBridgeBuiltins>({
113 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
114 #define GET_SVE_BUILTINS
115 #include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
116 #undef GET_SVE_BUILTINS
117 #undef TARGET_BUILTIN
118     });
119 static constexpr auto BuiltinAArch64Infos =
120     Builtin::MakeInfos<NumAArch64Builtins>({
121 #define BUILTIN CLANG_BUILTIN_ENTRY
122 #define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
123 #define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
124 #define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
125 #include "clang/Basic/BuiltinsAArch64.def"
126     });
127 
128 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
129                                      const TargetOptions &Opts)
130     : TargetInfo(Triple), ABI("aapcs") {
131   if (getTriple().isOSOpenBSD()) {
132     Int64Type = SignedLongLong;
133     IntMaxType = SignedLongLong;
134   } else {
135     if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
136       WCharType = UnsignedInt;
137 
138     Int64Type = SignedLong;
139     IntMaxType = SignedLong;
140   }
141 
142   AddrSpaceMap = &ARM64AddrSpaceMap;
143 
144   // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
145   HasLegalHalfType = true;
146   HalfArgsAndReturns = true;
147   HasFloat16 = true;
148   HasStrictFP = true;
149 
150   if (Triple.isArch64Bit())
151     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
152   else
153     LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
154 
155   BitIntMaxAlign = 128;
156   MaxVectorAlign = 128;
157   MaxAtomicInlineWidth = 128;
158   MaxAtomicPromoteWidth = 128;
159 
160   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
161   LongDoubleFormat = &llvm::APFloat::IEEEquad();
162 
163   BFloat16Width = BFloat16Align = 16;
164   BFloat16Format = &llvm::APFloat::BFloat();
165 
166   // Make __builtin_ms_va_list available.
167   HasBuiltinMSVaList = true;
168 
169   // Make the Neon ACLE and SVE types available.  Note that this deliberately
170   // doesn't depend on SveMode, since in principle it should be possible to turn
171   // SVE on and off within a translation unit.  It should also be possible
172   // to compile the global declaration:
173   //
174   // __SVInt8_t *ptr;
175   //
176   // even without SVE.
177   HasAArch64ACLETypes = true;
178 
179   // {} in inline assembly are neon specifiers, not assembly variant
180   // specifiers.
181   NoAsmVariants = true;
182 
183   // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
184   // contributes to the alignment of the containing aggregate in the same way
185   // a plain (non bit-field) member of that type would, without exception for
186   // zero-sized or anonymous bit-fields."
187   assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
188   UseZeroLengthBitfieldAlignment = true;
189 
190   // AAPCS64 allows any "fundamental integer data type" to be used for
191   // over-sized bitfields, which includes 128-bit integers.
192   LargestOverSizedBitfieldContainer = 128;
193 
194   HasUnalignedAccess = true;
195 
196   // AArch64 targets default to using the ARM C++ ABI.
197   TheCXXABI.set(TargetCXXABI::GenericAArch64);
198 
199   if (Triple.getOS() == llvm::Triple::Linux)
200     this->MCountName = "\01_mcount";
201   else if (Triple.getOS() == llvm::Triple::UnknownOS)
202     this->MCountName =
203         Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
204 }
205 
206 StringRef AArch64TargetInfo::getABI() const { return ABI; }
207 
208 bool AArch64TargetInfo::setABI(const std::string &Name) {
209   if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&
210       Name != "pauthtest")
211     return false;
212 
213   ABI = Name;
214   return true;
215 }
216 
217 bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
218   if (hasFeature("fp") && ABI == "aapcs-soft") {
219     // aapcs-soft is not allowed for targets with an FPU, to avoid there being
220     // two incomatible ABIs.
221     Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
222     return false;
223   }
224   if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&
225       getTriple().getOS() != llvm::Triple::Linux) {
226     Diags.Report(diag::err_target_unsupported_abi_for_triple)
227         << getTriple().getEnvironmentName() << getTriple().getTriple();
228     return false;
229   }
230   return true;
231 }
232 
233 bool AArch64TargetInfo::validateGlobalRegisterVariable(
234     StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
235   if (RegName == "sp") {
236     HasSizeMismatch = RegSize != 64;
237     return true;
238   }
239   if (RegName.starts_with("w"))
240     HasSizeMismatch = RegSize != 32;
241   else if (RegName.starts_with("x"))
242     HasSizeMismatch = RegSize != 64;
243   else
244     return false;
245   StringRef RegNum = RegName.drop_front();
246   // Check if the register is reserved. See also
247   // AArch64TargetLowering::getRegisterByName().
248   return RegNum == "0" ||
249          (RegNum == "18" &&
250           llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
251          getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str());
252 }
253 
254 bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
255                                                  BranchProtectionInfo &BPI,
256                                                  const LangOptions &LO,
257                                                  StringRef &Err) const {
258   llvm::ARM::ParsedBranchProtection PBP;
259   if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
260     return false;
261 
262   // GCS is currently untested with ptrauth-returns, but enabling this could be
263   // allowed in future after testing with a suitable system.
264   if (LO.PointerAuthReturns &&
265       (PBP.Scope != "none" || PBP.BranchProtectionPAuthLR ||
266        PBP.GuardedControlStack))
267     return false;
268 
269   BPI.SignReturnAddr =
270       llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
271           .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
272           .Case("all", LangOptions::SignReturnAddressScopeKind::All)
273           .Default(LangOptions::SignReturnAddressScopeKind::None);
274 
275   if (PBP.Key == "a_key")
276     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
277   else
278     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
279 
280   BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
281   BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
282   BPI.GuardedControlStack = PBP.GuardedControlStack;
283   return true;
284 }
285 
286 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
287   return llvm::AArch64::parseCpu(Name).has_value();
288 }
289 
290 bool AArch64TargetInfo::setCPU(const std::string &Name) {
291   return isValidCPUName(Name);
292 }
293 
294 void AArch64TargetInfo::fillValidCPUList(
295     SmallVectorImpl<StringRef> &Values) const {
296   llvm::AArch64::fillValidCPUArchList(Values);
297 }
298 
299 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
300                                                 MacroBuilder &Builder) const {
301   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
302 }
303 
304 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
305                                                 MacroBuilder &Builder) const {
306   // Also include the ARMv8.1 defines
307   getTargetDefinesARMV81A(Opts, Builder);
308 }
309 
310 void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
311                                                 MacroBuilder &Builder) const {
312   Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
313   Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
314   // Also include the Armv8.2 defines
315   getTargetDefinesARMV82A(Opts, Builder);
316 }
317 
318 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
319                                                 MacroBuilder &Builder) const {
320   // Also include the Armv8.3 defines
321   getTargetDefinesARMV83A(Opts, Builder);
322 }
323 
324 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
325                                                 MacroBuilder &Builder) const {
326   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
327   // Also include the Armv8.4 defines
328   getTargetDefinesARMV84A(Opts, Builder);
329 }
330 
331 void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
332                                                 MacroBuilder &Builder) const {
333   // Also include the Armv8.5 defines
334   // FIXME: Armv8.6 makes the following extensions mandatory:
335   // - __ARM_FEATURE_BF16
336   // - __ARM_FEATURE_MATMUL_INT8
337   // Handle them here.
338   getTargetDefinesARMV85A(Opts, Builder);
339 }
340 
341 void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
342                                                 MacroBuilder &Builder) const {
343   // Also include the Armv8.6 defines
344   getTargetDefinesARMV86A(Opts, Builder);
345 }
346 
347 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
348                                                 MacroBuilder &Builder) const {
349   // Also include the Armv8.7 defines
350   getTargetDefinesARMV87A(Opts, Builder);
351 }
352 
353 void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
354                                                 MacroBuilder &Builder) const {
355   // Also include the Armv8.8 defines
356   getTargetDefinesARMV88A(Opts, Builder);
357 }
358 
359 void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
360                                                MacroBuilder &Builder) const {
361   // Armv9-A maps to Armv8.5-A
362   getTargetDefinesARMV85A(Opts, Builder);
363 }
364 
365 void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
366                                                 MacroBuilder &Builder) const {
367   // Armv9.1-A maps to Armv8.6-A
368   getTargetDefinesARMV86A(Opts, Builder);
369 }
370 
371 void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
372                                                 MacroBuilder &Builder) const {
373   // Armv9.2-A maps to Armv8.7-A
374   getTargetDefinesARMV87A(Opts, Builder);
375 }
376 
377 void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
378                                                 MacroBuilder &Builder) const {
379   // Armv9.3-A maps to Armv8.8-A
380   getTargetDefinesARMV88A(Opts, Builder);
381 }
382 
383 void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
384                                                 MacroBuilder &Builder) const {
385   // Armv9.4-A maps to Armv8.9-A
386   getTargetDefinesARMV89A(Opts, Builder);
387 }
388 
389 void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
390                                                 MacroBuilder &Builder) const {
391   // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
392   getTargetDefinesARMV94A(Opts, Builder);
393 }
394 
395 void AArch64TargetInfo::getTargetDefinesARMV96A(const LangOptions &Opts,
396                                                 MacroBuilder &Builder) const {
397   // Armv9.6-A does not have a v8.* equivalent, but is a superset of v9.5-A.
398   getTargetDefinesARMV95A(Opts, Builder);
399 }
400 
401 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
402                                          MacroBuilder &Builder) const {
403   // Target identification.
404   if (getTriple().isWindowsArm64EC()) {
405     // Define the same set of macros as would be defined on x86_64 to ensure that
406     // ARM64EC datatype layouts match those of x86_64 compiled code
407     Builder.defineMacro("__amd64__");
408     Builder.defineMacro("__amd64");
409     Builder.defineMacro("__x86_64");
410     Builder.defineMacro("__x86_64__");
411     Builder.defineMacro("__arm64ec__");
412   } else {
413     Builder.defineMacro("__aarch64__");
414   }
415 
416   // Inline assembly supports AArch64 flag outputs.
417   Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
418 
419   std::string CodeModel = getTargetOpts().CodeModel;
420   if (CodeModel == "default")
421     CodeModel = "small";
422   for (char &c : CodeModel)
423     c = toupper(c);
424   Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
425 
426   // ACLE predefines. Many can only have one possible value on v8 AArch64.
427   Builder.defineMacro("__ARM_ACLE_VERSION(year, quarter, patch)",
428                       "(100 * (year) + 10 * (quarter) + (patch))");
429 #define ARM_ACLE_VERSION(Y, Q, P) (100 * (Y) + 10 * (Q) + (P))
430   Builder.defineMacro("__ARM_ACLE", Twine(ARM_ACLE_VERSION(2024, 2, 0)));
431   Builder.defineMacro("__FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL",
432                       Twine(ARM_ACLE_VERSION(2024, 3, 0)));
433 #undef ARM_ACLE_VERSION
434   Builder.defineMacro("__ARM_ARCH",
435                       std::to_string(ArchInfo->Version.getMajor()));
436   Builder.defineMacro("__ARM_ARCH_PROFILE",
437                       std::string("'") + (char)ArchInfo->Profile + "'");
438 
439   Builder.defineMacro("__ARM_64BIT_STATE", "1");
440   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
441   Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
442 
443   Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
444   Builder.defineMacro("__ARM_FEATURE_FMA", "1");
445   Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
446   Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
447   Builder.defineMacro("__ARM_FEATURE_DIV");       // For backwards compatibility
448   Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
449   Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
450 
451   Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
452 
453   // These macros are set when Clang can parse declarations with these
454   // attributes.
455   Builder.defineMacro("__ARM_STATE_ZA", "1");
456   Builder.defineMacro("__ARM_STATE_ZT0", "1");
457 
458   // 0xe implies support for half, single and double precision operations.
459   if (FPU & FPUMode)
460     Builder.defineMacro("__ARM_FP", "0xE");
461 
462   // PCS specifies this for SysV variants, which is all we support. Other ABIs
463   // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
464   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
465   Builder.defineMacro("__ARM_FP16_ARGS", "1");
466 
467   // Clang supports arm_neon_sve_bridge.h
468   Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
469 
470   if (Opts.UnsafeFPMath)
471     Builder.defineMacro("__ARM_FP_FAST", "1");
472 
473   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
474                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
475 
476   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
477 
478   if (FPU & NeonMode) {
479     Builder.defineMacro("__ARM_NEON", "1");
480     // 64-bit NEON supports half, single and double precision operations.
481     Builder.defineMacro("__ARM_NEON_FP", "0xE");
482   }
483 
484   if (FPU & SveMode)
485     Builder.defineMacro("__ARM_FEATURE_SVE", "1");
486 
487   if (HasSVE2)
488     Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
489 
490   if (HasSVE2p1)
491     Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");
492 
493   if (HasSVE2 && HasSVEAES)
494     Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
495 
496   if (HasSVE2 && HasSVEBitPerm)
497     Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
498 
499   if (HasSVE2 && HasSVE2SHA3)
500     Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
501 
502   if (HasSVE2 && HasSVE2SM4)
503     Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
504 
505   if (HasSVEB16B16)
506     Builder.defineMacro("__ARM_FEATURE_SVE_B16B16", "1");
507 
508   if (HasSME) {
509     Builder.defineMacro("__ARM_FEATURE_SME");
510     Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
511   }
512 
513   if (HasSME2)
514     Builder.defineMacro("__ARM_FEATURE_SME2", "1");
515 
516   if (HasSME2p1)
517     Builder.defineMacro("__ARM_FEATURE_SME2p1", "1");
518 
519   if (HasSMEF16F16)
520     Builder.defineMacro("__ARM_FEATURE_SME_F16F16", "1");
521 
522   if (HasSMEB16B16)
523     Builder.defineMacro("__ARM_FEATURE_SME_B16B16", "1");
524 
525   if (HasFP8)
526     Builder.defineMacro("__ARM_FEATURE_FP8", "1");
527 
528   if (HasFP8FMA)
529     Builder.defineMacro("__ARM_FEATURE_FP8FMA", "1");
530 
531   if (HasFP8DOT2)
532     Builder.defineMacro("__ARM_FEATURE_FP8DOT2", "1");
533 
534   if (HasFP8DOT4)
535     Builder.defineMacro("__ARM_FEATURE_FP8DOT4", "1");
536 
537   if (HasSSVE_FP8DOT2)
538     Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT2", "1");
539 
540   if (HasSSVE_FP8DOT4)
541     Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT4", "1");
542 
543   if (HasSSVE_FP8FMA)
544     Builder.defineMacro("__ARM_FEATURE_SSVE_FP8FMA", "1");
545 
546   if (HasSME_F8F32)
547     Builder.defineMacro("__ARM_FEATURE_SME_F8F32", "1");
548 
549   if (HasSME_F8F16)
550     Builder.defineMacro("__ARM_FEATURE_SME_F8F16", "1");
551 
552   if (HasCRC)
553     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
554 
555   if (HasCSSC)
556     Builder.defineMacro("__ARM_FEATURE_CSSC", "1");
557 
558   if (HasRCPC3)
559     Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
560   else if (HasRCPC)
561     Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
562 
563   if (HasFMV)
564     Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
565 
566   // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
567   // macros for AES, SHA2, SHA3 and SM4
568   if (HasAES && HasSHA2)
569     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
570 
571   if (HasAES)
572     Builder.defineMacro("__ARM_FEATURE_AES", "1");
573 
574   if (HasSHA2)
575     Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
576 
577   if (HasSHA3) {
578     Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
579     Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
580   }
581 
582   if (HasSM4) {
583     Builder.defineMacro("__ARM_FEATURE_SM3", "1");
584     Builder.defineMacro("__ARM_FEATURE_SM4", "1");
585   }
586 
587   if (HasPAuth)
588     Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
589 
590   if (HasPAuthLR)
591     Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
592 
593   if (HasBTI)
594     Builder.defineMacro("__ARM_FEATURE_BTI", "1");
595 
596   if (HasUnalignedAccess)
597     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
598 
599   if ((FPU & NeonMode) && HasFullFP16)
600     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
601   if (HasFullFP16)
602    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
603 
604   if (HasDotProd)
605     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
606 
607   if (HasMTE)
608     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
609 
610   if (HasTME)
611     Builder.defineMacro("__ARM_FEATURE_TME", "1");
612 
613   if (HasMatMul)
614     Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
615 
616   if (HasLSE)
617     Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
618 
619   if (HasBFloat16) {
620     Builder.defineMacro("__ARM_FEATURE_BF16", "1");
621     Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
622     Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
623     Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
624   }
625 
626   if ((FPU & SveMode) && HasBFloat16) {
627     Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
628   }
629 
630   if ((FPU & SveMode) && HasMatmulFP64)
631     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
632 
633   if ((FPU & SveMode) && HasMatmulFP32)
634     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
635 
636   if ((FPU & SveMode) && HasMatMul)
637     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
638 
639   if ((FPU & NeonMode) && HasFP16FML)
640     Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
641 
642   if (Opts.hasSignReturnAddress()) {
643     // Bitmask:
644     // 0: Protection using the A key
645     // 1: Protection using the B key
646     // 2: Protection including leaf functions
647     // 3: Protection using PC as a diversifier
648     unsigned Value = 0;
649 
650     if (Opts.isSignReturnAddressWithAKey())
651       Value |= (1 << 0);
652     else
653       Value |= (1 << 1);
654 
655     if (Opts.isSignReturnAddressScopeAll())
656       Value |= (1 << 2);
657 
658     if (Opts.BranchProtectionPAuthLR)
659       Value |= (1 << 3);
660 
661     Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
662   }
663 
664   if (Opts.BranchTargetEnforcement)
665     Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
666 
667   if (Opts.GuardedControlStack)
668     Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
669 
670   if (HasLS64)
671     Builder.defineMacro("__ARM_FEATURE_LS64", "1");
672 
673   if (HasRandGen)
674     Builder.defineMacro("__ARM_FEATURE_RNG", "1");
675 
676   if (HasMOPS)
677     Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
678 
679   if (HasD128)
680     Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
681 
682   if (HasGCS)
683     Builder.defineMacro("__ARM_FEATURE_GCS", "1");
684 
685   if (*ArchInfo == llvm::AArch64::ARMV8_1A)
686     getTargetDefinesARMV81A(Opts, Builder);
687   else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
688     getTargetDefinesARMV82A(Opts, Builder);
689   else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
690     getTargetDefinesARMV83A(Opts, Builder);
691   else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
692     getTargetDefinesARMV84A(Opts, Builder);
693   else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
694     getTargetDefinesARMV85A(Opts, Builder);
695   else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
696     getTargetDefinesARMV86A(Opts, Builder);
697   else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
698     getTargetDefinesARMV87A(Opts, Builder);
699   else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
700     getTargetDefinesARMV88A(Opts, Builder);
701   else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
702     getTargetDefinesARMV89A(Opts, Builder);
703   else if (*ArchInfo == llvm::AArch64::ARMV9A)
704     getTargetDefinesARMV9A(Opts, Builder);
705   else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
706     getTargetDefinesARMV91A(Opts, Builder);
707   else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
708     getTargetDefinesARMV92A(Opts, Builder);
709   else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
710     getTargetDefinesARMV93A(Opts, Builder);
711   else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
712     getTargetDefinesARMV94A(Opts, Builder);
713   else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
714     getTargetDefinesARMV95A(Opts, Builder);
715   else if (*ArchInfo == llvm::AArch64::ARMV9_6A)
716     getTargetDefinesARMV96A(Opts, Builder);
717 
718   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
719   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
720   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
721   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
722   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
723   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
724 
725   // Allow detection of fast FMA support.
726   Builder.defineMacro("__FP_FAST_FMA", "1");
727   Builder.defineMacro("__FP_FAST_FMAF", "1");
728 
729   // C/C++ operators work on both VLS and VLA SVE types
730   if (FPU & SveMode)
731     Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
732 
733   if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
734     Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
735   }
736 }
737 
738 llvm::SmallVector<Builtin::InfosShard>
739 AArch64TargetInfo::getTargetBuiltins() const {
740   return {
741       {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"},
742       {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos,
743        "__builtin_neon_"},
744       {&SVE::BuiltinStrings, SVE::BuiltinInfos, "__builtin_sve_"},
745       {&BuiltinSVENeonBridgeStrings, BuiltinSVENeonBridgeInfos},
746       {&SME::BuiltinStrings, SME::BuiltinInfos, "__builtin_sme_"},
747       {&BuiltinAArch64Strings, BuiltinAArch64Infos},
748   };
749 }
750 
751 std::optional<std::pair<unsigned, unsigned>>
752 AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts,
753                                   ArmStreamingKind Mode,
754                                   llvm::StringMap<bool> *FeatureMap) const {
755   if (Mode == ArmStreamingKind::NotStreaming &&
756       (LangOpts.VScaleMin || LangOpts.VScaleMax))
757     return std::pair<unsigned, unsigned>(
758         LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
759         LangOpts.VScaleMax ? LangOpts.VScaleMax : 16);
760 
761   if (Mode == ArmStreamingKind::Streaming &&
762       (LangOpts.VScaleStreamingMin || LangOpts.VScaleStreamingMax))
763     return std::pair<unsigned, unsigned>(
764         LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1,
765         LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
766 
767   if (Mode == ArmStreamingKind::StreamingCompatible &&
768       ((LangOpts.VScaleMin && LangOpts.VScaleStreamingMin) ||
769        (LangOpts.VScaleMax && LangOpts.VScaleStreamingMax))) {
770     unsigned Min =
771         std::min(LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
772                  LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1);
773     unsigned Max = std::max(
774         LangOpts.VScaleMax ? LangOpts.VScaleMax : 16,
775         LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
776     return std::pair(Min, Max);
777   }
778 
779   if (hasFeature("sve") || (FeatureMap && (FeatureMap->lookup("sve"))))
780     return std::pair<unsigned, unsigned>(1, 16);
781 
782   if (Mode == ArmStreamingKind::Streaming &&
783       (hasFeature("sme") || (FeatureMap && (FeatureMap->lookup("sme")))))
784     return std::pair<unsigned, unsigned>(1, 16);
785 
786   return std::nullopt;
787 }
788 
789 uint64_t AArch64TargetInfo::getFMVPriority(ArrayRef<StringRef> Features) const {
790   return llvm::AArch64::getFMVPriority(Features);
791 }
792 
793 bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
794   // FMV extensions which imply no backend features do not affect codegen.
795   if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
796     return Ext->ID.has_value();
797   return false;
798 }
799 
800 bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
801   // CPU features might be separated by '+', extract them and check
802   llvm::SmallVector<StringRef, 8> Features;
803   FeatureStr.split(Features, "+");
804   for (auto &Feature : Features)
805     if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())
806       return false;
807   return true;
808 }
809 
810 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
811   return llvm::StringSwitch<bool>(Feature)
812       .Cases("aarch64", "arm64", "arm", true)
813       .Case("fmv", HasFMV)
814       .Case("fp", FPU & FPUMode)
815       .Cases("neon", "simd", FPU & NeonMode)
816       .Case("jscvt", HasJSCVT)
817       .Case("fcma", HasFCMA)
818       .Case("rng", HasRandGen)
819       .Case("flagm", HasFlagM)
820       .Case("flagm2", HasAlternativeNZCV)
821       .Case("fp16fml", HasFP16FML)
822       .Case("dotprod", HasDotProd)
823       .Case("sm4", HasSM4)
824       .Case("rdm", HasRDM)
825       .Case("lse", HasLSE)
826       .Case("crc", HasCRC)
827       .Case("cssc", HasCSSC)
828       .Case("sha2", HasSHA2)
829       .Case("sha3", HasSHA3)
830       .Cases("aes", "pmull", HasAES)
831       .Cases("fp16", "fullfp16", HasFullFP16)
832       .Case("dit", HasDIT)
833       .Case("dpb", HasCCPP)
834       .Case("dpb2", HasCCDP)
835       .Case("rcpc", HasRCPC)
836       .Case("frintts", HasFRInt3264)
837       .Case("i8mm", HasMatMul)
838       .Case("bf16", HasBFloat16)
839       .Case("sve", FPU & SveMode)
840       .Case("sve-b16b16", HasSVEB16B16)
841       .Case("f32mm", FPU & SveMode && HasMatmulFP32)
842       .Case("f64mm", FPU & SveMode && HasMatmulFP64)
843       .Case("sve2", FPU & SveMode && HasSVE2)
844       .Case("sve-aes", HasSVEAES)
845       .Case("sve-bitperm", FPU & HasSVEBitPerm)
846       .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
847       .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
848       .Case("sve2p1", FPU & SveMode && HasSVE2p1)
849       .Case("sme", HasSME)
850       .Case("sme2", HasSME2)
851       .Case("sme2p1", HasSME2p1)
852       .Case("sme-f64f64", HasSMEF64F64)
853       .Case("sme-i16i64", HasSMEI16I64)
854       .Case("sme-fa64", HasSMEFA64)
855       .Case("sme-f16f16", HasSMEF16F16)
856       .Case("sme-b16b16", HasSMEB16B16)
857       .Case("memtag", HasMTE)
858       .Case("sb", HasSB)
859       .Case("predres", HasPredRes)
860       .Cases("ssbs", "ssbs2", HasSSBS)
861       .Case("bti", HasBTI)
862       .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
863       .Case("wfxt", HasWFxT)
864       .Case("rcpc3", HasRCPC3)
865       .Case("fp8", HasFP8)
866       .Case("fp8fma", HasFP8FMA)
867       .Case("fp8dot2", HasFP8DOT2)
868       .Case("fp8dot4", HasFP8DOT4)
869       .Case("ssve-fp8dot2", HasSSVE_FP8DOT2)
870       .Case("ssve-fp8dot4", HasSSVE_FP8DOT4)
871       .Case("ssve-fp8fma", HasSSVE_FP8FMA)
872       .Case("sme-f8f32", HasSME_F8F32)
873       .Case("sme-f8f16", HasSME_F8F16)
874       .Default(false);
875 }
876 
877 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
878                                           StringRef Name, bool Enabled) const {
879   Features[Name] = Enabled;
880   // If the feature is an architecture feature (like v8.2a), add all previous
881   // architecture versions and any dependant target features.
882   const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
883       llvm::AArch64::ArchInfo::findBySubArch(Name);
884 
885   if (!ArchInfo)
886     return; // Not an architecture, nothing more to do.
887 
888   // Disabling an architecture feature does not affect dependent features
889   if (!Enabled)
890     return;
891 
892   for (const auto *OtherArch : llvm::AArch64::ArchInfos)
893     if (ArchInfo->implies(*OtherArch))
894       Features[OtherArch->getSubArch()] = true;
895 
896   // Set any features implied by the architecture
897   std::vector<StringRef> CPUFeats;
898   if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
899     for (auto F : CPUFeats) {
900       assert(F[0] == '+' && "Expected + in target feature!");
901       Features[F.drop_front(1)] = true;
902     }
903   }
904 }
905 
906 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
907                                              DiagnosticsEngine &Diags) {
908   for (const auto &Feature : Features) {
909     if (Feature == "-fp-armv8")
910       HasNoFP = true;
911     if (Feature == "-neon")
912       HasNoNeon = true;
913     if (Feature == "-sve")
914       HasNoSVE = true;
915 
916     if (Feature == "+neon" || Feature == "+fp-armv8")
917       FPU |= NeonMode;
918     if (Feature == "+jscvt") {
919       HasJSCVT = true;
920       FPU |= NeonMode;
921     }
922     if (Feature == "+fcma") {
923       HasFCMA = true;
924       FPU |= NeonMode;
925     }
926 
927     if (Feature == "+sve") {
928       FPU |= NeonMode;
929       FPU |= SveMode;
930       HasFullFP16 = true;
931     }
932     if (Feature == "+sve2") {
933       FPU |= NeonMode;
934       FPU |= SveMode;
935       HasFullFP16 = true;
936       HasSVE2 = true;
937     }
938     if (Feature == "+sve2p1") {
939       FPU |= NeonMode;
940       FPU |= SveMode;
941       HasFullFP16 = true;
942       HasSVE2 = true;
943       HasSVE2p1 = true;
944     }
945     if (Feature == "+sve-aes") {
946       FPU |= NeonMode;
947       HasFullFP16 = true;
948       HasSVEAES = true;
949     }
950     if (Feature == "+sve2-sha3") {
951       FPU |= NeonMode;
952       FPU |= SveMode;
953       HasFullFP16 = true;
954       HasSVE2 = true;
955       HasSVE2SHA3 = true;
956     }
957     if (Feature == "+sve2-sm4") {
958       FPU |= NeonMode;
959       FPU |= SveMode;
960       HasFullFP16 = true;
961       HasSVE2 = true;
962       HasSVE2SM4 = true;
963     }
964     if (Feature == "+sve-b16b16")
965       HasSVEB16B16 = true;
966     if (Feature == "+sve-bitperm") {
967       FPU |= NeonMode;
968       HasFullFP16 = true;
969       HasSVEBitPerm = true;
970     }
971     if (Feature == "+f32mm") {
972       FPU |= NeonMode;
973       FPU |= SveMode;
974       HasFullFP16 = true;
975       HasMatmulFP32 = true;
976     }
977     if (Feature == "+f64mm") {
978       FPU |= NeonMode;
979       FPU |= SveMode;
980       HasFullFP16 = true;
981       HasMatmulFP64 = true;
982     }
983     if (Feature == "+sme") {
984       HasSME = true;
985       HasBFloat16 = true;
986       HasFullFP16 = true;
987     }
988     if (Feature == "+sme2") {
989       HasSME = true;
990       HasSME2 = true;
991       HasBFloat16 = true;
992       HasFullFP16 = true;
993     }
994     if (Feature == "+sme2p1") {
995       HasSME = true;
996       HasSME2 = true;
997       HasSME2p1 = true;
998       HasBFloat16 = true;
999       HasFullFP16 = true;
1000     }
1001     if (Feature == "+sme-f64f64") {
1002       HasSME = true;
1003       HasSMEF64F64 = true;
1004       HasBFloat16 = true;
1005       HasFullFP16 = true;
1006     }
1007     if (Feature == "+sme-i16i64") {
1008       HasSME = true;
1009       HasSMEI16I64 = true;
1010       HasBFloat16 = true;
1011       HasFullFP16 = true;
1012     }
1013     if (Feature == "+sme-fa64") {
1014       FPU |= NeonMode;
1015       FPU |= SveMode;
1016       HasSME = true;
1017       HasSVE2 = true;
1018       HasSMEFA64 = true;
1019     }
1020     if (Feature == "+sme-f16f16") {
1021       HasSME = true;
1022       HasSME2 = true;
1023       HasBFloat16 = true;
1024       HasFullFP16 = true;
1025       HasSMEF16F16 = true;
1026     }
1027     if (Feature == "+sme-b16b16") {
1028       HasSME = true;
1029       HasSME2 = true;
1030       HasBFloat16 = true;
1031       HasFullFP16 = true;
1032       HasSVEB16B16 = true;
1033       HasSMEB16B16 = true;
1034     }
1035 
1036     if (Feature == "+fp8")
1037       HasFP8 = true;
1038     if (Feature == "+fp8fma")
1039       HasFP8FMA = true;
1040     if (Feature == "+fp8dot2")
1041       HasFP8DOT2 = true;
1042     if (Feature == "+fp8dot4")
1043       HasFP8DOT4 = true;
1044     if (Feature == "+ssve-fp8dot2")
1045       HasSSVE_FP8DOT2 = true;
1046     if (Feature == "+ssve-fp8dot4")
1047       HasSSVE_FP8DOT4 = true;
1048     if (Feature == "+ssve-fp8fma")
1049       HasSSVE_FP8FMA = true;
1050     if (Feature == "+sme-f8f32")
1051       HasSME_F8F32 = true;
1052     if (Feature == "+sme-f8f16")
1053       HasSME_F8F16 = true;
1054     if (Feature == "+sb")
1055       HasSB = true;
1056     if (Feature == "+predres")
1057       HasPredRes = true;
1058     if (Feature == "+ssbs")
1059       HasSSBS = true;
1060     if (Feature == "+bti")
1061       HasBTI = true;
1062     if (Feature == "+wfxt")
1063       HasWFxT = true;
1064     if (Feature == "-fmv")
1065       HasFMV = false;
1066     if (Feature == "+crc")
1067       HasCRC = true;
1068     if (Feature == "+rcpc")
1069       HasRCPC = true;
1070     if (Feature == "+aes") {
1071       FPU |= NeonMode;
1072       HasAES = true;
1073     }
1074     if (Feature == "+sha2") {
1075       FPU |= NeonMode;
1076       HasSHA2 = true;
1077     }
1078     if (Feature == "+sha3") {
1079       FPU |= NeonMode;
1080       HasSHA2 = true;
1081       HasSHA3 = true;
1082     }
1083     if (Feature == "+rdm") {
1084       FPU |= NeonMode;
1085       HasRDM = true;
1086     }
1087     if (Feature == "+dit")
1088       HasDIT = true;
1089     if (Feature == "+cccp")
1090       HasCCPP = true;
1091     if (Feature == "+ccdp") {
1092       HasCCPP = true;
1093       HasCCDP = true;
1094     }
1095     if (Feature == "+fptoint")
1096       HasFRInt3264 = true;
1097     if (Feature == "+sm4") {
1098       FPU |= NeonMode;
1099       HasSM4 = true;
1100     }
1101     if (Feature == "+strict-align")
1102       HasUnalignedAccess = false;
1103 
1104     // All predecessor archs are added but select the latest one for ArchKind.
1105     if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
1106       ArchInfo = &llvm::AArch64::ARMV8A;
1107     if (Feature == "+v8.1a" &&
1108         ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
1109       ArchInfo = &llvm::AArch64::ARMV8_1A;
1110     if (Feature == "+v8.2a" &&
1111         ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
1112       ArchInfo = &llvm::AArch64::ARMV8_2A;
1113     if (Feature == "+v8.3a" &&
1114         ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
1115       ArchInfo = &llvm::AArch64::ARMV8_3A;
1116     if (Feature == "+v8.4a" &&
1117         ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
1118       ArchInfo = &llvm::AArch64::ARMV8_4A;
1119     if (Feature == "+v8.5a" &&
1120         ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
1121       ArchInfo = &llvm::AArch64::ARMV8_5A;
1122     if (Feature == "+v8.6a" &&
1123         ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
1124       ArchInfo = &llvm::AArch64::ARMV8_6A;
1125     if (Feature == "+v8.7a" &&
1126         ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
1127       ArchInfo = &llvm::AArch64::ARMV8_7A;
1128     if (Feature == "+v8.8a" &&
1129         ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
1130       ArchInfo = &llvm::AArch64::ARMV8_8A;
1131     if (Feature == "+v8.9a" &&
1132         ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
1133       ArchInfo = &llvm::AArch64::ARMV8_9A;
1134     if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
1135       ArchInfo = &llvm::AArch64::ARMV9A;
1136     if (Feature == "+v9.1a" &&
1137         ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
1138       ArchInfo = &llvm::AArch64::ARMV9_1A;
1139     if (Feature == "+v9.2a" &&
1140         ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
1141       ArchInfo = &llvm::AArch64::ARMV9_2A;
1142     if (Feature == "+v9.3a" &&
1143         ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
1144       ArchInfo = &llvm::AArch64::ARMV9_3A;
1145     if (Feature == "+v9.4a" &&
1146         ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
1147       ArchInfo = &llvm::AArch64::ARMV9_4A;
1148     if (Feature == "+v9.5a" &&
1149         ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
1150       ArchInfo = &llvm::AArch64::ARMV9_5A;
1151     if (Feature == "+v9.6a" &&
1152         ArchInfo->Version < llvm::AArch64::ARMV9_6A.Version)
1153       ArchInfo = &llvm::AArch64::ARMV9_6A;
1154     if (Feature == "+v8r")
1155       ArchInfo = &llvm::AArch64::ARMV8R;
1156     if (Feature == "+fullfp16") {
1157       FPU |= NeonMode;
1158       HasFullFP16 = true;
1159     }
1160     if (Feature == "+dotprod") {
1161       FPU |= NeonMode;
1162       HasDotProd = true;
1163     }
1164     if (Feature == "+fp16fml") {
1165       FPU |= NeonMode;
1166       HasFullFP16 = true;
1167       HasFP16FML = true;
1168     }
1169     if (Feature == "+mte")
1170       HasMTE = true;
1171     if (Feature == "+tme")
1172       HasTME = true;
1173     if (Feature == "+pauth")
1174       HasPAuth = true;
1175     if (Feature == "+i8mm")
1176       HasMatMul = true;
1177     if (Feature == "+bf16")
1178       HasBFloat16 = true;
1179     if (Feature == "+lse")
1180       HasLSE = true;
1181     if (Feature == "+ls64")
1182       HasLS64 = true;
1183     if (Feature == "+rand")
1184       HasRandGen = true;
1185     if (Feature == "+flagm")
1186       HasFlagM = true;
1187     if (Feature == "+altnzcv") {
1188       HasFlagM = true;
1189       HasAlternativeNZCV = true;
1190     }
1191     if (Feature == "+mops")
1192       HasMOPS = true;
1193     if (Feature == "+d128")
1194       HasD128 = true;
1195     if (Feature == "+gcs")
1196       HasGCS = true;
1197     if (Feature == "+rcpc3")
1198       HasRCPC3 = true;
1199     if (Feature == "+pauth-lr") {
1200       HasPAuthLR = true;
1201       HasPAuth = true;
1202     }
1203     if (Feature == "+cssc")
1204       HasCSSC = true;
1205   }
1206 
1207   // Check features that are manually disabled by command line options.
1208   // This needs to be checked after architecture-related features are handled,
1209   // making sure they are properly disabled when required.
1210   for (const auto &Feature : Features) {
1211     if (Feature == "-d128")
1212       HasD128 = false;
1213   }
1214 
1215   setDataLayout();
1216 
1217   if (HasNoFP) {
1218     FPU &= ~FPUMode;
1219     FPU &= ~NeonMode;
1220     FPU &= ~SveMode;
1221   }
1222   if (HasNoNeon) {
1223     FPU &= ~NeonMode;
1224     FPU &= ~SveMode;
1225   }
1226   if (HasNoSVE)
1227     FPU &= ~SveMode;
1228 
1229   return true;
1230 }
1231 
1232 // Parse AArch64 Target attributes, which are a comma separated list of:
1233 //  "arch=<arch>" - parsed to features as per -march=..
1234 //  "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1235 //  "tune=<cpu>" - TuneCPU set to <cpu>
1236 //  "feature", "no-feature" - Add (or remove) feature.
1237 //  "+feature", "+nofeature" - Add (or remove) feature.
1238 //
1239 // A feature may correspond to an Extension (anything with a corresponding
1240 // AEK_), in which case an ExtensionSet is used to parse it and expand its
1241 // dependencies. If the feature does not yield a successful parse then it
1242 // is passed through.
1243 ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1244   ParsedTargetAttr Ret;
1245   if (Features == "default")
1246     return Ret;
1247   SmallVector<StringRef, 1> AttrFeatures;
1248   Features.split(AttrFeatures, ",");
1249   bool FoundArch = false;
1250 
1251   auto SplitAndAddFeatures = [](StringRef FeatString,
1252                                 std::vector<std::string> &Features,
1253                                 llvm::AArch64::ExtensionSet &FeatureBits) {
1254     SmallVector<StringRef, 8> SplitFeatures;
1255     FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1256     for (StringRef Feature : SplitFeatures) {
1257       if (FeatureBits.parseModifier(Feature))
1258         continue;
1259       // Pass through anything that failed to parse so that we can emit
1260       // diagnostics, as well as valid internal feature names.
1261       //
1262       // FIXME: We should consider rejecting internal feature names like
1263       //        neon, v8a, etc.
1264       // FIXME: We should consider emitting diagnostics here.
1265       if (Feature.starts_with("no"))
1266         Features.push_back("-" + Feature.drop_front(2).str());
1267       else
1268         Features.push_back("+" + Feature.str());
1269     }
1270   };
1271 
1272   llvm::AArch64::ExtensionSet FeatureBits;
1273   // Reconstruct the bitset from the command line option features.
1274   FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten,
1275                                             Ret.Features);
1276 
1277   for (auto &Feature : AttrFeatures) {
1278     Feature = Feature.trim();
1279     if (Feature.starts_with("fpmath="))
1280       continue;
1281 
1282     if (Feature.starts_with("branch-protection=")) {
1283       Ret.BranchProtection = Feature.split('=').second.trim();
1284       continue;
1285     }
1286 
1287     if (Feature.starts_with("arch=")) {
1288       if (FoundArch)
1289         Ret.Duplicate = "arch=";
1290       FoundArch = true;
1291       std::pair<StringRef, StringRef> Split =
1292           Feature.split("=").second.trim().split("+");
1293       const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1294 
1295       // Parse the architecture version, adding the required features to
1296       // Ret.Features.
1297       if (!AI)
1298         continue;
1299       FeatureBits.addArchDefaults(*AI);
1300       // Add any extra features, after the +
1301       SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1302     } else if (Feature.starts_with("cpu=")) {
1303       if (!Ret.CPU.empty())
1304         Ret.Duplicate = "cpu=";
1305       else {
1306         // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1307         // "+feat" features.
1308         std::pair<StringRef, StringRef> Split =
1309             Feature.split("=").second.trim().split("+");
1310         Ret.CPU = Split.first;
1311         if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {
1312           FeatureBits.addCPUDefaults(*CpuInfo);
1313           SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1314         }
1315       }
1316     } else if (Feature.starts_with("tune=")) {
1317       if (!Ret.Tune.empty())
1318         Ret.Duplicate = "tune=";
1319       else
1320         Ret.Tune = Feature.split("=").second.trim();
1321     } else if (Feature.starts_with("+")) {
1322       SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);
1323     } else {
1324       if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))
1325         continue;
1326       // Pass through anything that failed to parse so that we can emit
1327       // diagnostics, as well as valid internal feature names.
1328       //
1329       // FIXME: We should consider rejecting internal feature names like
1330       //        neon, v8a, etc.
1331       // FIXME: We should consider emitting diagnostics here.
1332       if (Feature.starts_with("no-"))
1333         Ret.Features.push_back("-" + Feature.drop_front(3).str());
1334       else
1335         Ret.Features.push_back("+" + Feature.str());
1336     }
1337   }
1338   FeatureBits.toLLVMFeatureList(Ret.Features);
1339   return Ret;
1340 }
1341 
1342 bool AArch64TargetInfo::hasBFloat16Type() const {
1343   return true;
1344 }
1345 
1346 TargetInfo::CallingConvCheckResult
1347 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
1348   switch (CC) {
1349   case CC_C:
1350   case CC_Swift:
1351   case CC_SwiftAsync:
1352   case CC_PreserveMost:
1353   case CC_PreserveAll:
1354   case CC_PreserveNone:
1355   case CC_DeviceKernel:
1356   case CC_AArch64VectorCall:
1357   case CC_AArch64SVEPCS:
1358   case CC_Win64:
1359     return CCCR_OK;
1360   default:
1361     return CCCR_Warning;
1362   }
1363 }
1364 
1365 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1366 
1367 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1368   return TargetInfo::AArch64ABIBuiltinVaList;
1369 }
1370 
1371 const char *const AArch64TargetInfo::GCCRegNames[] = {
1372     // clang-format off
1373 
1374     // 32-bit Integer registers
1375     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1376     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1377     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1378 
1379     // 64-bit Integer registers
1380     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1381     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1382     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1383 
1384     // 32-bit floating point regsisters
1385     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1386     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1387     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1388 
1389     // 64-bit floating point regsisters
1390     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1391     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1392     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1393 
1394     // Neon vector registers
1395     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1396     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1397     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1398 
1399     // SVE vector registers
1400     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
1401     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1402     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1403 
1404     // SVE predicate registers
1405     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
1406     "p11", "p12", "p13", "p14", "p15",
1407 
1408     // SVE predicate-as-counter registers
1409     "pn0",  "pn1",  "pn2",  "pn3",  "pn4",  "pn5",  "pn6",  "pn7",  "pn8",
1410     "pn9",  "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
1411 
1412     // SME registers
1413     "za", "zt0",
1414 
1415     // clang-format on
1416 };
1417 
1418 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1419   return llvm::ArrayRef(GCCRegNames);
1420 }
1421 
1422 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1423     {{"w31"}, "wsp"},
1424     {{"x31"}, "sp"},
1425     // GCC rN registers are aliases of xN registers.
1426     {{"r0"}, "x0"},
1427     {{"r1"}, "x1"},
1428     {{"r2"}, "x2"},
1429     {{"r3"}, "x3"},
1430     {{"r4"}, "x4"},
1431     {{"r5"}, "x5"},
1432     {{"r6"}, "x6"},
1433     {{"r7"}, "x7"},
1434     {{"r8"}, "x8"},
1435     {{"r9"}, "x9"},
1436     {{"r10"}, "x10"},
1437     {{"r11"}, "x11"},
1438     {{"r12"}, "x12"},
1439     {{"r13"}, "x13"},
1440     {{"r14"}, "x14"},
1441     {{"r15"}, "x15"},
1442     {{"r16"}, "x16"},
1443     {{"r17"}, "x17"},
1444     {{"r18"}, "x18"},
1445     {{"r19"}, "x19"},
1446     {{"r20"}, "x20"},
1447     {{"r21"}, "x21"},
1448     {{"r22"}, "x22"},
1449     {{"r23"}, "x23"},
1450     {{"r24"}, "x24"},
1451     {{"r25"}, "x25"},
1452     {{"r26"}, "x26"},
1453     {{"r27"}, "x27"},
1454     {{"r28"}, "x28"},
1455     {{"r29", "x29"}, "fp"},
1456     {{"r30", "x30"}, "lr"},
1457     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1458     // don't want to substitute one of these for a different-sized one.
1459 };
1460 
1461 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1462   return llvm::ArrayRef(GCCRegAliases);
1463 }
1464 
1465 // Returns the length of cc constraint.
1466 static unsigned matchAsmCCConstraint(const char *Name) {
1467   constexpr unsigned len = 5;
1468   auto RV = llvm::StringSwitch<unsigned>(Name)
1469                 .Case("@cceq", len)
1470                 .Case("@ccne", len)
1471                 .Case("@cchs", len)
1472                 .Case("@cccs", len)
1473                 .Case("@cccc", len)
1474                 .Case("@cclo", len)
1475                 .Case("@ccmi", len)
1476                 .Case("@ccpl", len)
1477                 .Case("@ccvs", len)
1478                 .Case("@ccvc", len)
1479                 .Case("@cchi", len)
1480                 .Case("@ccls", len)
1481                 .Case("@ccge", len)
1482                 .Case("@cclt", len)
1483                 .Case("@ccgt", len)
1484                 .Case("@ccle", len)
1485                 .Default(0);
1486   return RV;
1487 }
1488 
1489 std::string
1490 AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
1491   std::string R;
1492   switch (*Constraint) {
1493   case 'U': // Three-character constraint; add "@3" hint for later parsing.
1494     R = std::string("@3") + std::string(Constraint, 3);
1495     Constraint += 2;
1496     break;
1497   case '@':
1498     if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
1499       std::string Converted = "{" + std::string(Constraint, Len) + "}";
1500       Constraint += Len - 1;
1501       return Converted;
1502     }
1503     return std::string(1, *Constraint);
1504   default:
1505     R = TargetInfo::convertConstraint(Constraint);
1506     break;
1507   }
1508   return R;
1509 }
1510 
1511 bool AArch64TargetInfo::validateAsmConstraint(
1512     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1513   switch (*Name) {
1514   default:
1515     return false;
1516   case 'w': // Floating point and SIMD registers (V0-V31)
1517     Info.setAllowsRegister();
1518     return true;
1519   case 'I': // Constant that can be used with an ADD instruction
1520   case 'J': // Constant that can be used with a SUB instruction
1521   case 'K': // Constant that can be used with a 32-bit logical instruction
1522   case 'L': // Constant that can be used with a 64-bit logical instruction
1523   case 'M': // Constant that can be used as a 32-bit MOV immediate
1524   case 'N': // Constant that can be used as a 64-bit MOV immediate
1525   case 'Y': // Floating point constant zero
1526   case 'Z': // Integer constant zero
1527     return true;
1528   case 'Q': // A memory reference with base register and no offset
1529     Info.setAllowsMemory();
1530     return true;
1531   case 'S': // A symbolic address
1532     Info.setAllowsRegister();
1533     return true;
1534   case 'U':
1535     if (Name[1] == 'p' &&
1536         (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
1537       // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
1538       Info.setAllowsRegister();
1539       Name += 2;
1540       return true;
1541     }
1542     if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
1543       // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
1544       Info.setAllowsRegister();
1545       Name += 2;
1546       return true;
1547     }
1548     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1549     // Utf: A memory address suitable for ldp/stp in TF mode.
1550     // Usa: An absolute symbolic address.
1551     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1552 
1553     // Better to return an error saying that it's an unrecognised constraint
1554     // even if this is a valid constraint in gcc.
1555     return false;
1556   case 'z': // Zero register, wzr or xzr
1557     Info.setAllowsRegister();
1558     return true;
1559   case 'x': // Floating point and SIMD registers (V0-V15)
1560     Info.setAllowsRegister();
1561     return true;
1562   case 'y': // SVE registers (V0-V7)
1563     Info.setAllowsRegister();
1564     return true;
1565   case '@':
1566     // CC condition
1567     if (const unsigned Len = matchAsmCCConstraint(Name)) {
1568       Name += Len - 1;
1569       Info.setAllowsRegister();
1570       return true;
1571     }
1572   }
1573   return false;
1574 }
1575 
1576 bool AArch64TargetInfo::validateConstraintModifier(
1577     StringRef Constraint, char Modifier, unsigned Size,
1578     std::string &SuggestedModifier) const {
1579   // Strip off constraint modifiers.
1580   Constraint = Constraint.ltrim("=+&");
1581 
1582   switch (Constraint[0]) {
1583   default:
1584     return true;
1585   case 'z':
1586   case 'r': {
1587     switch (Modifier) {
1588     case 'x':
1589     case 'w':
1590       // For now assume that the person knows what they're
1591       // doing with the modifier.
1592       return true;
1593     default:
1594       // By default an 'r' constraint will be in the 'x'
1595       // registers.
1596       if (Size == 64)
1597         return true;
1598 
1599       if (Size == 512)
1600         return HasLS64;
1601 
1602       SuggestedModifier = "w";
1603       return false;
1604     }
1605   }
1606   }
1607 }
1608 
1609 std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1610 
1611 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1612   if (RegNo == 0)
1613     return 0;
1614   if (RegNo == 1)
1615     return 1;
1616   return -1;
1617 }
1618 
1619 bool AArch64TargetInfo::validatePointerAuthKey(
1620     const llvm::APSInt &value) const {
1621   return 0 <= value && value <= 3;
1622 }
1623 
1624 bool AArch64TargetInfo::hasInt128Type() const { return true; }
1625 
1626 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1627                                          const TargetOptions &Opts)
1628     : AArch64TargetInfo(Triple, Opts) {}
1629 
1630 void AArch64leTargetInfo::setDataLayout() {
1631   if (getTriple().isOSBinFormatMachO()) {
1632     if(getTriple().isArch32Bit())
1633       resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
1634                       "i128:128-n32:64-S128-Fn32",
1635                       "_");
1636     else
1637       resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
1638                       "n32:64-S128-Fn32",
1639                       "_");
1640   } else
1641     resetDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-"
1642                     "i64:64-i128:128-n32:64-S128-Fn32");
1643 }
1644 
1645 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1646                                            MacroBuilder &Builder) const {
1647   Builder.defineMacro("__AARCH64EL__");
1648   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1649 }
1650 
1651 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1652                                          const TargetOptions &Opts)
1653     : AArch64TargetInfo(Triple, Opts) {}
1654 
1655 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
1656                                            MacroBuilder &Builder) const {
1657   Builder.defineMacro("__AARCH64EB__");
1658   Builder.defineMacro("__AARCH_BIG_ENDIAN");
1659   Builder.defineMacro("__ARM_BIG_ENDIAN");
1660   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1661 }
1662 
1663 void AArch64beTargetInfo::setDataLayout() {
1664   assert(!getTriple().isOSBinFormatMachO());
1665   resetDataLayout("E-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-"
1666                   "i64:64-i128:128-n32:64-S128-Fn32");
1667 }
1668 
1669 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
1670                                                const TargetOptions &Opts)
1671     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1672 
1673   // This is an LLP64 platform.
1674   // int:4, long:4, long long:8, long double:8.
1675   IntWidth = IntAlign = 32;
1676   LongWidth = LongAlign = 32;
1677   DoubleAlign = LongLongAlign = 64;
1678   LongDoubleWidth = LongDoubleAlign = 64;
1679   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1680   IntMaxType = SignedLongLong;
1681   Int64Type = SignedLongLong;
1682   SizeType = UnsignedLongLong;
1683   PtrDiffType = SignedLongLong;
1684   IntPtrType = SignedLongLong;
1685 }
1686 
1687 void WindowsARM64TargetInfo::setDataLayout() {
1688   resetDataLayout(Triple.isOSBinFormatMachO()
1689                       ? "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:"
1690                         "128-n32:64-S128-Fn32"
1691                       : "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-"
1692                         "i64:64-i128:128-n32:64-S128-Fn32",
1693                   Triple.isOSBinFormatMachO() ? "_" : "");
1694 }
1695 
1696 TargetInfo::BuiltinVaListKind
1697 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1698   return TargetInfo::CharPtrBuiltinVaList;
1699 }
1700 
1701 TargetInfo::CallingConvCheckResult
1702 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
1703   switch (CC) {
1704   case CC_X86VectorCall:
1705     if (getTriple().isWindowsArm64EC())
1706       return CCCR_OK;
1707     return CCCR_Ignore;
1708   case CC_X86StdCall:
1709   case CC_X86ThisCall:
1710   case CC_X86FastCall:
1711     return CCCR_Ignore;
1712   case CC_C:
1713   case CC_DeviceKernel:
1714   case CC_PreserveMost:
1715   case CC_PreserveAll:
1716   case CC_PreserveNone:
1717   case CC_Swift:
1718   case CC_SwiftAsync:
1719   case CC_Win64:
1720     return CCCR_OK;
1721   default:
1722     return CCCR_Warning;
1723   }
1724 }
1725 
1726 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1727                                                    const TargetOptions &Opts)
1728     : WindowsARM64TargetInfo(Triple, Opts) {
1729   TheCXXABI.set(TargetCXXABI::Microsoft);
1730 }
1731 
1732 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
1733                                                 MacroBuilder &Builder) const {
1734   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
1735   if (getTriple().isWindowsArm64EC()) {
1736     Builder.defineMacro("_M_X64", "100");
1737     Builder.defineMacro("_M_AMD64", "100");
1738     Builder.defineMacro("_M_ARM64EC", "1");
1739   } else {
1740     Builder.defineMacro("_M_ARM64", "1");
1741   }
1742 }
1743 
1744 TargetInfo::CallingConvKind
1745 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1746   return CCK_MicrosoftWin64;
1747 }
1748 
1749 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize,
1750                                                      bool HasNonWeakDef) const {
1751   unsigned Align =
1752       WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
1753 
1754   // MSVC does size based alignment for arm64 based on alignment section in
1755   // below document, replicate that to keep alignment consistent with object
1756   // files compiled by MSVC.
1757   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
1758   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
1759     Align = std::max(Align, 128u);    // align type at least 16 bytes
1760   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
1761     Align = std::max(Align, 64u);     // align type at least 8 butes
1762   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
1763     Align = std::max(Align, 32u);     // align type at least 4 bytes
1764   }
1765   return Align;
1766 }
1767 
1768 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1769                                            const TargetOptions &Opts)
1770     : WindowsARM64TargetInfo(Triple, Opts) {
1771   TheCXXABI.set(TargetCXXABI::GenericAArch64);
1772 }
1773 
1774 AppleMachOAArch64TargetInfo::AppleMachOAArch64TargetInfo(
1775     const llvm::Triple &Triple, const TargetOptions &Opts)
1776     : AppleMachOTargetInfo<AArch64leTargetInfo>(Triple, Opts) {}
1777 
1778 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1779                                                  const TargetOptions &Opts)
1780     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1781   Int64Type = SignedLongLong;
1782   if (getTriple().isArch32Bit())
1783     IntMaxType = SignedLongLong;
1784 
1785   WCharType = SignedInt;
1786   UseSignedCharForObjCBool = false;
1787 
1788   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1789   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1790 
1791   UseZeroLengthBitfieldAlignment = false;
1792 
1793   if (getTriple().isArch32Bit()) {
1794     UseBitFieldTypeAlignment = false;
1795     ZeroLengthBitfieldBoundary = 32;
1796     UseZeroLengthBitfieldAlignment = true;
1797     TheCXXABI.set(TargetCXXABI::WatchOS);
1798   } else
1799     TheCXXABI.set(TargetCXXABI::AppleARM64);
1800 }
1801 
1802 void clang::targets::getAppleMachOAArch64Defines(MacroBuilder &Builder,
1803                                                  const LangOptions &Opts,
1804                                                  const llvm::Triple &Triple) {
1805   Builder.defineMacro("__AARCH64_SIMD__");
1806   if (Triple.isArch32Bit())
1807     Builder.defineMacro("__ARM64_ARCH_8_32__");
1808   else
1809     Builder.defineMacro("__ARM64_ARCH_8__");
1810   Builder.defineMacro("__ARM_NEON__");
1811   Builder.defineMacro("__REGISTER_PREFIX__", "");
1812   Builder.defineMacro("__arm64", "1");
1813   Builder.defineMacro("__arm64__", "1");
1814 
1815   if (Triple.isArm64e())
1816     Builder.defineMacro("__arm64e__", "1");
1817 }
1818 
1819 void AppleMachOAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1820                                                const llvm::Triple &Triple,
1821                                                MacroBuilder &Builder) const {
1822   getAppleMachOAArch64Defines(Builder, Opts, Triple);
1823   AppleMachOTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple,
1824                                                           Builder);
1825 }
1826 
1827 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1828                                            const llvm::Triple &Triple,
1829                                            MacroBuilder &Builder) const {
1830   getAppleMachOAArch64Defines(Builder, Opts, Triple);
1831   DarwinTargetInfo<AArch64leTargetInfo>::getOSDefines(Opts, Triple, Builder);
1832 }
1833 
1834 TargetInfo::BuiltinVaListKind
1835 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1836   return TargetInfo::CharPtrBuiltinVaList;
1837 }
1838