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