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