xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/AArch64.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements AArch64 TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "AArch64.h"
14ec727ea7Spatrick #include "clang/Basic/LangOptions.h"
15e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
16e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
17e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
18e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
19e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
20e5dd7070Spatrick #include "llvm/Support/AArch64TargetParser.h"
21*12c85518Srobert #include "llvm/Support/ARMTargetParserCommon.h"
22*12c85518Srobert #include <optional>
23e5dd7070Spatrick 
24e5dd7070Spatrick using namespace clang;
25e5dd7070Spatrick using namespace clang::targets;
26e5dd7070Spatrick 
27*12c85518Srobert static constexpr Builtin::Info BuiltinInfo[] = {
28e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
29*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
30*12c85518Srobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
31*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
32e5dd7070Spatrick #include "clang/Basic/BuiltinsNEON.def"
33e5dd7070Spatrick 
34e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
35*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
36*12c85518Srobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
37*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
38ec727ea7Spatrick #include "clang/Basic/BuiltinsSVE.def"
39ec727ea7Spatrick 
40ec727ea7Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
41*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
42e5dd7070Spatrick #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
43*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
44*12c85518Srobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
45*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
46e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
47*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
48e5dd7070Spatrick #include "clang/Basic/BuiltinsAArch64.def"
49e5dd7070Spatrick };
50e5dd7070Spatrick 
setArchFeatures()51*12c85518Srobert void AArch64TargetInfo::setArchFeatures() {
52*12c85518Srobert   if (*ArchInfo == llvm::AArch64::ARMV8R) {
53*12c85518Srobert     HasDotProd = true;
54*12c85518Srobert     HasDIT = true;
55*12c85518Srobert     HasFlagM = true;
56*12c85518Srobert     HasRCPC = true;
57*12c85518Srobert     FPU |= NeonMode;
58*12c85518Srobert     HasCCPP = true;
59*12c85518Srobert     HasCRC = true;
60*12c85518Srobert     HasLSE = true;
61*12c85518Srobert     HasRDM = true;
62*12c85518Srobert   } else if (ArchInfo->Version.getMajor() == 8) {
63*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 7u) {
64*12c85518Srobert       HasWFxT = true;
65*12c85518Srobert     }
66*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 6u) {
67*12c85518Srobert       HasBFloat16 = true;
68*12c85518Srobert       HasMatMul = true;
69*12c85518Srobert     }
70*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 5u) {
71*12c85518Srobert       HasAlternativeNZCV = true;
72*12c85518Srobert       HasFRInt3264 = true;
73*12c85518Srobert       HasSSBS = true;
74*12c85518Srobert       HasSB = true;
75*12c85518Srobert       HasPredRes = true;
76*12c85518Srobert       HasBTI = true;
77*12c85518Srobert     }
78*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 4u) {
79*12c85518Srobert       HasDotProd = true;
80*12c85518Srobert       HasDIT = true;
81*12c85518Srobert       HasFlagM = true;
82*12c85518Srobert     }
83*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 3u) {
84*12c85518Srobert       HasRCPC = true;
85*12c85518Srobert       FPU |= NeonMode;
86*12c85518Srobert     }
87*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 2u) {
88*12c85518Srobert       HasCCPP = true;
89*12c85518Srobert     }
90*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 1u) {
91*12c85518Srobert       HasCRC = true;
92*12c85518Srobert       HasLSE = true;
93*12c85518Srobert       HasRDM = true;
94*12c85518Srobert     }
95*12c85518Srobert   } else if (ArchInfo->Version.getMajor() == 9) {
96*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 2u) {
97*12c85518Srobert       HasWFxT = true;
98*12c85518Srobert     }
99*12c85518Srobert     if (ArchInfo->Version.getMinor() >= 1u) {
100*12c85518Srobert       HasBFloat16 = true;
101*12c85518Srobert       HasMatMul = true;
102*12c85518Srobert     }
103*12c85518Srobert     FPU |= SveMode;
104*12c85518Srobert     HasSVE2 = true;
105*12c85518Srobert     HasFullFP16 = true;
106*12c85518Srobert     HasAlternativeNZCV = true;
107*12c85518Srobert     HasFRInt3264 = true;
108*12c85518Srobert     HasSSBS = true;
109*12c85518Srobert     HasSB = true;
110*12c85518Srobert     HasPredRes = true;
111*12c85518Srobert     HasBTI = true;
112*12c85518Srobert     HasDotProd = true;
113*12c85518Srobert     HasDIT = true;
114*12c85518Srobert     HasFlagM = true;
115*12c85518Srobert     HasRCPC = true;
116*12c85518Srobert     FPU |= NeonMode;
117*12c85518Srobert     HasCCPP = true;
118*12c85518Srobert     HasCRC = true;
119*12c85518Srobert     HasLSE = true;
120*12c85518Srobert     HasRDM = true;
121*12c85518Srobert   }
122*12c85518Srobert }
123*12c85518Srobert 
AArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)124e5dd7070Spatrick AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
125e5dd7070Spatrick                                      const TargetOptions &Opts)
126e5dd7070Spatrick     : TargetInfo(Triple), ABI("aapcs") {
127e5dd7070Spatrick   if (getTriple().isOSOpenBSD()) {
128e5dd7070Spatrick     Int64Type = SignedLongLong;
129e5dd7070Spatrick     IntMaxType = SignedLongLong;
130e5dd7070Spatrick   } else {
131e5dd7070Spatrick     if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
132e5dd7070Spatrick       WCharType = UnsignedInt;
133e5dd7070Spatrick 
134e5dd7070Spatrick     Int64Type = SignedLong;
135e5dd7070Spatrick     IntMaxType = SignedLong;
136e5dd7070Spatrick   }
137e5dd7070Spatrick 
138e5dd7070Spatrick   // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
139e5dd7070Spatrick   HasLegalHalfType = true;
140*12c85518Srobert   HalfArgsAndReturns = true;
141e5dd7070Spatrick   HasFloat16 = true;
142*12c85518Srobert   HasStrictFP = true;
143e5dd7070Spatrick 
144e5dd7070Spatrick   if (Triple.isArch64Bit())
145e5dd7070Spatrick     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
146e5dd7070Spatrick   else
147e5dd7070Spatrick     LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
148e5dd7070Spatrick 
149e5dd7070Spatrick   MaxVectorAlign = 128;
150e5dd7070Spatrick   MaxAtomicInlineWidth = 128;
151e5dd7070Spatrick   MaxAtomicPromoteWidth = 128;
152e5dd7070Spatrick 
153e5dd7070Spatrick   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
154e5dd7070Spatrick   LongDoubleFormat = &llvm::APFloat::IEEEquad();
155e5dd7070Spatrick 
156ec727ea7Spatrick   BFloat16Width = BFloat16Align = 16;
157ec727ea7Spatrick   BFloat16Format = &llvm::APFloat::BFloat();
158ec727ea7Spatrick 
159e5dd7070Spatrick   // Make __builtin_ms_va_list available.
160e5dd7070Spatrick   HasBuiltinMSVaList = true;
161e5dd7070Spatrick 
162e5dd7070Spatrick   // Make the SVE types available.  Note that this deliberately doesn't
163e5dd7070Spatrick   // depend on SveMode, since in principle it should be possible to turn
164e5dd7070Spatrick   // SVE on and off within a translation unit.  It should also be possible
165e5dd7070Spatrick   // to compile the global declaration:
166e5dd7070Spatrick   //
167e5dd7070Spatrick   // __SVInt8_t *ptr;
168e5dd7070Spatrick   //
169e5dd7070Spatrick   // even without SVE.
170e5dd7070Spatrick   HasAArch64SVETypes = true;
171e5dd7070Spatrick 
172e5dd7070Spatrick   // {} in inline assembly are neon specifiers, not assembly variant
173e5dd7070Spatrick   // specifiers.
174e5dd7070Spatrick   NoAsmVariants = true;
175e5dd7070Spatrick 
176e5dd7070Spatrick   // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
177e5dd7070Spatrick   // contributes to the alignment of the containing aggregate in the same way
178e5dd7070Spatrick   // a plain (non bit-field) member of that type would, without exception for
179e5dd7070Spatrick   // zero-sized or anonymous bit-fields."
180e5dd7070Spatrick   assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
181e5dd7070Spatrick   UseZeroLengthBitfieldAlignment = true;
182e5dd7070Spatrick 
183e5dd7070Spatrick   // AArch64 targets default to using the ARM C++ ABI.
184e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::GenericAArch64);
185e5dd7070Spatrick 
186e5dd7070Spatrick   if (Triple.getOS() == llvm::Triple::Linux)
187e5dd7070Spatrick     this->MCountName = "\01_mcount";
188e5dd7070Spatrick   else if (Triple.getOS() == llvm::Triple::UnknownOS)
189e5dd7070Spatrick     this->MCountName =
190e5dd7070Spatrick         Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
191e5dd7070Spatrick }
192e5dd7070Spatrick 
getABI() const193e5dd7070Spatrick StringRef AArch64TargetInfo::getABI() const { return ABI; }
194e5dd7070Spatrick 
setABI(const std::string & Name)195e5dd7070Spatrick bool AArch64TargetInfo::setABI(const std::string &Name) {
196e5dd7070Spatrick   if (Name != "aapcs" && Name != "darwinpcs")
197e5dd7070Spatrick     return false;
198e5dd7070Spatrick 
199e5dd7070Spatrick   ABI = Name;
200e5dd7070Spatrick   return true;
201e5dd7070Spatrick }
202e5dd7070Spatrick 
validateBranchProtection(StringRef Spec,StringRef,BranchProtectionInfo & BPI,StringRef & Err) const203*12c85518Srobert bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
204e5dd7070Spatrick                                                  BranchProtectionInfo &BPI,
205e5dd7070Spatrick                                                  StringRef &Err) const {
206*12c85518Srobert   llvm::ARM::ParsedBranchProtection PBP;
207*12c85518Srobert   if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
208e5dd7070Spatrick     return false;
209e5dd7070Spatrick 
210e5dd7070Spatrick   BPI.SignReturnAddr =
211ec727ea7Spatrick       llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
212ec727ea7Spatrick           .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
213ec727ea7Spatrick           .Case("all", LangOptions::SignReturnAddressScopeKind::All)
214ec727ea7Spatrick           .Default(LangOptions::SignReturnAddressScopeKind::None);
215e5dd7070Spatrick 
216e5dd7070Spatrick   if (PBP.Key == "a_key")
217ec727ea7Spatrick     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
218e5dd7070Spatrick   else
219ec727ea7Spatrick     BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
220e5dd7070Spatrick 
221e5dd7070Spatrick   BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
222e5dd7070Spatrick   return true;
223e5dd7070Spatrick }
224e5dd7070Spatrick 
isValidCPUName(StringRef Name) const225e5dd7070Spatrick bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
226e5dd7070Spatrick   return Name == "generic" ||
227*12c85518Srobert          llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID;
228e5dd7070Spatrick }
229e5dd7070Spatrick 
setCPU(const std::string & Name)230e5dd7070Spatrick bool AArch64TargetInfo::setCPU(const std::string &Name) {
231e5dd7070Spatrick   return isValidCPUName(Name);
232e5dd7070Spatrick }
233e5dd7070Spatrick 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const234e5dd7070Spatrick void AArch64TargetInfo::fillValidCPUList(
235e5dd7070Spatrick     SmallVectorImpl<StringRef> &Values) const {
236e5dd7070Spatrick   llvm::AArch64::fillValidCPUArchList(Values);
237e5dd7070Spatrick }
238e5dd7070Spatrick 
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const239e5dd7070Spatrick void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
240e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
241e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
242a9ac8606Spatrick   Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
243a9ac8606Spatrick   Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
244e5dd7070Spatrick }
245e5dd7070Spatrick 
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const246e5dd7070Spatrick void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
247e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
248e5dd7070Spatrick   // Also include the ARMv8.1 defines
249e5dd7070Spatrick   getTargetDefinesARMV81A(Opts, Builder);
250e5dd7070Spatrick }
251e5dd7070Spatrick 
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const252e5dd7070Spatrick void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
253e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
254e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
255e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
256*12c85518Srobert   Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
257e5dd7070Spatrick   // Also include the Armv8.2 defines
258e5dd7070Spatrick   getTargetDefinesARMV82A(Opts, Builder);
259e5dd7070Spatrick }
260e5dd7070Spatrick 
getTargetDefinesARMV84A(const LangOptions & Opts,MacroBuilder & Builder) const261e5dd7070Spatrick void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
262e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
263e5dd7070Spatrick   // Also include the Armv8.3 defines
264e5dd7070Spatrick   getTargetDefinesARMV83A(Opts, Builder);
265e5dd7070Spatrick }
266e5dd7070Spatrick 
getTargetDefinesARMV85A(const LangOptions & Opts,MacroBuilder & Builder) const267e5dd7070Spatrick void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
268e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
269a9ac8606Spatrick   Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
270*12c85518Srobert   Builder.defineMacro("__ARM_FEATURE_BTI", "1");
271e5dd7070Spatrick   // Also include the Armv8.4 defines
272e5dd7070Spatrick   getTargetDefinesARMV84A(Opts, Builder);
273e5dd7070Spatrick }
274e5dd7070Spatrick 
getTargetDefinesARMV86A(const LangOptions & Opts,MacroBuilder & Builder) const275ec727ea7Spatrick void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
276ec727ea7Spatrick                                                 MacroBuilder &Builder) const {
277ec727ea7Spatrick   // Also include the Armv8.5 defines
278ec727ea7Spatrick   // FIXME: Armv8.6 makes the following extensions mandatory:
279ec727ea7Spatrick   // - __ARM_FEATURE_BF16
280ec727ea7Spatrick   // - __ARM_FEATURE_MATMUL_INT8
281ec727ea7Spatrick   // Handle them here.
282ec727ea7Spatrick   getTargetDefinesARMV85A(Opts, Builder);
283ec727ea7Spatrick }
284e5dd7070Spatrick 
getTargetDefinesARMV87A(const LangOptions & Opts,MacroBuilder & Builder) const285a9ac8606Spatrick void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
286a9ac8606Spatrick                                                 MacroBuilder &Builder) const {
287a9ac8606Spatrick   // Also include the Armv8.6 defines
288a9ac8606Spatrick   getTargetDefinesARMV86A(Opts, Builder);
289a9ac8606Spatrick }
290a9ac8606Spatrick 
getTargetDefinesARMV88A(const LangOptions & Opts,MacroBuilder & Builder) const291*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
292*12c85518Srobert                                                 MacroBuilder &Builder) const {
293*12c85518Srobert   // Also include the Armv8.7 defines
294*12c85518Srobert   getTargetDefinesARMV87A(Opts, Builder);
295*12c85518Srobert }
296*12c85518Srobert 
getTargetDefinesARMV89A(const LangOptions & Opts,MacroBuilder & Builder) const297*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
298*12c85518Srobert                                                 MacroBuilder &Builder) const {
299*12c85518Srobert   // Also include the Armv8.8 defines
300*12c85518Srobert   getTargetDefinesARMV88A(Opts, Builder);
301*12c85518Srobert }
302*12c85518Srobert 
getTargetDefinesARMV9A(const LangOptions & Opts,MacroBuilder & Builder) const303*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
304*12c85518Srobert                                                MacroBuilder &Builder) const {
305*12c85518Srobert   // Armv9-A maps to Armv8.5-A
306*12c85518Srobert   getTargetDefinesARMV85A(Opts, Builder);
307*12c85518Srobert }
308*12c85518Srobert 
getTargetDefinesARMV91A(const LangOptions & Opts,MacroBuilder & Builder) const309*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
310*12c85518Srobert                                                 MacroBuilder &Builder) const {
311*12c85518Srobert   // Armv9.1-A maps to Armv8.6-A
312*12c85518Srobert   getTargetDefinesARMV86A(Opts, Builder);
313*12c85518Srobert }
314*12c85518Srobert 
getTargetDefinesARMV92A(const LangOptions & Opts,MacroBuilder & Builder) const315*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
316*12c85518Srobert                                                 MacroBuilder &Builder) const {
317*12c85518Srobert   // Armv9.2-A maps to Armv8.7-A
318*12c85518Srobert   getTargetDefinesARMV87A(Opts, Builder);
319*12c85518Srobert }
320*12c85518Srobert 
getTargetDefinesARMV93A(const LangOptions & Opts,MacroBuilder & Builder) const321*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
322*12c85518Srobert                                                 MacroBuilder &Builder) const {
323*12c85518Srobert   // Armv9.3-A maps to Armv8.8-A
324*12c85518Srobert   getTargetDefinesARMV88A(Opts, Builder);
325*12c85518Srobert }
326*12c85518Srobert 
getTargetDefinesARMV94A(const LangOptions & Opts,MacroBuilder & Builder) const327*12c85518Srobert void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
328*12c85518Srobert                                                 MacroBuilder &Builder) const {
329*12c85518Srobert   // Armv9.4-A maps to Armv8.9-A
330*12c85518Srobert   getTargetDefinesARMV89A(Opts, Builder);
331*12c85518Srobert }
332*12c85518Srobert 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const333e5dd7070Spatrick void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
334e5dd7070Spatrick                                          MacroBuilder &Builder) const {
335e5dd7070Spatrick   // Target identification.
336e5dd7070Spatrick   Builder.defineMacro("__aarch64__");
337e5dd7070Spatrick   // For bare-metal.
338e5dd7070Spatrick   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
339e5dd7070Spatrick       getTriple().isOSBinFormatELF())
340e5dd7070Spatrick     Builder.defineMacro("__ELF__");
341e5dd7070Spatrick 
342e5dd7070Spatrick   // Target properties.
343e5dd7070Spatrick   if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
344e5dd7070Spatrick     Builder.defineMacro("_LP64");
345e5dd7070Spatrick     Builder.defineMacro("__LP64__");
346e5dd7070Spatrick   }
347e5dd7070Spatrick 
348ec727ea7Spatrick   std::string CodeModel = getTargetOpts().CodeModel;
349ec727ea7Spatrick   if (CodeModel == "default")
350ec727ea7Spatrick     CodeModel = "small";
351ec727ea7Spatrick   for (char &c : CodeModel)
352ec727ea7Spatrick     c = toupper(c);
353ec727ea7Spatrick   Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
354ec727ea7Spatrick 
355e5dd7070Spatrick   // ACLE predefines. Many can only have one possible value on v8 AArch64.
356e5dd7070Spatrick   Builder.defineMacro("__ARM_ACLE", "200");
357*12c85518Srobert   Builder.defineMacro("__ARM_ARCH",
358*12c85518Srobert                       std::to_string(ArchInfo->Version.getMajor()));
359*12c85518Srobert   Builder.defineMacro("__ARM_ARCH_PROFILE",
360*12c85518Srobert                       std::string("'") + (char)ArchInfo->Profile + "'");
361e5dd7070Spatrick 
362e5dd7070Spatrick   Builder.defineMacro("__ARM_64BIT_STATE", "1");
363e5dd7070Spatrick   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
364e5dd7070Spatrick   Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
365e5dd7070Spatrick 
366e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
367e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_FMA", "1");
368e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
369e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
370e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_DIV");       // For backwards compatibility
371e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
372e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
373e5dd7070Spatrick 
374e5dd7070Spatrick   Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
375e5dd7070Spatrick 
376e5dd7070Spatrick   // 0xe implies support for half, single and double precision operations.
377e5dd7070Spatrick   Builder.defineMacro("__ARM_FP", "0xE");
378e5dd7070Spatrick 
379e5dd7070Spatrick   // PCS specifies this for SysV variants, which is all we support. Other ABIs
380e5dd7070Spatrick   // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
381e5dd7070Spatrick   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
382e5dd7070Spatrick   Builder.defineMacro("__ARM_FP16_ARGS", "1");
383e5dd7070Spatrick 
384e5dd7070Spatrick   if (Opts.UnsafeFPMath)
385e5dd7070Spatrick     Builder.defineMacro("__ARM_FP_FAST", "1");
386e5dd7070Spatrick 
387e5dd7070Spatrick   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
388e5dd7070Spatrick                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
389e5dd7070Spatrick 
390e5dd7070Spatrick   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
391e5dd7070Spatrick 
392e5dd7070Spatrick   if (FPU & NeonMode) {
393e5dd7070Spatrick     Builder.defineMacro("__ARM_NEON", "1");
394e5dd7070Spatrick     // 64-bit NEON supports half, single and double precision operations.
395e5dd7070Spatrick     Builder.defineMacro("__ARM_NEON_FP", "0xE");
396e5dd7070Spatrick   }
397e5dd7070Spatrick 
398ec727ea7Spatrick   if (FPU & SveMode)
399ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE", "1");
400ec727ea7Spatrick 
401*12c85518Srobert   if ((FPU & NeonMode) && (FPU & SveMode))
402*12c85518Srobert     Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
403*12c85518Srobert 
404ec727ea7Spatrick   if (HasSVE2)
405ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
406ec727ea7Spatrick 
407ec727ea7Spatrick   if (HasSVE2 && HasSVE2AES)
408ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
409ec727ea7Spatrick 
410ec727ea7Spatrick   if (HasSVE2 && HasSVE2BitPerm)
411ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
412ec727ea7Spatrick 
413ec727ea7Spatrick   if (HasSVE2 && HasSVE2SHA3)
414ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
415ec727ea7Spatrick 
416ec727ea7Spatrick   if (HasSVE2 && HasSVE2SM4)
417ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
418ec727ea7Spatrick 
419e5dd7070Spatrick   if (HasCRC)
420e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
421e5dd7070Spatrick 
422*12c85518Srobert   if (HasRCPC)
423*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
424*12c85518Srobert 
425*12c85518Srobert   if (HasFMV)
426*12c85518Srobert     Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
427*12c85518Srobert 
428a9ac8606Spatrick   // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
429a9ac8606Spatrick   // macros for AES, SHA2, SHA3 and SM4
430a9ac8606Spatrick   if (HasAES && HasSHA2)
431e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
432e5dd7070Spatrick 
433a9ac8606Spatrick   if (HasAES)
434a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_AES", "1");
435a9ac8606Spatrick 
436a9ac8606Spatrick   if (HasSHA2)
437a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
438a9ac8606Spatrick 
439a9ac8606Spatrick   if (HasSHA3) {
440a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
441a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
442a9ac8606Spatrick   }
443a9ac8606Spatrick 
444a9ac8606Spatrick   if (HasSM4) {
445a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_SM3", "1");
446a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_SM4", "1");
447a9ac8606Spatrick   }
448a9ac8606Spatrick 
449*12c85518Srobert   if (HasPAuth)
450*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
451*12c85518Srobert 
452e5dd7070Spatrick   if (HasUnaligned)
453e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
454e5dd7070Spatrick 
455e5dd7070Spatrick   if ((FPU & NeonMode) && HasFullFP16)
456e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
457e5dd7070Spatrick   if (HasFullFP16)
458e5dd7070Spatrick    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
459e5dd7070Spatrick 
460e5dd7070Spatrick   if (HasDotProd)
461e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
462e5dd7070Spatrick 
463e5dd7070Spatrick   if (HasMTE)
464e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
465e5dd7070Spatrick 
466e5dd7070Spatrick   if (HasTME)
467e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_TME", "1");
468e5dd7070Spatrick 
469ec727ea7Spatrick   if (HasMatMul)
470ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
471ec727ea7Spatrick 
472a9ac8606Spatrick   if (HasLSE)
473a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
474a9ac8606Spatrick 
475ec727ea7Spatrick   if (HasBFloat16) {
476ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BF16", "1");
477ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
478ec727ea7Spatrick     Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
479ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
480ec727ea7Spatrick   }
481ec727ea7Spatrick 
482ec727ea7Spatrick   if ((FPU & SveMode) && HasBFloat16) {
483ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
484ec727ea7Spatrick   }
485ec727ea7Spatrick 
486ec727ea7Spatrick   if ((FPU & SveMode) && HasMatmulFP64)
487ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
488ec727ea7Spatrick 
489ec727ea7Spatrick   if ((FPU & SveMode) && HasMatmulFP32)
490ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
491ec727ea7Spatrick 
492ec727ea7Spatrick   if ((FPU & SveMode) && HasMatMul)
493ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
494ec727ea7Spatrick 
495e5dd7070Spatrick   if ((FPU & NeonMode) && HasFP16FML)
496a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
497e5dd7070Spatrick 
498ec727ea7Spatrick   if (Opts.hasSignReturnAddress()) {
499ec727ea7Spatrick     // Bitmask:
500ec727ea7Spatrick     // 0: Protection using the A key
501ec727ea7Spatrick     // 1: Protection using the B key
502ec727ea7Spatrick     // 2: Protection including leaf functions
503ec727ea7Spatrick     unsigned Value = 0;
504ec727ea7Spatrick 
505ec727ea7Spatrick     if (Opts.isSignReturnAddressWithAKey())
506ec727ea7Spatrick       Value |= (1 << 0);
507ec727ea7Spatrick     else
508ec727ea7Spatrick       Value |= (1 << 1);
509ec727ea7Spatrick 
510ec727ea7Spatrick     if (Opts.isSignReturnAddressScopeAll())
511ec727ea7Spatrick       Value |= (1 << 2);
512ec727ea7Spatrick 
513ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
514ec727ea7Spatrick   }
515ec727ea7Spatrick 
516ec727ea7Spatrick   if (Opts.BranchTargetEnforcement)
517ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
518ec727ea7Spatrick 
519a9ac8606Spatrick   if (HasLS64)
520a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_LS64", "1");
521a9ac8606Spatrick 
522a9ac8606Spatrick   if (HasRandGen)
523a9ac8606Spatrick     Builder.defineMacro("__ARM_FEATURE_RNG", "1");
524a9ac8606Spatrick 
525*12c85518Srobert   if (HasMOPS)
526*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
527*12c85518Srobert 
528*12c85518Srobert   if (HasD128)
529*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
530*12c85518Srobert 
531*12c85518Srobert   if (*ArchInfo == llvm::AArch64::ARMV8_1A)
532e5dd7070Spatrick     getTargetDefinesARMV81A(Opts, Builder);
533*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
534e5dd7070Spatrick     getTargetDefinesARMV82A(Opts, Builder);
535*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
536e5dd7070Spatrick     getTargetDefinesARMV83A(Opts, Builder);
537*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
538e5dd7070Spatrick     getTargetDefinesARMV84A(Opts, Builder);
539*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
540e5dd7070Spatrick     getTargetDefinesARMV85A(Opts, Builder);
541*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
542ec727ea7Spatrick     getTargetDefinesARMV86A(Opts, Builder);
543*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
544a9ac8606Spatrick     getTargetDefinesARMV87A(Opts, Builder);
545*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
546*12c85518Srobert     getTargetDefinesARMV88A(Opts, Builder);
547*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
548*12c85518Srobert     getTargetDefinesARMV89A(Opts, Builder);
549*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV9A)
550*12c85518Srobert     getTargetDefinesARMV9A(Opts, Builder);
551*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
552*12c85518Srobert     getTargetDefinesARMV91A(Opts, Builder);
553*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
554*12c85518Srobert     getTargetDefinesARMV92A(Opts, Builder);
555*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
556*12c85518Srobert     getTargetDefinesARMV93A(Opts, Builder);
557*12c85518Srobert   else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
558*12c85518Srobert     getTargetDefinesARMV94A(Opts, Builder);
559e5dd7070Spatrick 
560e5dd7070Spatrick   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
561e5dd7070Spatrick   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
562e5dd7070Spatrick   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
563e5dd7070Spatrick   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
564e5dd7070Spatrick   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
565a9ac8606Spatrick 
566*12c85518Srobert   // Allow detection of fast FMA support.
567*12c85518Srobert   Builder.defineMacro("__FP_FAST_FMA", "1");
568*12c85518Srobert   Builder.defineMacro("__FP_FAST_FMAF", "1");
569*12c85518Srobert 
570*12c85518Srobert   // C/C++ operators work on both VLS and VLA SVE types
571*12c85518Srobert   if (FPU & SveMode)
572*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
573*12c85518Srobert 
574*12c85518Srobert   if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
575*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
576a9ac8606Spatrick   }
577e5dd7070Spatrick }
578e5dd7070Spatrick 
getTargetBuiltins() const579e5dd7070Spatrick ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
580*12c85518Srobert   return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
581e5dd7070Spatrick                                          Builtin::FirstTSBuiltin);
582e5dd7070Spatrick }
583e5dd7070Spatrick 
584*12c85518Srobert std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions & LangOpts) const585*12c85518Srobert AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
586*12c85518Srobert   if (LangOpts.VScaleMin || LangOpts.VScaleMax)
587*12c85518Srobert     return std::pair<unsigned, unsigned>(
588*12c85518Srobert         LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
589*12c85518Srobert 
590*12c85518Srobert   if (hasFeature("sve"))
591*12c85518Srobert     return std::pair<unsigned, unsigned>(1, 16);
592*12c85518Srobert 
593*12c85518Srobert   return std::nullopt;
594*12c85518Srobert }
595*12c85518Srobert 
multiVersionSortPriority(StringRef Name) const596*12c85518Srobert unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
597*12c85518Srobert   if (Name == "default")
598*12c85518Srobert     return 0;
599*12c85518Srobert   for (const auto &E : llvm::AArch64::Extensions)
600*12c85518Srobert     if (Name == E.Name)
601*12c85518Srobert       return E.FmvPriority;
602*12c85518Srobert   return 0;
603*12c85518Srobert }
604*12c85518Srobert 
multiVersionFeatureCost() const605*12c85518Srobert unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
606*12c85518Srobert   // Take the maximum priority as per feature cost, so more features win.
607*12c85518Srobert   return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
608*12c85518Srobert }
609*12c85518Srobert 
getFeatureDepOptions(StringRef Name,std::string & FeatureVec) const610*12c85518Srobert bool AArch64TargetInfo::getFeatureDepOptions(StringRef Name,
611*12c85518Srobert                                              std::string &FeatureVec) const {
612*12c85518Srobert   FeatureVec = "";
613*12c85518Srobert   for (const auto &E : llvm::AArch64::Extensions) {
614*12c85518Srobert     if (Name == E.Name) {
615*12c85518Srobert       FeatureVec = E.DependentFeatures;
616*12c85518Srobert       break;
617*12c85518Srobert     }
618*12c85518Srobert   }
619*12c85518Srobert   return FeatureVec != "";
620*12c85518Srobert }
621*12c85518Srobert 
validateCpuSupports(StringRef FeatureStr) const622*12c85518Srobert bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
623*12c85518Srobert   for (const auto &E : llvm::AArch64::Extensions)
624*12c85518Srobert     if (FeatureStr == E.Name)
625*12c85518Srobert       return true;
626*12c85518Srobert   return false;
627*12c85518Srobert }
628*12c85518Srobert 
hasFeature(StringRef Feature) const629e5dd7070Spatrick bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
630*12c85518Srobert   return llvm::StringSwitch<bool>(Feature)
631*12c85518Srobert       .Cases("aarch64", "arm64", "arm", true)
632*12c85518Srobert       .Case("fmv", HasFMV)
633*12c85518Srobert       .Cases("neon", "fp", "simd", FPU & NeonMode)
634*12c85518Srobert       .Case("jscvt", HasJSCVT)
635*12c85518Srobert       .Case("fcma", HasFCMA)
636*12c85518Srobert       .Case("rng", HasRandGen)
637*12c85518Srobert       .Case("flagm", HasFlagM)
638*12c85518Srobert       .Case("flagm2", HasAlternativeNZCV)
639*12c85518Srobert       .Case("fp16fml", HasFP16FML)
640*12c85518Srobert       .Case("dotprod", HasDotProd)
641*12c85518Srobert       .Case("sm4", HasSM4)
642*12c85518Srobert       .Case("rdm", HasRDM)
643*12c85518Srobert       .Case("lse", HasLSE)
644*12c85518Srobert       .Case("crc", HasCRC)
645*12c85518Srobert       .Case("sha2", HasSHA2)
646*12c85518Srobert       .Case("sha3", HasSHA3)
647*12c85518Srobert       .Cases("aes", "pmull", HasAES)
648*12c85518Srobert       .Cases("fp16", "fullfp16", HasFullFP16)
649*12c85518Srobert       .Case("dit", HasDIT)
650*12c85518Srobert       .Case("dpb", HasCCPP)
651*12c85518Srobert       .Case("dpb2", HasCCDP)
652*12c85518Srobert       .Case("rcpc", HasRCPC)
653*12c85518Srobert       .Case("frintts", HasFRInt3264)
654*12c85518Srobert       .Case("i8mm", HasMatMul)
655*12c85518Srobert       .Case("bf16", HasBFloat16)
656*12c85518Srobert       .Case("sve", FPU & SveMode)
657*12c85518Srobert       .Case("sve-bf16", FPU & SveMode && HasBFloat16)
658*12c85518Srobert       .Case("sve-i8mm", FPU & SveMode && HasMatMul)
659*12c85518Srobert       .Case("f32mm", FPU & SveMode && HasMatmulFP32)
660*12c85518Srobert       .Case("f64mm", FPU & SveMode && HasMatmulFP64)
661*12c85518Srobert       .Case("sve2", FPU & SveMode && HasSVE2)
662*12c85518Srobert       .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
663*12c85518Srobert       .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
664*12c85518Srobert       .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
665*12c85518Srobert       .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
666*12c85518Srobert       .Case("sme", HasSME)
667*12c85518Srobert       .Case("sme-f64f64", HasSMEF64)
668*12c85518Srobert       .Case("sme-i16i64", HasSMEI64)
669*12c85518Srobert       .Cases("memtag", "memtag2", HasMTE)
670*12c85518Srobert       .Case("sb", HasSB)
671*12c85518Srobert       .Case("predres", HasPredRes)
672*12c85518Srobert       .Cases("ssbs", "ssbs2", HasSSBS)
673*12c85518Srobert       .Case("bti", HasBTI)
674*12c85518Srobert       .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
675*12c85518Srobert       .Case("wfxt", HasWFxT)
676*12c85518Srobert       .Default(false);
677*12c85518Srobert }
678*12c85518Srobert 
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const679*12c85518Srobert void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
680*12c85518Srobert                                           StringRef Name, bool Enabled) const {
681*12c85518Srobert   Features[Name] = Enabled;
682*12c85518Srobert   // If the feature is an architecture feature (like v8.2a), add all previous
683*12c85518Srobert   // architecture versions and any dependant target features.
684*12c85518Srobert   const llvm::AArch64::ArchInfo &ArchInfo =
685*12c85518Srobert       llvm::AArch64::ArchInfo::findBySubArch(Name);
686*12c85518Srobert 
687*12c85518Srobert   if (ArchInfo == llvm::AArch64::INVALID)
688*12c85518Srobert     return; // Not an architecure, nothing more to do.
689*12c85518Srobert 
690*12c85518Srobert   // Disabling an architecture feature does not affect dependent features
691*12c85518Srobert   if (!Enabled)
692*12c85518Srobert     return;
693*12c85518Srobert 
694*12c85518Srobert   for (const auto *OtherArch : llvm::AArch64::ArchInfos)
695*12c85518Srobert     if (ArchInfo.implies(*OtherArch))
696*12c85518Srobert       Features[OtherArch->getSubArch()] = true;
697*12c85518Srobert 
698*12c85518Srobert   // Set any features implied by the architecture
699*12c85518Srobert   uint64_t Extensions =
700*12c85518Srobert       llvm::AArch64::getDefaultExtensions("generic", ArchInfo);
701*12c85518Srobert   std::vector<StringRef> CPUFeats;
702*12c85518Srobert   if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) {
703*12c85518Srobert     for (auto F : CPUFeats) {
704*12c85518Srobert       assert(F[0] == '+' && "Expected + in target feature!");
705*12c85518Srobert       Features[F.drop_front(1)] = true;
706*12c85518Srobert     }
707*12c85518Srobert   }
708e5dd7070Spatrick }
709e5dd7070Spatrick 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)710e5dd7070Spatrick bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
711e5dd7070Spatrick                                              DiagnosticsEngine &Diags) {
712e5dd7070Spatrick   for (const auto &Feature : Features) {
713*12c85518Srobert     if (Feature == "-neon")
714*12c85518Srobert       HasNoNeon = true;
715*12c85518Srobert     if (Feature == "-sve")
716*12c85518Srobert       HasNoSVE = true;
717*12c85518Srobert 
718*12c85518Srobert     if (Feature == "+neon" || Feature == "+fp-armv8")
719e5dd7070Spatrick       FPU |= NeonMode;
720*12c85518Srobert     if (Feature == "+jscvt") {
721*12c85518Srobert       HasJSCVT = true;
722*12c85518Srobert       FPU |= NeonMode;
723*12c85518Srobert     }
724*12c85518Srobert     if (Feature == "+fcma") {
725*12c85518Srobert       HasFCMA = true;
726*12c85518Srobert       FPU |= NeonMode;
727*12c85518Srobert     }
728*12c85518Srobert 
729ec727ea7Spatrick     if (Feature == "+sve") {
730*12c85518Srobert       FPU |= NeonMode;
731e5dd7070Spatrick       FPU |= SveMode;
732*12c85518Srobert       HasFullFP16 = true;
733ec727ea7Spatrick     }
734ec727ea7Spatrick     if (Feature == "+sve2") {
735*12c85518Srobert       FPU |= NeonMode;
736ec727ea7Spatrick       FPU |= SveMode;
737*12c85518Srobert       HasFullFP16 = true;
738*12c85518Srobert       HasSVE2 = true;
739ec727ea7Spatrick     }
740ec727ea7Spatrick     if (Feature == "+sve2-aes") {
741*12c85518Srobert       FPU |= NeonMode;
742ec727ea7Spatrick       FPU |= SveMode;
743*12c85518Srobert       HasFullFP16 = true;
744*12c85518Srobert       HasSVE2 = true;
745*12c85518Srobert       HasSVE2AES = true;
746ec727ea7Spatrick     }
747ec727ea7Spatrick     if (Feature == "+sve2-sha3") {
748*12c85518Srobert       FPU |= NeonMode;
749ec727ea7Spatrick       FPU |= SveMode;
750*12c85518Srobert       HasFullFP16 = true;
751*12c85518Srobert       HasSVE2 = true;
752*12c85518Srobert       HasSVE2SHA3 = true;
753ec727ea7Spatrick     }
754ec727ea7Spatrick     if (Feature == "+sve2-sm4") {
755*12c85518Srobert       FPU |= NeonMode;
756ec727ea7Spatrick       FPU |= SveMode;
757*12c85518Srobert       HasFullFP16 = true;
758*12c85518Srobert       HasSVE2 = true;
759*12c85518Srobert       HasSVE2SM4 = true;
760ec727ea7Spatrick     }
761ec727ea7Spatrick     if (Feature == "+sve2-bitperm") {
762*12c85518Srobert       FPU |= NeonMode;
763ec727ea7Spatrick       FPU |= SveMode;
764*12c85518Srobert       HasFullFP16 = true;
765*12c85518Srobert       HasSVE2 = true;
766*12c85518Srobert       HasSVE2BitPerm = true;
767ec727ea7Spatrick     }
768ec727ea7Spatrick     if (Feature == "+f32mm") {
769*12c85518Srobert       FPU |= NeonMode;
770ec727ea7Spatrick       FPU |= SveMode;
771*12c85518Srobert       HasFullFP16 = true;
772ec727ea7Spatrick       HasMatmulFP32 = true;
773ec727ea7Spatrick     }
774ec727ea7Spatrick     if (Feature == "+f64mm") {
775*12c85518Srobert       FPU |= NeonMode;
776ec727ea7Spatrick       FPU |= SveMode;
777*12c85518Srobert       HasFullFP16 = true;
778ec727ea7Spatrick       HasMatmulFP64 = true;
779ec727ea7Spatrick     }
780*12c85518Srobert     if (Feature == "+sme") {
781*12c85518Srobert       HasSME = true;
782*12c85518Srobert       HasBFloat16 = true;
783*12c85518Srobert     }
784*12c85518Srobert     if (Feature == "+sme-f64f64") {
785*12c85518Srobert       HasSME = true;
786*12c85518Srobert       HasSMEF64 = true;
787*12c85518Srobert       HasBFloat16 = true;
788*12c85518Srobert     }
789*12c85518Srobert     if (Feature == "+sme-i16i64") {
790*12c85518Srobert       HasSME = true;
791*12c85518Srobert       HasSMEI64 = true;
792*12c85518Srobert       HasBFloat16 = true;
793*12c85518Srobert     }
794*12c85518Srobert     if (Feature == "+sb")
795*12c85518Srobert       HasSB = true;
796*12c85518Srobert     if (Feature == "+predres")
797*12c85518Srobert       HasPredRes = true;
798*12c85518Srobert     if (Feature == "+ssbs")
799*12c85518Srobert       HasSSBS = true;
800*12c85518Srobert     if (Feature == "+bti")
801*12c85518Srobert       HasBTI = true;
802*12c85518Srobert     if (Feature == "+wfxt")
803*12c85518Srobert       HasWFxT = true;
804*12c85518Srobert     if (Feature == "-fmv")
805*12c85518Srobert       HasFMV = false;
806e5dd7070Spatrick     if (Feature == "+crc")
807e5dd7070Spatrick       HasCRC = true;
808*12c85518Srobert     if (Feature == "+rcpc")
809*12c85518Srobert       HasRCPC = true;
810*12c85518Srobert     if (Feature == "+aes") {
811*12c85518Srobert       FPU |= NeonMode;
812a9ac8606Spatrick       HasAES = true;
813*12c85518Srobert     }
814*12c85518Srobert     if (Feature == "+sha2") {
815*12c85518Srobert       FPU |= NeonMode;
816a9ac8606Spatrick       HasSHA2 = true;
817*12c85518Srobert     }
818a9ac8606Spatrick     if (Feature == "+sha3") {
819*12c85518Srobert       FPU |= NeonMode;
820a9ac8606Spatrick       HasSHA2 = true;
821a9ac8606Spatrick       HasSHA3 = true;
822a9ac8606Spatrick     }
823*12c85518Srobert     if (Feature == "+rdm") {
824*12c85518Srobert       FPU |= NeonMode;
825*12c85518Srobert       HasRDM = true;
826*12c85518Srobert     }
827*12c85518Srobert     if (Feature == "+dit")
828*12c85518Srobert       HasDIT = true;
829*12c85518Srobert     if (Feature == "+cccp")
830*12c85518Srobert       HasCCPP = true;
831*12c85518Srobert     if (Feature == "+ccdp") {
832*12c85518Srobert       HasCCPP = true;
833*12c85518Srobert       HasCCDP = true;
834*12c85518Srobert     }
835*12c85518Srobert     if (Feature == "+fptoint")
836*12c85518Srobert       HasFRInt3264 = true;
837*12c85518Srobert     if (Feature == "+sm4") {
838*12c85518Srobert       FPU |= NeonMode;
839a9ac8606Spatrick       HasSM4 = true;
840*12c85518Srobert     }
841e5dd7070Spatrick     if (Feature == "+strict-align")
842e5dd7070Spatrick       HasUnaligned = false;
843*12c85518Srobert     // All predecessor archs are added but select the latest one for ArchKind.
844*12c85518Srobert     if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
845*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8A;
846*12c85518Srobert     if (Feature == "+v8.1a" &&
847*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
848*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_1A;
849*12c85518Srobert     if (Feature == "+v8.2a" &&
850*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
851*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_2A;
852*12c85518Srobert     if (Feature == "+v8.3a" &&
853*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
854*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_3A;
855*12c85518Srobert     if (Feature == "+v8.4a" &&
856*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
857*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_4A;
858*12c85518Srobert     if (Feature == "+v8.5a" &&
859*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
860*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_5A;
861*12c85518Srobert     if (Feature == "+v8.6a" &&
862*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
863*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_6A;
864*12c85518Srobert     if (Feature == "+v8.7a" &&
865*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
866*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_7A;
867*12c85518Srobert     if (Feature == "+v8.8a" &&
868*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
869*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_8A;
870*12c85518Srobert     if (Feature == "+v8.9a" &&
871*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
872*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8_9A;
873*12c85518Srobert     if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
874*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV9A;
875*12c85518Srobert     if (Feature == "+v9.1a" &&
876*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
877*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV9_1A;
878*12c85518Srobert     if (Feature == "+v9.2a" &&
879*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
880*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV9_2A;
881*12c85518Srobert     if (Feature == "+v9.3a" &&
882*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
883*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV9_3A;
884*12c85518Srobert     if (Feature == "+v9.4a" &&
885*12c85518Srobert         ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
886*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV9_4A;
887a9ac8606Spatrick     if (Feature == "+v8r")
888*12c85518Srobert       ArchInfo = &llvm::AArch64::ARMV8R;
889*12c85518Srobert     if (Feature == "+fullfp16") {
890*12c85518Srobert       FPU |= NeonMode;
891e5dd7070Spatrick       HasFullFP16 = true;
892*12c85518Srobert     }
893*12c85518Srobert     if (Feature == "+dotprod") {
894*12c85518Srobert       FPU |= NeonMode;
895e5dd7070Spatrick       HasDotProd = true;
896*12c85518Srobert     }
897*12c85518Srobert     if (Feature == "+fp16fml") {
898*12c85518Srobert       FPU |= NeonMode;
899*12c85518Srobert       HasFullFP16 = true;
900e5dd7070Spatrick       HasFP16FML = true;
901*12c85518Srobert     }
902e5dd7070Spatrick     if (Feature == "+mte")
903e5dd7070Spatrick       HasMTE = true;
904e5dd7070Spatrick     if (Feature == "+tme")
905e5dd7070Spatrick       HasTME = true;
906a9ac8606Spatrick     if (Feature == "+pauth")
907a9ac8606Spatrick       HasPAuth = true;
908ec727ea7Spatrick     if (Feature == "+i8mm")
909ec727ea7Spatrick       HasMatMul = true;
910ec727ea7Spatrick     if (Feature == "+bf16")
911ec727ea7Spatrick       HasBFloat16 = true;
912a9ac8606Spatrick     if (Feature == "+lse")
913a9ac8606Spatrick       HasLSE = true;
914a9ac8606Spatrick     if (Feature == "+ls64")
915a9ac8606Spatrick       HasLS64 = true;
916a9ac8606Spatrick     if (Feature == "+rand")
917a9ac8606Spatrick       HasRandGen = true;
918a9ac8606Spatrick     if (Feature == "+flagm")
919a9ac8606Spatrick       HasFlagM = true;
920*12c85518Srobert     if (Feature == "+altnzcv") {
921*12c85518Srobert       HasFlagM = true;
922*12c85518Srobert       HasAlternativeNZCV = true;
923*12c85518Srobert     }
924*12c85518Srobert     if (Feature == "+mops")
925*12c85518Srobert       HasMOPS = true;
926*12c85518Srobert     if (Feature == "+d128")
927*12c85518Srobert       HasD128 = true;
928*12c85518Srobert   }
929*12c85518Srobert 
930*12c85518Srobert   // Check features that are manually disabled by command line options.
931*12c85518Srobert   // This needs to be checked after architecture-related features are handled,
932*12c85518Srobert   // making sure they are properly disabled when required.
933*12c85518Srobert   for (const auto &Feature : Features) {
934*12c85518Srobert     if (Feature == "-d128")
935*12c85518Srobert       HasD128 = false;
936e5dd7070Spatrick   }
937e5dd7070Spatrick 
938e5dd7070Spatrick   setDataLayout();
939*12c85518Srobert   setArchFeatures();
940e5dd7070Spatrick 
941*12c85518Srobert   if (HasNoNeon) {
942*12c85518Srobert     FPU &= ~NeonMode;
943*12c85518Srobert     FPU &= ~SveMode;
944*12c85518Srobert   }
945*12c85518Srobert   if (HasNoSVE)
946*12c85518Srobert     FPU &= ~SveMode;
947*12c85518Srobert 
948*12c85518Srobert   return true;
949*12c85518Srobert }
950*12c85518Srobert 
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const951*12c85518Srobert bool AArch64TargetInfo::initFeatureMap(
952*12c85518Srobert     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
953*12c85518Srobert     const std::vector<std::string> &FeaturesVec) const {
954*12c85518Srobert   std::vector<std::string> UpdatedFeaturesVec;
955*12c85518Srobert   // Parse the CPU and add any implied features.
956*12c85518Srobert   const llvm::AArch64::ArchInfo &Arch = llvm::AArch64::parseCpu(CPU).Arch;
957*12c85518Srobert   if (Arch != llvm::AArch64::INVALID) {
958*12c85518Srobert     uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, Arch);
959*12c85518Srobert     std::vector<StringRef> CPUFeats;
960*12c85518Srobert     llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
961*12c85518Srobert     for (auto F : CPUFeats) {
962*12c85518Srobert       assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!");
963*12c85518Srobert       UpdatedFeaturesVec.push_back(F.str());
964*12c85518Srobert     }
965*12c85518Srobert   }
966*12c85518Srobert 
967*12c85518Srobert   // Process target and dependent features. This is done in two loops collecting
968*12c85518Srobert   // them into UpdatedFeaturesVec: first to add dependent '+'features,
969*12c85518Srobert   // second to add target '+/-'features that can later disable some of
970*12c85518Srobert   // features added on the first loop.
971*12c85518Srobert   for (const auto &Feature : FeaturesVec)
972*12c85518Srobert     if ((Feature[0] == '?' || Feature[0] == '+')) {
973*12c85518Srobert       std::string Options;
974*12c85518Srobert       if (AArch64TargetInfo::getFeatureDepOptions(Feature.substr(1), Options)) {
975*12c85518Srobert         SmallVector<StringRef, 1> AttrFeatures;
976*12c85518Srobert         StringRef(Options).split(AttrFeatures, ",");
977*12c85518Srobert         for (auto F : AttrFeatures)
978*12c85518Srobert           UpdatedFeaturesVec.push_back(F.str());
979*12c85518Srobert       }
980*12c85518Srobert     }
981*12c85518Srobert   for (const auto &Feature : FeaturesVec)
982*12c85518Srobert     if (Feature[0] == '+') {
983*12c85518Srobert       std::string F;
984*12c85518Srobert       llvm::AArch64::getFeatureOption(Feature, F);
985*12c85518Srobert       UpdatedFeaturesVec.push_back(F);
986*12c85518Srobert     } else if (Feature[0] != '?')
987*12c85518Srobert       UpdatedFeaturesVec.push_back(Feature);
988*12c85518Srobert 
989*12c85518Srobert   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
990*12c85518Srobert }
991*12c85518Srobert 
992*12c85518Srobert // Parse AArch64 Target attributes, which are a comma separated list of:
993*12c85518Srobert //  "arch=<arch>" - parsed to features as per -march=..
994*12c85518Srobert //  "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
995*12c85518Srobert //  "tune=<cpu>" - TuneCPU set to <cpu>
996*12c85518Srobert //  "feature", "no-feature" - Add (or remove) feature.
997*12c85518Srobert //  "+feature", "+nofeature" - Add (or remove) feature.
parseTargetAttr(StringRef Features) const998*12c85518Srobert ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
999*12c85518Srobert   ParsedTargetAttr Ret;
1000*12c85518Srobert   if (Features == "default")
1001*12c85518Srobert     return Ret;
1002*12c85518Srobert   SmallVector<StringRef, 1> AttrFeatures;
1003*12c85518Srobert   Features.split(AttrFeatures, ",");
1004*12c85518Srobert   bool FoundArch = false;
1005*12c85518Srobert 
1006*12c85518Srobert   auto SplitAndAddFeatures = [](StringRef FeatString,
1007*12c85518Srobert                                 std::vector<std::string> &Features) {
1008*12c85518Srobert     SmallVector<StringRef, 8> SplitFeatures;
1009*12c85518Srobert     FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1010*12c85518Srobert     for (StringRef Feature : SplitFeatures) {
1011*12c85518Srobert       StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1012*12c85518Srobert       if (!FeatureName.empty())
1013*12c85518Srobert         Features.push_back(FeatureName.str());
1014*12c85518Srobert       else
1015*12c85518Srobert         // Pushing the original feature string to give a sema error later on
1016*12c85518Srobert         // when they get checked.
1017*12c85518Srobert         if (Feature.startswith("no"))
1018*12c85518Srobert           Features.push_back("-" + Feature.drop_front(2).str());
1019*12c85518Srobert         else
1020*12c85518Srobert           Features.push_back("+" + Feature.str());
1021*12c85518Srobert     }
1022*12c85518Srobert   };
1023*12c85518Srobert 
1024*12c85518Srobert   for (auto &Feature : AttrFeatures) {
1025*12c85518Srobert     Feature = Feature.trim();
1026*12c85518Srobert     if (Feature.startswith("fpmath="))
1027*12c85518Srobert       continue;
1028*12c85518Srobert 
1029*12c85518Srobert     if (Feature.startswith("branch-protection=")) {
1030*12c85518Srobert       Ret.BranchProtection = Feature.split('=').second.trim();
1031*12c85518Srobert       continue;
1032*12c85518Srobert     }
1033*12c85518Srobert 
1034*12c85518Srobert     if (Feature.startswith("arch=")) {
1035*12c85518Srobert       if (FoundArch)
1036*12c85518Srobert         Ret.Duplicate = "arch=";
1037*12c85518Srobert       FoundArch = true;
1038*12c85518Srobert       std::pair<StringRef, StringRef> Split =
1039*12c85518Srobert           Feature.split("=").second.trim().split("+");
1040*12c85518Srobert       const llvm::AArch64::ArchInfo &AI = llvm::AArch64::parseArch(Split.first);
1041*12c85518Srobert 
1042*12c85518Srobert       // Parse the architecture version, adding the required features to
1043*12c85518Srobert       // Ret.Features.
1044*12c85518Srobert       if (AI == llvm::AArch64::INVALID)
1045*12c85518Srobert         continue;
1046*12c85518Srobert       Ret.Features.push_back(AI.ArchFeature.str());
1047*12c85518Srobert       // Add any extra features, after the +
1048*12c85518Srobert       SplitAndAddFeatures(Split.second, Ret.Features);
1049*12c85518Srobert     } else if (Feature.startswith("cpu=")) {
1050*12c85518Srobert       if (!Ret.CPU.empty())
1051*12c85518Srobert         Ret.Duplicate = "cpu=";
1052*12c85518Srobert       else {
1053*12c85518Srobert         // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1054*12c85518Srobert         // "+feat" features.
1055*12c85518Srobert         std::pair<StringRef, StringRef> Split =
1056*12c85518Srobert             Feature.split("=").second.trim().split("+");
1057*12c85518Srobert         Ret.CPU = Split.first;
1058*12c85518Srobert         SplitAndAddFeatures(Split.second, Ret.Features);
1059*12c85518Srobert       }
1060*12c85518Srobert     } else if (Feature.startswith("tune=")) {
1061*12c85518Srobert       if (!Ret.Tune.empty())
1062*12c85518Srobert         Ret.Duplicate = "tune=";
1063*12c85518Srobert       else
1064*12c85518Srobert         Ret.Tune = Feature.split("=").second.trim();
1065*12c85518Srobert     } else if (Feature.startswith("+")) {
1066*12c85518Srobert       SplitAndAddFeatures(Feature, Ret.Features);
1067*12c85518Srobert     } else if (Feature.startswith("no-")) {
1068*12c85518Srobert       StringRef FeatureName =
1069*12c85518Srobert           llvm::AArch64::getArchExtFeature(Feature.split("-").second);
1070*12c85518Srobert       if (!FeatureName.empty())
1071*12c85518Srobert         Ret.Features.push_back("-" + FeatureName.drop_front(1).str());
1072*12c85518Srobert       else
1073*12c85518Srobert         Ret.Features.push_back("-" + Feature.split("-").second.str());
1074*12c85518Srobert     } else {
1075*12c85518Srobert       // Try parsing the string to the internal target feature name. If it is
1076*12c85518Srobert       // invalid, add the original string (which could already be an internal
1077*12c85518Srobert       // name). These should be checked later by isValidFeatureName.
1078*12c85518Srobert       StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1079*12c85518Srobert       if (!FeatureName.empty())
1080*12c85518Srobert         Ret.Features.push_back(FeatureName.str());
1081*12c85518Srobert       else
1082*12c85518Srobert         Ret.Features.push_back("+" + Feature.str());
1083*12c85518Srobert     }
1084*12c85518Srobert   }
1085*12c85518Srobert   return Ret;
1086*12c85518Srobert }
1087*12c85518Srobert 
hasBFloat16Type() const1088*12c85518Srobert bool AArch64TargetInfo::hasBFloat16Type() const {
1089e5dd7070Spatrick   return true;
1090e5dd7070Spatrick }
1091e5dd7070Spatrick 
1092e5dd7070Spatrick TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1093e5dd7070Spatrick AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
1094e5dd7070Spatrick   switch (CC) {
1095e5dd7070Spatrick   case CC_C:
1096e5dd7070Spatrick   case CC_Swift:
1097a9ac8606Spatrick   case CC_SwiftAsync:
1098e5dd7070Spatrick   case CC_PreserveMost:
1099e5dd7070Spatrick   case CC_PreserveAll:
1100e5dd7070Spatrick   case CC_OpenCLKernel:
1101e5dd7070Spatrick   case CC_AArch64VectorCall:
1102*12c85518Srobert   case CC_AArch64SVEPCS:
1103e5dd7070Spatrick   case CC_Win64:
1104e5dd7070Spatrick     return CCCR_OK;
1105e5dd7070Spatrick   default:
1106e5dd7070Spatrick     return CCCR_Warning;
1107e5dd7070Spatrick   }
1108e5dd7070Spatrick }
1109e5dd7070Spatrick 
isCLZForZeroUndef() const1110e5dd7070Spatrick bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1111e5dd7070Spatrick 
getBuiltinVaListKind() const1112e5dd7070Spatrick TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1113e5dd7070Spatrick   return TargetInfo::AArch64ABIBuiltinVaList;
1114e5dd7070Spatrick }
1115e5dd7070Spatrick 
1116e5dd7070Spatrick const char *const AArch64TargetInfo::GCCRegNames[] = {
1117e5dd7070Spatrick     // 32-bit Integer registers
1118e5dd7070Spatrick     "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1119e5dd7070Spatrick     "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1120e5dd7070Spatrick     "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1121e5dd7070Spatrick 
1122e5dd7070Spatrick     // 64-bit Integer registers
1123e5dd7070Spatrick     "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1124e5dd7070Spatrick     "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1125e5dd7070Spatrick     "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1126e5dd7070Spatrick 
1127e5dd7070Spatrick     // 32-bit floating point regsisters
1128e5dd7070Spatrick     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1129e5dd7070Spatrick     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1130e5dd7070Spatrick     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1131e5dd7070Spatrick 
1132e5dd7070Spatrick     // 64-bit floating point regsisters
1133e5dd7070Spatrick     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1134e5dd7070Spatrick     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1135e5dd7070Spatrick     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1136e5dd7070Spatrick 
1137e5dd7070Spatrick     // Neon vector registers
1138e5dd7070Spatrick     "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1139e5dd7070Spatrick     "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1140e5dd7070Spatrick     "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1141e5dd7070Spatrick 
1142e5dd7070Spatrick     // SVE vector registers
1143e5dd7070Spatrick     "z0",  "z1",  "z2",  "z3",  "z4",  "z5",  "z6",  "z7",  "z8",  "z9",  "z10",
1144e5dd7070Spatrick     "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1145e5dd7070Spatrick     "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1146e5dd7070Spatrick 
1147e5dd7070Spatrick     // SVE predicate registers
1148e5dd7070Spatrick     "p0",  "p1",  "p2",  "p3",  "p4",  "p5",  "p6",  "p7",  "p8",  "p9",  "p10",
1149e5dd7070Spatrick     "p11", "p12", "p13", "p14", "p15"
1150e5dd7070Spatrick };
1151e5dd7070Spatrick 
getGCCRegNames() const1152e5dd7070Spatrick ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1153*12c85518Srobert   return llvm::ArrayRef(GCCRegNames);
1154e5dd7070Spatrick }
1155e5dd7070Spatrick 
1156e5dd7070Spatrick const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1157e5dd7070Spatrick     {{"w31"}, "wsp"},
1158e5dd7070Spatrick     {{"x31"}, "sp"},
1159e5dd7070Spatrick     // GCC rN registers are aliases of xN registers.
1160e5dd7070Spatrick     {{"r0"}, "x0"},
1161e5dd7070Spatrick     {{"r1"}, "x1"},
1162e5dd7070Spatrick     {{"r2"}, "x2"},
1163e5dd7070Spatrick     {{"r3"}, "x3"},
1164e5dd7070Spatrick     {{"r4"}, "x4"},
1165e5dd7070Spatrick     {{"r5"}, "x5"},
1166e5dd7070Spatrick     {{"r6"}, "x6"},
1167e5dd7070Spatrick     {{"r7"}, "x7"},
1168e5dd7070Spatrick     {{"r8"}, "x8"},
1169e5dd7070Spatrick     {{"r9"}, "x9"},
1170e5dd7070Spatrick     {{"r10"}, "x10"},
1171e5dd7070Spatrick     {{"r11"}, "x11"},
1172e5dd7070Spatrick     {{"r12"}, "x12"},
1173e5dd7070Spatrick     {{"r13"}, "x13"},
1174e5dd7070Spatrick     {{"r14"}, "x14"},
1175e5dd7070Spatrick     {{"r15"}, "x15"},
1176e5dd7070Spatrick     {{"r16"}, "x16"},
1177e5dd7070Spatrick     {{"r17"}, "x17"},
1178e5dd7070Spatrick     {{"r18"}, "x18"},
1179e5dd7070Spatrick     {{"r19"}, "x19"},
1180e5dd7070Spatrick     {{"r20"}, "x20"},
1181e5dd7070Spatrick     {{"r21"}, "x21"},
1182e5dd7070Spatrick     {{"r22"}, "x22"},
1183e5dd7070Spatrick     {{"r23"}, "x23"},
1184e5dd7070Spatrick     {{"r24"}, "x24"},
1185e5dd7070Spatrick     {{"r25"}, "x25"},
1186e5dd7070Spatrick     {{"r26"}, "x26"},
1187e5dd7070Spatrick     {{"r27"}, "x27"},
1188e5dd7070Spatrick     {{"r28"}, "x28"},
1189e5dd7070Spatrick     {{"r29", "x29"}, "fp"},
1190e5dd7070Spatrick     {{"r30", "x30"}, "lr"},
1191e5dd7070Spatrick     // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1192e5dd7070Spatrick     // don't want to substitute one of these for a different-sized one.
1193e5dd7070Spatrick };
1194e5dd7070Spatrick 
getGCCRegAliases() const1195e5dd7070Spatrick ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1196*12c85518Srobert   return llvm::ArrayRef(GCCRegAliases);
1197e5dd7070Spatrick }
1198e5dd7070Spatrick 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1199e5dd7070Spatrick bool AArch64TargetInfo::validateAsmConstraint(
1200e5dd7070Spatrick     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1201e5dd7070Spatrick   switch (*Name) {
1202e5dd7070Spatrick   default:
1203e5dd7070Spatrick     return false;
1204e5dd7070Spatrick   case 'w': // Floating point and SIMD registers (V0-V31)
1205e5dd7070Spatrick     Info.setAllowsRegister();
1206e5dd7070Spatrick     return true;
1207e5dd7070Spatrick   case 'I': // Constant that can be used with an ADD instruction
1208e5dd7070Spatrick   case 'J': // Constant that can be used with a SUB instruction
1209e5dd7070Spatrick   case 'K': // Constant that can be used with a 32-bit logical instruction
1210e5dd7070Spatrick   case 'L': // Constant that can be used with a 64-bit logical instruction
1211e5dd7070Spatrick   case 'M': // Constant that can be used as a 32-bit MOV immediate
1212e5dd7070Spatrick   case 'N': // Constant that can be used as a 64-bit MOV immediate
1213e5dd7070Spatrick   case 'Y': // Floating point constant zero
1214e5dd7070Spatrick   case 'Z': // Integer constant zero
1215e5dd7070Spatrick     return true;
1216e5dd7070Spatrick   case 'Q': // A memory reference with base register and no offset
1217e5dd7070Spatrick     Info.setAllowsMemory();
1218e5dd7070Spatrick     return true;
1219e5dd7070Spatrick   case 'S': // A symbolic address
1220e5dd7070Spatrick     Info.setAllowsRegister();
1221e5dd7070Spatrick     return true;
1222e5dd7070Spatrick   case 'U':
1223ec727ea7Spatrick     if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) {
1224ec727ea7Spatrick       // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7)
1225ec727ea7Spatrick       Info.setAllowsRegister();
1226ec727ea7Spatrick       Name += 2;
1227ec727ea7Spatrick       return true;
1228ec727ea7Spatrick     }
1229e5dd7070Spatrick     // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1230e5dd7070Spatrick     // Utf: A memory address suitable for ldp/stp in TF mode.
1231e5dd7070Spatrick     // Usa: An absolute symbolic address.
1232e5dd7070Spatrick     // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1233ec727ea7Spatrick 
1234ec727ea7Spatrick     // Better to return an error saying that it's an unrecognised constraint
1235ec727ea7Spatrick     // even if this is a valid constraint in gcc.
1236ec727ea7Spatrick     return false;
1237e5dd7070Spatrick   case 'z': // Zero register, wzr or xzr
1238e5dd7070Spatrick     Info.setAllowsRegister();
1239e5dd7070Spatrick     return true;
1240e5dd7070Spatrick   case 'x': // Floating point and SIMD registers (V0-V15)
1241e5dd7070Spatrick     Info.setAllowsRegister();
1242e5dd7070Spatrick     return true;
1243ec727ea7Spatrick   case 'y': // SVE registers (V0-V7)
1244ec727ea7Spatrick     Info.setAllowsRegister();
1245ec727ea7Spatrick     return true;
1246e5dd7070Spatrick   }
1247e5dd7070Spatrick   return false;
1248e5dd7070Spatrick }
1249e5dd7070Spatrick 
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const1250e5dd7070Spatrick bool AArch64TargetInfo::validateConstraintModifier(
1251e5dd7070Spatrick     StringRef Constraint, char Modifier, unsigned Size,
1252e5dd7070Spatrick     std::string &SuggestedModifier) const {
1253e5dd7070Spatrick   // Strip off constraint modifiers.
1254e5dd7070Spatrick   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1255e5dd7070Spatrick     Constraint = Constraint.substr(1);
1256e5dd7070Spatrick 
1257e5dd7070Spatrick   switch (Constraint[0]) {
1258e5dd7070Spatrick   default:
1259e5dd7070Spatrick     return true;
1260e5dd7070Spatrick   case 'z':
1261e5dd7070Spatrick   case 'r': {
1262e5dd7070Spatrick     switch (Modifier) {
1263e5dd7070Spatrick     case 'x':
1264e5dd7070Spatrick     case 'w':
1265e5dd7070Spatrick       // For now assume that the person knows what they're
1266e5dd7070Spatrick       // doing with the modifier.
1267e5dd7070Spatrick       return true;
1268e5dd7070Spatrick     default:
1269e5dd7070Spatrick       // By default an 'r' constraint will be in the 'x'
1270e5dd7070Spatrick       // registers.
1271e5dd7070Spatrick       if (Size == 64)
1272e5dd7070Spatrick         return true;
1273e5dd7070Spatrick 
1274a9ac8606Spatrick       if (Size == 512)
1275a9ac8606Spatrick         return HasLS64;
1276a9ac8606Spatrick 
1277e5dd7070Spatrick       SuggestedModifier = "w";
1278e5dd7070Spatrick       return false;
1279e5dd7070Spatrick     }
1280e5dd7070Spatrick   }
1281e5dd7070Spatrick   }
1282e5dd7070Spatrick }
1283e5dd7070Spatrick 
getClobbers() const1284e5dd7070Spatrick const char *AArch64TargetInfo::getClobbers() const { return ""; }
1285e5dd7070Spatrick 
getEHDataRegisterNumber(unsigned RegNo) const1286e5dd7070Spatrick int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1287e5dd7070Spatrick   if (RegNo == 0)
1288e5dd7070Spatrick     return 0;
1289e5dd7070Spatrick   if (RegNo == 1)
1290e5dd7070Spatrick     return 1;
1291e5dd7070Spatrick   return -1;
1292e5dd7070Spatrick }
1293e5dd7070Spatrick 
hasInt128Type() const1294e5dd7070Spatrick bool AArch64TargetInfo::hasInt128Type() const { return true; }
1295e5dd7070Spatrick 
AArch64leTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1296e5dd7070Spatrick AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1297e5dd7070Spatrick                                          const TargetOptions &Opts)
1298e5dd7070Spatrick     : AArch64TargetInfo(Triple, Opts) {}
1299e5dd7070Spatrick 
setDataLayout()1300e5dd7070Spatrick void AArch64leTargetInfo::setDataLayout() {
1301e5dd7070Spatrick   if (getTriple().isOSBinFormatMachO()) {
1302e5dd7070Spatrick     if(getTriple().isArch32Bit())
1303a9ac8606Spatrick       resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_");
1304e5dd7070Spatrick     else
1305a9ac8606Spatrick       resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_");
1306e5dd7070Spatrick   } else
1307e5dd7070Spatrick     resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1308e5dd7070Spatrick }
1309e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1310e5dd7070Spatrick void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1311e5dd7070Spatrick                                            MacroBuilder &Builder) const {
1312e5dd7070Spatrick   Builder.defineMacro("__AARCH64EL__");
1313e5dd7070Spatrick   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1314e5dd7070Spatrick }
1315e5dd7070Spatrick 
AArch64beTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1316e5dd7070Spatrick AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1317e5dd7070Spatrick                                          const TargetOptions &Opts)
1318e5dd7070Spatrick     : AArch64TargetInfo(Triple, Opts) {}
1319e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1320e5dd7070Spatrick void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
1321e5dd7070Spatrick                                            MacroBuilder &Builder) const {
1322e5dd7070Spatrick   Builder.defineMacro("__AARCH64EB__");
1323e5dd7070Spatrick   Builder.defineMacro("__AARCH_BIG_ENDIAN");
1324e5dd7070Spatrick   Builder.defineMacro("__ARM_BIG_ENDIAN");
1325e5dd7070Spatrick   AArch64TargetInfo::getTargetDefines(Opts, Builder);
1326e5dd7070Spatrick }
1327e5dd7070Spatrick 
setDataLayout()1328e5dd7070Spatrick void AArch64beTargetInfo::setDataLayout() {
1329e5dd7070Spatrick   assert(!getTriple().isOSBinFormatMachO());
1330e5dd7070Spatrick   resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1331e5dd7070Spatrick }
1332e5dd7070Spatrick 
WindowsARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1333e5dd7070Spatrick WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
1334e5dd7070Spatrick                                                const TargetOptions &Opts)
1335e5dd7070Spatrick     : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1336e5dd7070Spatrick 
1337e5dd7070Spatrick   // This is an LLP64 platform.
1338e5dd7070Spatrick   // int:4, long:4, long long:8, long double:8.
1339e5dd7070Spatrick   IntWidth = IntAlign = 32;
1340e5dd7070Spatrick   LongWidth = LongAlign = 32;
1341e5dd7070Spatrick   DoubleAlign = LongLongAlign = 64;
1342e5dd7070Spatrick   LongDoubleWidth = LongDoubleAlign = 64;
1343e5dd7070Spatrick   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1344e5dd7070Spatrick   IntMaxType = SignedLongLong;
1345e5dd7070Spatrick   Int64Type = SignedLongLong;
1346e5dd7070Spatrick   SizeType = UnsignedLongLong;
1347e5dd7070Spatrick   PtrDiffType = SignedLongLong;
1348e5dd7070Spatrick   IntPtrType = SignedLongLong;
1349e5dd7070Spatrick }
1350e5dd7070Spatrick 
setDataLayout()1351e5dd7070Spatrick void WindowsARM64TargetInfo::setDataLayout() {
1352a9ac8606Spatrick   resetDataLayout(Triple.isOSBinFormatMachO()
1353a9ac8606Spatrick                       ? "e-m:o-i64:64-i128:128-n32:64-S128"
1354a9ac8606Spatrick                       : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128",
1355a9ac8606Spatrick                   Triple.isOSBinFormatMachO() ? "_" : "");
1356e5dd7070Spatrick }
1357e5dd7070Spatrick 
1358e5dd7070Spatrick TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1359e5dd7070Spatrick WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1360e5dd7070Spatrick   return TargetInfo::CharPtrBuiltinVaList;
1361e5dd7070Spatrick }
1362e5dd7070Spatrick 
1363e5dd7070Spatrick TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1364e5dd7070Spatrick WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
1365e5dd7070Spatrick   switch (CC) {
1366e5dd7070Spatrick   case CC_X86StdCall:
1367e5dd7070Spatrick   case CC_X86ThisCall:
1368e5dd7070Spatrick   case CC_X86FastCall:
1369e5dd7070Spatrick   case CC_X86VectorCall:
1370e5dd7070Spatrick     return CCCR_Ignore;
1371e5dd7070Spatrick   case CC_C:
1372e5dd7070Spatrick   case CC_OpenCLKernel:
1373e5dd7070Spatrick   case CC_PreserveMost:
1374e5dd7070Spatrick   case CC_PreserveAll:
1375e5dd7070Spatrick   case CC_Swift:
1376a9ac8606Spatrick   case CC_SwiftAsync:
1377e5dd7070Spatrick   case CC_Win64:
1378e5dd7070Spatrick     return CCCR_OK;
1379e5dd7070Spatrick   default:
1380e5dd7070Spatrick     return CCCR_Warning;
1381e5dd7070Spatrick   }
1382e5dd7070Spatrick }
1383e5dd7070Spatrick 
MicrosoftARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1384e5dd7070Spatrick MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1385e5dd7070Spatrick                                                    const TargetOptions &Opts)
1386e5dd7070Spatrick     : WindowsARM64TargetInfo(Triple, Opts) {
1387e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::Microsoft);
1388e5dd7070Spatrick }
1389e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1390e5dd7070Spatrick void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
1391e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
1392e5dd7070Spatrick   WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
1393e5dd7070Spatrick   Builder.defineMacro("_M_ARM64", "1");
1394e5dd7070Spatrick }
1395e5dd7070Spatrick 
1396e5dd7070Spatrick TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const1397e5dd7070Spatrick MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1398e5dd7070Spatrick   return CCK_MicrosoftWin64;
1399e5dd7070Spatrick }
1400e5dd7070Spatrick 
getMinGlobalAlign(uint64_t TypeSize) const1401e5dd7070Spatrick unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
1402e5dd7070Spatrick   unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
1403e5dd7070Spatrick 
1404e5dd7070Spatrick   // MSVC does size based alignment for arm64 based on alignment section in
1405e5dd7070Spatrick   // below document, replicate that to keep alignment consistent with object
1406e5dd7070Spatrick   // files compiled by MSVC.
1407e5dd7070Spatrick   // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
1408e5dd7070Spatrick   if (TypeSize >= 512) {              // TypeSize >= 64 bytes
1409e5dd7070Spatrick     Align = std::max(Align, 128u);    // align type at least 16 bytes
1410e5dd7070Spatrick   } else if (TypeSize >= 64) {        // TypeSize >= 8 bytes
1411e5dd7070Spatrick     Align = std::max(Align, 64u);     // align type at least 8 butes
1412e5dd7070Spatrick   } else if (TypeSize >= 16) {        // TypeSize >= 2 bytes
1413e5dd7070Spatrick     Align = std::max(Align, 32u);     // align type at least 4 bytes
1414e5dd7070Spatrick   }
1415e5dd7070Spatrick   return Align;
1416e5dd7070Spatrick }
1417e5dd7070Spatrick 
MinGWARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1418e5dd7070Spatrick MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1419e5dd7070Spatrick                                            const TargetOptions &Opts)
1420e5dd7070Spatrick     : WindowsARM64TargetInfo(Triple, Opts) {
1421e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::GenericAArch64);
1422e5dd7070Spatrick }
1423e5dd7070Spatrick 
DarwinAArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1424e5dd7070Spatrick DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1425e5dd7070Spatrick                                                  const TargetOptions &Opts)
1426e5dd7070Spatrick     : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1427e5dd7070Spatrick   Int64Type = SignedLongLong;
1428e5dd7070Spatrick   if (getTriple().isArch32Bit())
1429e5dd7070Spatrick     IntMaxType = SignedLongLong;
1430e5dd7070Spatrick 
1431e5dd7070Spatrick   WCharType = SignedInt;
1432e5dd7070Spatrick   UseSignedCharForObjCBool = false;
1433e5dd7070Spatrick 
1434e5dd7070Spatrick   LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1435e5dd7070Spatrick   LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1436e5dd7070Spatrick 
1437e5dd7070Spatrick   UseZeroLengthBitfieldAlignment = false;
1438e5dd7070Spatrick 
1439e5dd7070Spatrick   if (getTriple().isArch32Bit()) {
1440e5dd7070Spatrick     UseBitFieldTypeAlignment = false;
1441e5dd7070Spatrick     ZeroLengthBitfieldBoundary = 32;
1442e5dd7070Spatrick     UseZeroLengthBitfieldAlignment = true;
1443e5dd7070Spatrick     TheCXXABI.set(TargetCXXABI::WatchOS);
1444e5dd7070Spatrick   } else
1445a9ac8606Spatrick     TheCXXABI.set(TargetCXXABI::AppleARM64);
1446e5dd7070Spatrick }
1447e5dd7070Spatrick 
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1448e5dd7070Spatrick void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1449e5dd7070Spatrick                                            const llvm::Triple &Triple,
1450e5dd7070Spatrick                                            MacroBuilder &Builder) const {
1451e5dd7070Spatrick   Builder.defineMacro("__AARCH64_SIMD__");
1452e5dd7070Spatrick   if (Triple.isArch32Bit())
1453e5dd7070Spatrick     Builder.defineMacro("__ARM64_ARCH_8_32__");
1454e5dd7070Spatrick   else
1455e5dd7070Spatrick     Builder.defineMacro("__ARM64_ARCH_8__");
1456e5dd7070Spatrick   Builder.defineMacro("__ARM_NEON__");
1457e5dd7070Spatrick   Builder.defineMacro("__LITTLE_ENDIAN__");
1458e5dd7070Spatrick   Builder.defineMacro("__REGISTER_PREFIX__", "");
1459e5dd7070Spatrick   Builder.defineMacro("__arm64", "1");
1460e5dd7070Spatrick   Builder.defineMacro("__arm64__", "1");
1461e5dd7070Spatrick 
1462a9ac8606Spatrick   if (Triple.isArm64e())
1463a9ac8606Spatrick     Builder.defineMacro("__arm64e__", "1");
1464a9ac8606Spatrick 
1465e5dd7070Spatrick   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1466e5dd7070Spatrick }
1467e5dd7070Spatrick 
1468e5dd7070Spatrick TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1469e5dd7070Spatrick DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1470e5dd7070Spatrick   return TargetInfo::CharPtrBuiltinVaList;
1471e5dd7070Spatrick }
1472e5dd7070Spatrick 
1473e5dd7070Spatrick // 64-bit RenderScript is aarch64
RenderScript64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1474e5dd7070Spatrick RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
1475e5dd7070Spatrick                                                    const TargetOptions &Opts)
1476e5dd7070Spatrick     : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
1477e5dd7070Spatrick                                        Triple.getOSName(),
1478e5dd7070Spatrick                                        Triple.getEnvironmentName()),
1479e5dd7070Spatrick                           Opts) {
1480e5dd7070Spatrick   IsRenderScriptTarget = true;
1481e5dd7070Spatrick }
1482e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1483e5dd7070Spatrick void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
1484e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
1485e5dd7070Spatrick   Builder.defineMacro("__RENDERSCRIPT__");
1486e5dd7070Spatrick   AArch64leTargetInfo::getTargetDefines(Opts, Builder);
1487e5dd7070Spatrick }
1488