blob: f70a5345761313b593704a51a50efe4efd6103e1 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Erich Keaneebba5922017-07-21 22:37:03 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements AArch64 TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "AArch64.h"
Daniel Kiss7314aea2020-04-02 10:11:01 +020014#include "clang/Basic/LangOptions.h"
Erich Keaneebba5922017-07-21 22:37:03 +000015#include "clang/Basic/TargetBuiltins.h"
16#include "clang/Basic/TargetInfo.h"
17#include "llvm/ADT/ArrayRef.h"
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000018#include "llvm/ADT/StringExtras.h"
Momchil Velikovaa6d48f2019-11-15 11:34:47 +000019#include "llvm/ADT/StringSwitch.h"
20#include "llvm/Support/AArch64TargetParser.h"
Erich Keaneebba5922017-07-21 22:37:03 +000021
22using namespace clang;
23using namespace clang::targets;
24
Tim Northoverad4c5db2017-07-24 17:06:23 +000025const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
26#define BUILTIN(ID, TYPE, ATTRS) \
27 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
28#include "clang/Basic/BuiltinsNEON.def"
29
30#define BUILTIN(ID, TYPE, ATTRS) \
31 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
Sander de Smalenc5b81462020-03-18 11:07:20 +000032#include "clang/Basic/BuiltinsSVE.def"
33
34#define BUILTIN(ID, TYPE, ATTRS) \
35 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
Martin Storsjod8a44ed2017-10-12 07:05:37 +000036#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
37 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
Martin Storsjo17c0f722018-07-18 06:15:09 +000038#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
39 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
Tim Northoverad4c5db2017-07-24 17:06:23 +000040#include "clang/Basic/BuiltinsAArch64.def"
41};
42
43AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
44 const TargetOptions &Opts)
45 : TargetInfo(Triple), ABI("aapcs") {
Michal Gorny5a409d02018-12-20 13:09:30 +000046 if (getTriple().isOSOpenBSD()) {
Tim Northoverad4c5db2017-07-24 17:06:23 +000047 Int64Type = SignedLongLong;
48 IntMaxType = SignedLongLong;
49 } else {
Michal Gorny5a409d02018-12-20 13:09:30 +000050 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000051 WCharType = UnsignedInt;
52
Tim Northoverad4c5db2017-07-24 17:06:23 +000053 Int64Type = SignedLong;
54 IntMaxType = SignedLong;
55 }
56
Sjoerd Meijer87793e72018-03-19 13:22:49 +000057 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
58 HasLegalHalfType = true;
Erich Keane1d1d4382019-01-25 17:27:57 +000059 HasFloat16 = true;
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000060
Tim Northover44e58792018-09-18 10:34:39 +010061 if (Triple.isArch64Bit())
62 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
63 else
64 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
65
Tim Northoverad4c5db2017-07-24 17:06:23 +000066 MaxVectorAlign = 128;
67 MaxAtomicInlineWidth = 128;
68 MaxAtomicPromoteWidth = 128;
69
70 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
71 LongDoubleFormat = &llvm::APFloat::IEEEquad();
72
73 // Make __builtin_ms_va_list available.
74 HasBuiltinMSVaList = true;
75
Richard Sandifordeb485fb2019-08-09 08:52:54 +000076 // Make the SVE types available. Note that this deliberately doesn't
77 // depend on SveMode, since in principle it should be possible to turn
78 // SVE on and off within a translation unit. It should also be possible
79 // to compile the global declaration:
80 //
81 // __SVInt8_t *ptr;
82 //
83 // even without SVE.
84 HasAArch64SVETypes = true;
85
Tim Northoverad4c5db2017-07-24 17:06:23 +000086 // {} in inline assembly are neon specifiers, not assembly variant
87 // specifiers.
88 NoAsmVariants = true;
89
90 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
91 // contributes to the alignment of the containing aggregate in the same way
92 // a plain (non bit-field) member of that type would, without exception for
93 // zero-sized or anonymous bit-fields."
94 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
95 UseZeroLengthBitfieldAlignment = true;
96
97 // AArch64 targets default to using the ARM C++ ABI.
98 TheCXXABI.set(TargetCXXABI::GenericAArch64);
99
100 if (Triple.getOS() == llvm::Triple::Linux)
101 this->MCountName = "\01_mcount";
102 else if (Triple.getOS() == llvm::Triple::UnknownOS)
103 this->MCountName =
104 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
105}
106
107StringRef AArch64TargetInfo::getABI() const { return ABI; }
108
109bool AArch64TargetInfo::setABI(const std::string &Name) {
110 if (Name != "aapcs" && Name != "darwinpcs")
111 return false;
112
113 ABI = Name;
114 return true;
115}
116
Momchil Velikovaa6d48f2019-11-15 11:34:47 +0000117bool AArch64TargetInfo::validateBranchProtection(StringRef Spec,
118 BranchProtectionInfo &BPI,
119 StringRef &Err) const {
120 llvm::AArch64::ParsedBranchProtection PBP;
121 if (!llvm::AArch64::parseBranchProtection(Spec, PBP, Err))
122 return false;
123
124 BPI.SignReturnAddr =
Daniel Kiss7314aea2020-04-02 10:11:01 +0200125 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
126 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
127 .Case("all", LangOptions::SignReturnAddressScopeKind::All)
128 .Default(LangOptions::SignReturnAddressScopeKind::None);
Momchil Velikovaa6d48f2019-11-15 11:34:47 +0000129
130 if (PBP.Key == "a_key")
Daniel Kiss7314aea2020-04-02 10:11:01 +0200131 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
Momchil Velikovaa6d48f2019-11-15 11:34:47 +0000132 else
Daniel Kiss7314aea2020-04-02 10:11:01 +0200133 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
Momchil Velikovaa6d48f2019-11-15 11:34:47 +0000134
135 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
136 return true;
137}
138
Tim Northoverad4c5db2017-07-24 17:06:23 +0000139bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
140 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000141 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000142}
143
144bool AArch64TargetInfo::setCPU(const std::string &Name) {
145 return isValidCPUName(Name);
146}
147
Erich Keane3ec17432018-02-08 23:14:15 +0000148void AArch64TargetInfo::fillValidCPUList(
149 SmallVectorImpl<StringRef> &Values) const {
150 llvm::AArch64::fillValidCPUArchList(Values);
151}
152
Tim Northoverad4c5db2017-07-24 17:06:23 +0000153void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
154 MacroBuilder &Builder) const {
Ties Stuij71ae2672020-03-26 08:17:29 +0000155 // FIXME: Armv8.1 makes __ARM_FEATURE_CRC32 mandatory. Handle it here.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000156 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
157}
158
159void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
160 MacroBuilder &Builder) const {
161 // Also include the ARMv8.1 defines
162 getTargetDefinesARMV81A(Opts, Builder);
163}
164
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000165void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
166 MacroBuilder &Builder) const {
Victor Camposdcf11c5e2019-12-02 12:13:04 +0000167 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000168 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
169 // Also include the Armv8.2 defines
170 getTargetDefinesARMV82A(Opts, Builder);
171}
172
173void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
174 MacroBuilder &Builder) const {
175 // Also include the Armv8.3 defines
Ties Stuij71ae2672020-03-26 08:17:29 +0000176 // FIXME: Armv8.4 makes __ARM_FEATURE_ATOMICS, defined in GCC, mandatory.
177 // Add and handle it here.
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000178 getTargetDefinesARMV83A(Opts, Builder);
179}
180
181void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
182 MacroBuilder &Builder) const {
183 // Also include the Armv8.4 defines
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000184 getTargetDefinesARMV84A(Opts, Builder);
185}
186
Ties Stuij71ae2672020-03-26 08:17:29 +0000187void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
188 MacroBuilder &Builder) const {
189 // Also include the Armv8.5 defines
190 // FIXME: Armv8.6 makes the following extensions mandatory:
191 // - __ARM_FEATURE_BF16
192 // - __ARM_FEATURE_MATMUL_INT8
193 // Handle them here.
194 getTargetDefinesARMV85A(Opts, Builder);
195}
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000196
Tim Northoverad4c5db2017-07-24 17:06:23 +0000197void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
198 MacroBuilder &Builder) const {
199 // Target identification.
200 Builder.defineMacro("__aarch64__");
Eli Friedman39ceea32018-10-17 21:07:11 +0000201 // For bare-metal.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000202 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
Eli Friedman39ceea32018-10-17 21:07:11 +0000203 getTriple().isOSBinFormatELF())
Tim Northoverad4c5db2017-07-24 17:06:23 +0000204 Builder.defineMacro("__ELF__");
205
206 // Target properties.
Tim Northover44e58792018-09-18 10:34:39 +0100207 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
Martin Storsjo588a3e52017-07-31 20:40:53 +0000208 Builder.defineMacro("_LP64");
209 Builder.defineMacro("__LP64__");
210 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000211
Roland McGrathd2e949e2020-02-21 21:25:57 -0800212 std::string CodeModel = getTargetOpts().CodeModel;
213 if (CodeModel == "default")
214 CodeModel = "small";
215 for (char &c : CodeModel)
216 c = toupper(c);
217 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
218
Tim Northoverad4c5db2017-07-24 17:06:23 +0000219 // ACLE predefines. Many can only have one possible value on v8 AArch64.
220 Builder.defineMacro("__ARM_ACLE", "200");
221 Builder.defineMacro("__ARM_ARCH", "8");
222 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
223
224 Builder.defineMacro("__ARM_64BIT_STATE", "1");
225 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
226 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
227
228 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
229 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
230 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
231 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
232 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
233 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
234 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
235
236 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
237
238 // 0xe implies support for half, single and double precision operations.
239 Builder.defineMacro("__ARM_FP", "0xE");
240
241 // PCS specifies this for SysV variants, which is all we support. Other ABIs
242 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
243 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
244 Builder.defineMacro("__ARM_FP16_ARGS", "1");
245
246 if (Opts.UnsafeFPMath)
247 Builder.defineMacro("__ARM_FP_FAST", "1");
248
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000249 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000250 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000251
252 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
253
254 if (FPU & NeonMode) {
255 Builder.defineMacro("__ARM_NEON", "1");
256 // 64-bit NEON supports half, single and double precision operations.
257 Builder.defineMacro("__ARM_NEON_FP", "0xE");
258 }
259
Momchil Velikove14cfe22019-07-17 11:24:37 +0000260 if (HasCRC)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000261 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
262
Momchil Velikove14cfe22019-07-17 11:24:37 +0000263 if (HasCrypto)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000264 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
265
Momchil Velikove14cfe22019-07-17 11:24:37 +0000266 if (HasUnaligned)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000267 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
268
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000269 if ((FPU & NeonMode) && HasFullFP16)
270 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000271 if (HasFullFP16)
272 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000273
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000274 if (HasDotProd)
275 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
276
Javed Absar18b0c402019-04-26 21:08:11 +0000277 if (HasMTE)
278 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
279
Momchil Velikova36d3142019-07-31 12:52:17 +0000280 if (HasTME)
281 Builder.defineMacro("__ARM_FEATURE_TME", "1");
282
Bryan Chan223307b2018-10-25 23:47:00 +0000283 if ((FPU & NeonMode) && HasFP16FML)
284 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
285
Tim Northoverad4c5db2017-07-24 17:06:23 +0000286 switch (ArchKind) {
287 default:
288 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000289 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000290 getTargetDefinesARMV81A(Opts, Builder);
291 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000292 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000293 getTargetDefinesARMV82A(Opts, Builder);
294 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000295 case llvm::AArch64::ArchKind::ARMV8_3A:
296 getTargetDefinesARMV83A(Opts, Builder);
297 break;
298 case llvm::AArch64::ArchKind::ARMV8_4A:
299 getTargetDefinesARMV84A(Opts, Builder);
300 break;
301 case llvm::AArch64::ArchKind::ARMV8_5A:
302 getTargetDefinesARMV85A(Opts, Builder);
303 break;
Ties Stuij71ae2672020-03-26 08:17:29 +0000304 case llvm::AArch64::ArchKind::ARMV8_6A:
305 getTargetDefinesARMV86A(Opts, Builder);
306 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000307 }
308
309 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
310 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
311 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
312 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
313 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
314}
315
316ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
317 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
318 Builtin::FirstTSBuiltin);
319}
320
321bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
322 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
323 (Feature == "neon" && (FPU & NeonMode)) ||
324 (Feature == "sve" && (FPU & SveMode));
325}
326
327bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
328 DiagnosticsEngine &Diags) {
329 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000330 HasCRC = false;
331 HasCrypto = false;
332 HasUnaligned = true;
333 HasFullFP16 = false;
334 HasDotProd = false;
335 HasFP16FML = false;
336 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000337 HasTME = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000338 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000339
340 for (const auto &Feature : Features) {
341 if (Feature == "+neon")
342 FPU |= NeonMode;
343 if (Feature == "+sve")
344 FPU |= SveMode;
345 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000346 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000347 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000348 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000349 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000350 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000351 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000352 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000353 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000354 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000355 if (Feature == "+v8.3a")
356 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
357 if (Feature == "+v8.4a")
358 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
359 if (Feature == "+v8.5a")
360 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Ties Stuij71ae2672020-03-26 08:17:29 +0000361 if (Feature == "+v8.6a")
362 ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000363 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000364 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000365 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000366 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000367 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000368 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000369 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000370 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000371 if (Feature == "+tme")
372 HasTME = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000373 }
374
375 setDataLayout();
376
377 return true;
378}
379
380TargetInfo::CallingConvCheckResult
381AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
382 switch (CC) {
383 case CC_C:
384 case CC_Swift:
385 case CC_PreserveMost:
386 case CC_PreserveAll:
387 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000388 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000389 case CC_Win64:
390 return CCCR_OK;
391 default:
392 return CCCR_Warning;
393 }
394}
395
396bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
397
398TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
399 return TargetInfo::AArch64ABIBuiltinVaList;
400}
401
Erich Keaneebba5922017-07-21 22:37:03 +0000402const char *const AArch64TargetInfo::GCCRegNames[] = {
403 // 32-bit Integer registers
404 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
405 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
406 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
407
408 // 64-bit Integer registers
409 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
410 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
411 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
412
413 // 32-bit floating point regsisters
414 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
415 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
416 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
417
418 // 64-bit floating point regsisters
419 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
420 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
421 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
422
Sander de Smalen2b290882019-07-24 08:42:34 +0000423 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000424 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
425 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000426 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
427
428 // SVE vector registers
429 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
430 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
431 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
432
433 // SVE predicate registers
434 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
435 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000436};
437
438ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
439 return llvm::makeArrayRef(GCCRegNames);
440}
441
442const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000443 {{"w31"}, "wsp"},
444 {{"x31"}, "sp"},
445 // GCC rN registers are aliases of xN registers.
446 {{"r0"}, "x0"},
447 {{"r1"}, "x1"},
448 {{"r2"}, "x2"},
449 {{"r3"}, "x3"},
450 {{"r4"}, "x4"},
451 {{"r5"}, "x5"},
452 {{"r6"}, "x6"},
453 {{"r7"}, "x7"},
454 {{"r8"}, "x8"},
455 {{"r9"}, "x9"},
456 {{"r10"}, "x10"},
457 {{"r11"}, "x11"},
458 {{"r12"}, "x12"},
459 {{"r13"}, "x13"},
460 {{"r14"}, "x14"},
461 {{"r15"}, "x15"},
462 {{"r16"}, "x16"},
463 {{"r17"}, "x17"},
464 {{"r18"}, "x18"},
465 {{"r19"}, "x19"},
466 {{"r20"}, "x20"},
467 {{"r21"}, "x21"},
468 {{"r22"}, "x22"},
469 {{"r23"}, "x23"},
470 {{"r24"}, "x24"},
471 {{"r25"}, "x25"},
472 {{"r26"}, "x26"},
473 {{"r27"}, "x27"},
474 {{"r28"}, "x28"},
475 {{"r29", "x29"}, "fp"},
476 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000477 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
478 // don't want to substitute one of these for a different-sized one.
479};
480
481ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
482 return llvm::makeArrayRef(GCCRegAliases);
483}
484
Tim Northoverad4c5db2017-07-24 17:06:23 +0000485bool AArch64TargetInfo::validateAsmConstraint(
486 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
487 switch (*Name) {
488 default:
489 return false;
490 case 'w': // Floating point and SIMD registers (V0-V31)
491 Info.setAllowsRegister();
492 return true;
493 case 'I': // Constant that can be used with an ADD instruction
494 case 'J': // Constant that can be used with a SUB instruction
495 case 'K': // Constant that can be used with a 32-bit logical instruction
496 case 'L': // Constant that can be used with a 64-bit logical instruction
497 case 'M': // Constant that can be used as a 32-bit MOV immediate
498 case 'N': // Constant that can be used as a 64-bit MOV immediate
499 case 'Y': // Floating point constant zero
500 case 'Z': // Integer constant zero
501 return true;
502 case 'Q': // A memory reference with base register and no offset
503 Info.setAllowsMemory();
504 return true;
505 case 'S': // A symbolic address
506 Info.setAllowsRegister();
507 return true;
508 case 'U':
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000509 if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) {
510 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7)
511 Info.setAllowsRegister();
512 Name += 2;
513 return true;
514 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000515 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
516 // Utf: A memory address suitable for ldp/stp in TF mode.
517 // Usa: An absolute symbolic address.
518 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000519
520 // Better to return an error saying that it's an unrecognised constraint
521 // even if this is a valid constraint in gcc.
522 return false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000523 case 'z': // Zero register, wzr or xzr
524 Info.setAllowsRegister();
525 return true;
526 case 'x': // Floating point and SIMD registers (V0-V15)
527 Info.setAllowsRegister();
528 return true;
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000529 case 'y': // SVE registers (V0-V7)
530 Info.setAllowsRegister();
531 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000532 }
533 return false;
534}
Erich Keaneebba5922017-07-21 22:37:03 +0000535
Tim Northoverad4c5db2017-07-24 17:06:23 +0000536bool AArch64TargetInfo::validateConstraintModifier(
537 StringRef Constraint, char Modifier, unsigned Size,
538 std::string &SuggestedModifier) const {
539 // Strip off constraint modifiers.
540 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
541 Constraint = Constraint.substr(1);
542
543 switch (Constraint[0]) {
544 default:
545 return true;
546 case 'z':
547 case 'r': {
548 switch (Modifier) {
549 case 'x':
550 case 'w':
551 // For now assume that the person knows what they're
552 // doing with the modifier.
553 return true;
554 default:
555 // By default an 'r' constraint will be in the 'x'
556 // registers.
557 if (Size == 64)
558 return true;
559
560 SuggestedModifier = "w";
561 return false;
562 }
563 }
564 }
565}
566
567const char *AArch64TargetInfo::getClobbers() const { return ""; }
568
569int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
570 if (RegNo == 0)
571 return 0;
572 if (RegNo == 1)
573 return 1;
574 return -1;
575}
576
Tim Northover44e58792018-09-18 10:34:39 +0100577bool AArch64TargetInfo::hasInt128Type() const { return true; }
578
Tim Northoverad4c5db2017-07-24 17:06:23 +0000579AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
580 const TargetOptions &Opts)
581 : AArch64TargetInfo(Triple, Opts) {}
582
583void AArch64leTargetInfo::setDataLayout() {
Tim Northover44e58792018-09-18 10:34:39 +0100584 if (getTriple().isOSBinFormatMachO()) {
585 if(getTriple().isArch32Bit())
586 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
587 else
588 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
589 } else
Tim Northoverad4c5db2017-07-24 17:06:23 +0000590 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
591}
592
593void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
594 MacroBuilder &Builder) const {
595 Builder.defineMacro("__AARCH64EL__");
596 AArch64TargetInfo::getTargetDefines(Opts, Builder);
597}
598
599AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
600 const TargetOptions &Opts)
601 : AArch64TargetInfo(Triple, Opts) {}
602
603void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
604 MacroBuilder &Builder) const {
605 Builder.defineMacro("__AARCH64EB__");
606 Builder.defineMacro("__AARCH_BIG_ENDIAN");
607 Builder.defineMacro("__ARM_BIG_ENDIAN");
608 AArch64TargetInfo::getTargetDefines(Opts, Builder);
609}
610
611void AArch64beTargetInfo::setDataLayout() {
612 assert(!getTriple().isOSBinFormatMachO());
613 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
614}
615
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000616WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
617 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000618 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
619
620 // This is an LLP64 platform.
621 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000622 IntWidth = IntAlign = 32;
623 LongWidth = LongAlign = 32;
624 DoubleAlign = LongLongAlign = 64;
625 LongDoubleWidth = LongDoubleAlign = 64;
626 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
627 IntMaxType = SignedLongLong;
628 Int64Type = SignedLongLong;
629 SizeType = UnsignedLongLong;
630 PtrDiffType = SignedLongLong;
631 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000632}
633
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000634void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000635 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
636}
637
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000638TargetInfo::BuiltinVaListKind
639WindowsARM64TargetInfo::getBuiltinVaListKind() const {
640 return TargetInfo::CharPtrBuiltinVaList;
641}
642
643TargetInfo::CallingConvCheckResult
644WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
645 switch (CC) {
646 case CC_X86StdCall:
647 case CC_X86ThisCall:
648 case CC_X86FastCall:
649 case CC_X86VectorCall:
650 return CCCR_Ignore;
651 case CC_C:
652 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000653 case CC_PreserveMost:
654 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000655 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000656 case CC_Win64:
657 return CCCR_OK;
658 default:
659 return CCCR_Warning;
660 }
661}
662
663MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
664 const TargetOptions &Opts)
665 : WindowsARM64TargetInfo(Triple, Opts) {
666 TheCXXABI.set(TargetCXXABI::Microsoft);
667}
668
Tim Northoverad4c5db2017-07-24 17:06:23 +0000669void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
670 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000671 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
672 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000673}
674
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000675TargetInfo::CallingConvKind
676MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
677 return CCK_MicrosoftWin64;
678}
679
Tom Tanb7c6d952019-05-02 00:38:14 +0000680unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
681 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
682
683 // MSVC does size based alignment for arm64 based on alignment section in
684 // below document, replicate that to keep alignment consistent with object
685 // files compiled by MSVC.
686 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
687 if (TypeSize >= 512) { // TypeSize >= 64 bytes
688 Align = std::max(Align, 128u); // align type at least 16 bytes
689 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
690 Align = std::max(Align, 64u); // align type at least 8 butes
691 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
692 Align = std::max(Align, 32u); // align type at least 4 bytes
693 }
694 return Align;
695}
696
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000697MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
698 const TargetOptions &Opts)
699 : WindowsARM64TargetInfo(Triple, Opts) {
700 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000701}
702
703DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
704 const TargetOptions &Opts)
705 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
706 Int64Type = SignedLongLong;
Tim Northover44e58792018-09-18 10:34:39 +0100707 if (getTriple().isArch32Bit())
708 IntMaxType = SignedLongLong;
709
710 WCharType = SignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000711 UseSignedCharForObjCBool = false;
712
713 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
714 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
715
Tim Northover44e58792018-09-18 10:34:39 +0100716 UseZeroLengthBitfieldAlignment = false;
717
718 if (getTriple().isArch32Bit()) {
719 UseBitFieldTypeAlignment = false;
720 ZeroLengthBitfieldBoundary = 32;
721 UseZeroLengthBitfieldAlignment = true;
722 TheCXXABI.set(TargetCXXABI::WatchOS);
723 } else
724 TheCXXABI.set(TargetCXXABI::iOS64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000725}
726
727void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
728 const llvm::Triple &Triple,
729 MacroBuilder &Builder) const {
730 Builder.defineMacro("__AARCH64_SIMD__");
Tim Northover44e58792018-09-18 10:34:39 +0100731 if (Triple.isArch32Bit())
732 Builder.defineMacro("__ARM64_ARCH_8_32__");
733 else
734 Builder.defineMacro("__ARM64_ARCH_8__");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000735 Builder.defineMacro("__ARM_NEON__");
736 Builder.defineMacro("__LITTLE_ENDIAN__");
737 Builder.defineMacro("__REGISTER_PREFIX__", "");
738 Builder.defineMacro("__arm64", "1");
739 Builder.defineMacro("__arm64__", "1");
740
741 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
742}
743
744TargetInfo::BuiltinVaListKind
745DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
746 return TargetInfo::CharPtrBuiltinVaList;
747}
748
749// 64-bit RenderScript is aarch64
750RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
751 const TargetOptions &Opts)
752 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
753 Triple.getOSName(),
754 Triple.getEnvironmentName()),
755 Opts) {
756 IsRenderScriptTarget = true;
757}
758
759void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
760 MacroBuilder &Builder) const {
761 Builder.defineMacro("__RENDERSCRIPT__");
762 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
763}