blob: 5357d31ee64c8c32c6b300097a3882739e2a369f [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
Luke Geeson832cd742020-04-09 17:21:19 +0100283 if (HasMatMul)
284 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
285
Bryan Chan223307b2018-10-25 23:47:00 +0000286 if ((FPU & NeonMode) && HasFP16FML)
287 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
288
Daniel Kiss37ced5a2020-04-02 12:10:41 +0200289 if (Opts.hasSignReturnAddress()) {
290 // Bitmask:
291 // 0: Protection using the A key
292 // 1: Protection using the B key
293 // 2: Protection including leaf functions
294 unsigned Value = 0;
295
296 if (Opts.isSignReturnAddressWithAKey())
297 Value |= (1 << 0);
298 else
299 Value |= (1 << 1);
300
301 if (Opts.isSignReturnAddressScopeAll())
302 Value |= (1 << 2);
303
304 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
305 }
306
307 if (Opts.BranchTargetEnforcement)
308 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
309
Tim Northoverad4c5db2017-07-24 17:06:23 +0000310 switch (ArchKind) {
311 default:
312 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000313 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000314 getTargetDefinesARMV81A(Opts, Builder);
315 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000316 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000317 getTargetDefinesARMV82A(Opts, Builder);
318 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000319 case llvm::AArch64::ArchKind::ARMV8_3A:
320 getTargetDefinesARMV83A(Opts, Builder);
321 break;
322 case llvm::AArch64::ArchKind::ARMV8_4A:
323 getTargetDefinesARMV84A(Opts, Builder);
324 break;
325 case llvm::AArch64::ArchKind::ARMV8_5A:
326 getTargetDefinesARMV85A(Opts, Builder);
327 break;
Ties Stuij71ae2672020-03-26 08:17:29 +0000328 case llvm::AArch64::ArchKind::ARMV8_6A:
329 getTargetDefinesARMV86A(Opts, Builder);
330 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000331 }
332
333 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
334 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
335 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
336 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
337 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
338}
339
340ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
341 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
342 Builtin::FirstTSBuiltin);
343}
344
345bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
346 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
347 (Feature == "neon" && (FPU & NeonMode)) ||
348 (Feature == "sve" && (FPU & SveMode));
349}
350
351bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
352 DiagnosticsEngine &Diags) {
353 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000354 HasCRC = false;
355 HasCrypto = false;
356 HasUnaligned = true;
357 HasFullFP16 = false;
358 HasDotProd = false;
359 HasFP16FML = false;
360 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000361 HasTME = false;
Luke Geeson832cd742020-04-09 17:21:19 +0100362 HasMatMul = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000363 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000364
365 for (const auto &Feature : Features) {
366 if (Feature == "+neon")
367 FPU |= NeonMode;
368 if (Feature == "+sve")
369 FPU |= SveMode;
370 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000371 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000372 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000373 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000374 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000375 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000376 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000377 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000378 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000379 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000380 if (Feature == "+v8.3a")
381 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
382 if (Feature == "+v8.4a")
383 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
384 if (Feature == "+v8.5a")
385 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Ties Stuij71ae2672020-03-26 08:17:29 +0000386 if (Feature == "+v8.6a")
387 ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000388 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000389 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000390 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000391 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000392 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000393 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000394 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000395 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000396 if (Feature == "+tme")
397 HasTME = true;
Luke Geeson832cd742020-04-09 17:21:19 +0100398 if (Feature == "+i8mm")
399 HasMatMul = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000400 }
401
402 setDataLayout();
403
404 return true;
405}
406
407TargetInfo::CallingConvCheckResult
408AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
409 switch (CC) {
410 case CC_C:
411 case CC_Swift:
412 case CC_PreserveMost:
413 case CC_PreserveAll:
414 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000415 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000416 case CC_Win64:
417 return CCCR_OK;
418 default:
419 return CCCR_Warning;
420 }
421}
422
423bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
424
425TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
426 return TargetInfo::AArch64ABIBuiltinVaList;
427}
428
Erich Keaneebba5922017-07-21 22:37:03 +0000429const char *const AArch64TargetInfo::GCCRegNames[] = {
430 // 32-bit Integer registers
431 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
432 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
433 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
434
435 // 64-bit Integer registers
436 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
437 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
438 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
439
440 // 32-bit floating point regsisters
441 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
442 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
443 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
444
445 // 64-bit floating point regsisters
446 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
447 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
448 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
449
Sander de Smalen2b290882019-07-24 08:42:34 +0000450 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000451 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
452 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000453 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
454
455 // SVE vector registers
456 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
457 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
458 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
459
460 // SVE predicate registers
461 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
462 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000463};
464
465ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
466 return llvm::makeArrayRef(GCCRegNames);
467}
468
469const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000470 {{"w31"}, "wsp"},
471 {{"x31"}, "sp"},
472 // GCC rN registers are aliases of xN registers.
473 {{"r0"}, "x0"},
474 {{"r1"}, "x1"},
475 {{"r2"}, "x2"},
476 {{"r3"}, "x3"},
477 {{"r4"}, "x4"},
478 {{"r5"}, "x5"},
479 {{"r6"}, "x6"},
480 {{"r7"}, "x7"},
481 {{"r8"}, "x8"},
482 {{"r9"}, "x9"},
483 {{"r10"}, "x10"},
484 {{"r11"}, "x11"},
485 {{"r12"}, "x12"},
486 {{"r13"}, "x13"},
487 {{"r14"}, "x14"},
488 {{"r15"}, "x15"},
489 {{"r16"}, "x16"},
490 {{"r17"}, "x17"},
491 {{"r18"}, "x18"},
492 {{"r19"}, "x19"},
493 {{"r20"}, "x20"},
494 {{"r21"}, "x21"},
495 {{"r22"}, "x22"},
496 {{"r23"}, "x23"},
497 {{"r24"}, "x24"},
498 {{"r25"}, "x25"},
499 {{"r26"}, "x26"},
500 {{"r27"}, "x27"},
501 {{"r28"}, "x28"},
502 {{"r29", "x29"}, "fp"},
503 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000504 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
505 // don't want to substitute one of these for a different-sized one.
506};
507
508ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
509 return llvm::makeArrayRef(GCCRegAliases);
510}
511
Tim Northoverad4c5db2017-07-24 17:06:23 +0000512bool AArch64TargetInfo::validateAsmConstraint(
513 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
514 switch (*Name) {
515 default:
516 return false;
517 case 'w': // Floating point and SIMD registers (V0-V31)
518 Info.setAllowsRegister();
519 return true;
520 case 'I': // Constant that can be used with an ADD instruction
521 case 'J': // Constant that can be used with a SUB instruction
522 case 'K': // Constant that can be used with a 32-bit logical instruction
523 case 'L': // Constant that can be used with a 64-bit logical instruction
524 case 'M': // Constant that can be used as a 32-bit MOV immediate
525 case 'N': // Constant that can be used as a 64-bit MOV immediate
526 case 'Y': // Floating point constant zero
527 case 'Z': // Integer constant zero
528 return true;
529 case 'Q': // A memory reference with base register and no offset
530 Info.setAllowsMemory();
531 return true;
532 case 'S': // A symbolic address
533 Info.setAllowsRegister();
534 return true;
535 case 'U':
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000536 if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) {
537 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7)
538 Info.setAllowsRegister();
539 Name += 2;
540 return true;
541 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000542 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
543 // Utf: A memory address suitable for ldp/stp in TF mode.
544 // Usa: An absolute symbolic address.
545 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000546
547 // Better to return an error saying that it's an unrecognised constraint
548 // even if this is a valid constraint in gcc.
549 return false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000550 case 'z': // Zero register, wzr or xzr
551 Info.setAllowsRegister();
552 return true;
553 case 'x': // Floating point and SIMD registers (V0-V15)
554 Info.setAllowsRegister();
555 return true;
Kerry McLaughlinaf649482020-03-17 10:27:29 +0000556 case 'y': // SVE registers (V0-V7)
557 Info.setAllowsRegister();
558 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000559 }
560 return false;
561}
Erich Keaneebba5922017-07-21 22:37:03 +0000562
Tim Northoverad4c5db2017-07-24 17:06:23 +0000563bool AArch64TargetInfo::validateConstraintModifier(
564 StringRef Constraint, char Modifier, unsigned Size,
565 std::string &SuggestedModifier) const {
566 // Strip off constraint modifiers.
567 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
568 Constraint = Constraint.substr(1);
569
570 switch (Constraint[0]) {
571 default:
572 return true;
573 case 'z':
574 case 'r': {
575 switch (Modifier) {
576 case 'x':
577 case 'w':
578 // For now assume that the person knows what they're
579 // doing with the modifier.
580 return true;
581 default:
582 // By default an 'r' constraint will be in the 'x'
583 // registers.
584 if (Size == 64)
585 return true;
586
587 SuggestedModifier = "w";
588 return false;
589 }
590 }
591 }
592}
593
594const char *AArch64TargetInfo::getClobbers() const { return ""; }
595
596int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
597 if (RegNo == 0)
598 return 0;
599 if (RegNo == 1)
600 return 1;
601 return -1;
602}
603
Tim Northover44e58792018-09-18 10:34:39 +0100604bool AArch64TargetInfo::hasInt128Type() const { return true; }
605
Tim Northoverad4c5db2017-07-24 17:06:23 +0000606AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
607 const TargetOptions &Opts)
608 : AArch64TargetInfo(Triple, Opts) {}
609
610void AArch64leTargetInfo::setDataLayout() {
Tim Northover44e58792018-09-18 10:34:39 +0100611 if (getTriple().isOSBinFormatMachO()) {
612 if(getTriple().isArch32Bit())
613 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
614 else
615 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
616 } else
Tim Northoverad4c5db2017-07-24 17:06:23 +0000617 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
618}
619
620void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
621 MacroBuilder &Builder) const {
622 Builder.defineMacro("__AARCH64EL__");
623 AArch64TargetInfo::getTargetDefines(Opts, Builder);
624}
625
626AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
627 const TargetOptions &Opts)
628 : AArch64TargetInfo(Triple, Opts) {}
629
630void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
631 MacroBuilder &Builder) const {
632 Builder.defineMacro("__AARCH64EB__");
633 Builder.defineMacro("__AARCH_BIG_ENDIAN");
634 Builder.defineMacro("__ARM_BIG_ENDIAN");
635 AArch64TargetInfo::getTargetDefines(Opts, Builder);
636}
637
638void AArch64beTargetInfo::setDataLayout() {
639 assert(!getTriple().isOSBinFormatMachO());
640 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
641}
642
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000643WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
644 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000645 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
646
647 // This is an LLP64 platform.
648 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000649 IntWidth = IntAlign = 32;
650 LongWidth = LongAlign = 32;
651 DoubleAlign = LongLongAlign = 64;
652 LongDoubleWidth = LongDoubleAlign = 64;
653 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
654 IntMaxType = SignedLongLong;
655 Int64Type = SignedLongLong;
656 SizeType = UnsignedLongLong;
657 PtrDiffType = SignedLongLong;
658 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000659}
660
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000661void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000662 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
663}
664
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000665TargetInfo::BuiltinVaListKind
666WindowsARM64TargetInfo::getBuiltinVaListKind() const {
667 return TargetInfo::CharPtrBuiltinVaList;
668}
669
670TargetInfo::CallingConvCheckResult
671WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
672 switch (CC) {
673 case CC_X86StdCall:
674 case CC_X86ThisCall:
675 case CC_X86FastCall:
676 case CC_X86VectorCall:
677 return CCCR_Ignore;
678 case CC_C:
679 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000680 case CC_PreserveMost:
681 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000682 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000683 case CC_Win64:
684 return CCCR_OK;
685 default:
686 return CCCR_Warning;
687 }
688}
689
690MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
691 const TargetOptions &Opts)
692 : WindowsARM64TargetInfo(Triple, Opts) {
693 TheCXXABI.set(TargetCXXABI::Microsoft);
694}
695
Tim Northoverad4c5db2017-07-24 17:06:23 +0000696void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
697 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000698 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
699 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000700}
701
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000702TargetInfo::CallingConvKind
703MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
704 return CCK_MicrosoftWin64;
705}
706
Tom Tanb7c6d952019-05-02 00:38:14 +0000707unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
708 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
709
710 // MSVC does size based alignment for arm64 based on alignment section in
711 // below document, replicate that to keep alignment consistent with object
712 // files compiled by MSVC.
713 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
714 if (TypeSize >= 512) { // TypeSize >= 64 bytes
715 Align = std::max(Align, 128u); // align type at least 16 bytes
716 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
717 Align = std::max(Align, 64u); // align type at least 8 butes
718 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
719 Align = std::max(Align, 32u); // align type at least 4 bytes
720 }
721 return Align;
722}
723
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000724MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
725 const TargetOptions &Opts)
726 : WindowsARM64TargetInfo(Triple, Opts) {
727 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000728}
729
730DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
731 const TargetOptions &Opts)
732 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
733 Int64Type = SignedLongLong;
Tim Northover44e58792018-09-18 10:34:39 +0100734 if (getTriple().isArch32Bit())
735 IntMaxType = SignedLongLong;
736
737 WCharType = SignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000738 UseSignedCharForObjCBool = false;
739
740 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
741 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
742
Tim Northover44e58792018-09-18 10:34:39 +0100743 UseZeroLengthBitfieldAlignment = false;
744
745 if (getTriple().isArch32Bit()) {
746 UseBitFieldTypeAlignment = false;
747 ZeroLengthBitfieldBoundary = 32;
748 UseZeroLengthBitfieldAlignment = true;
749 TheCXXABI.set(TargetCXXABI::WatchOS);
750 } else
751 TheCXXABI.set(TargetCXXABI::iOS64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000752}
753
754void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
755 const llvm::Triple &Triple,
756 MacroBuilder &Builder) const {
757 Builder.defineMacro("__AARCH64_SIMD__");
Tim Northover44e58792018-09-18 10:34:39 +0100758 if (Triple.isArch32Bit())
759 Builder.defineMacro("__ARM64_ARCH_8_32__");
760 else
761 Builder.defineMacro("__ARM64_ARCH_8__");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000762 Builder.defineMacro("__ARM_NEON__");
763 Builder.defineMacro("__LITTLE_ENDIAN__");
764 Builder.defineMacro("__REGISTER_PREFIX__", "");
765 Builder.defineMacro("__arm64", "1");
766 Builder.defineMacro("__arm64__", "1");
767
768 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
769}
770
771TargetInfo::BuiltinVaListKind
772DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
773 return TargetInfo::CharPtrBuiltinVaList;
774}
775
776// 64-bit RenderScript is aarch64
777RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
778 const TargetOptions &Opts)
779 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
780 Triple.getOSName(),
781 Triple.getEnvironmentName()),
782 Opts) {
783 IsRenderScriptTarget = true;
784}
785
786void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
787 MacroBuilder &Builder) const {
788 Builder.defineMacro("__RENDERSCRIPT__");
789 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
790}