blob: cba3e3ada7ea5fdedca8057666ec6fc56192ba99 [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"
14#include "clang/Basic/TargetBuiltins.h"
15#include "clang/Basic/TargetInfo.h"
16#include "llvm/ADT/ArrayRef.h"
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000017#include "llvm/ADT/StringExtras.h"
Momchil Velikovaa6d48f2019-11-15 11:34:47 +000018#include "llvm/ADT/StringSwitch.h"
19#include "llvm/Support/AArch64TargetParser.h"
Erich Keaneebba5922017-07-21 22:37:03 +000020
21using namespace clang;
22using namespace clang::targets;
23
Tim Northoverad4c5db2017-07-24 17:06:23 +000024const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
25#define BUILTIN(ID, TYPE, ATTRS) \
26 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
27#include "clang/Basic/BuiltinsNEON.def"
28
29#define BUILTIN(ID, TYPE, ATTRS) \
30 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
Martin Storsjod8a44ed2017-10-12 07:05:37 +000031#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
32 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
Martin Storsjo17c0f722018-07-18 06:15:09 +000033#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
34 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
Tim Northoverad4c5db2017-07-24 17:06:23 +000035#include "clang/Basic/BuiltinsAArch64.def"
36};
37
38AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
39 const TargetOptions &Opts)
40 : TargetInfo(Triple), ABI("aapcs") {
Michal Gorny5a409d02018-12-20 13:09:30 +000041 if (getTriple().isOSOpenBSD()) {
Tim Northoverad4c5db2017-07-24 17:06:23 +000042 Int64Type = SignedLongLong;
43 IntMaxType = SignedLongLong;
44 } else {
Michal Gorny5a409d02018-12-20 13:09:30 +000045 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000046 WCharType = UnsignedInt;
47
Tim Northoverad4c5db2017-07-24 17:06:23 +000048 Int64Type = SignedLong;
49 IntMaxType = SignedLong;
50 }
51
Sjoerd Meijer87793e72018-03-19 13:22:49 +000052 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
53 HasLegalHalfType = true;
Erich Keane1d1d4382019-01-25 17:27:57 +000054 HasFloat16 = true;
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000055
Tim Northover44e58792018-09-18 10:34:39 +010056 if (Triple.isArch64Bit())
57 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
58 else
59 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
60
Tim Northoverad4c5db2017-07-24 17:06:23 +000061 MaxVectorAlign = 128;
62 MaxAtomicInlineWidth = 128;
63 MaxAtomicPromoteWidth = 128;
64
65 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
66 LongDoubleFormat = &llvm::APFloat::IEEEquad();
67
68 // Make __builtin_ms_va_list available.
69 HasBuiltinMSVaList = true;
70
Richard Sandifordeb485fb2019-08-09 08:52:54 +000071 // Make the SVE types available. Note that this deliberately doesn't
72 // depend on SveMode, since in principle it should be possible to turn
73 // SVE on and off within a translation unit. It should also be possible
74 // to compile the global declaration:
75 //
76 // __SVInt8_t *ptr;
77 //
78 // even without SVE.
79 HasAArch64SVETypes = true;
80
Tim Northoverad4c5db2017-07-24 17:06:23 +000081 // {} in inline assembly are neon specifiers, not assembly variant
82 // specifiers.
83 NoAsmVariants = true;
84
85 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
86 // contributes to the alignment of the containing aggregate in the same way
87 // a plain (non bit-field) member of that type would, without exception for
88 // zero-sized or anonymous bit-fields."
89 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
90 UseZeroLengthBitfieldAlignment = true;
91
92 // AArch64 targets default to using the ARM C++ ABI.
93 TheCXXABI.set(TargetCXXABI::GenericAArch64);
94
95 if (Triple.getOS() == llvm::Triple::Linux)
96 this->MCountName = "\01_mcount";
97 else if (Triple.getOS() == llvm::Triple::UnknownOS)
98 this->MCountName =
99 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
100}
101
102StringRef AArch64TargetInfo::getABI() const { return ABI; }
103
104bool AArch64TargetInfo::setABI(const std::string &Name) {
105 if (Name != "aapcs" && Name != "darwinpcs")
106 return false;
107
108 ABI = Name;
109 return true;
110}
111
Momchil Velikovaa6d48f2019-11-15 11:34:47 +0000112bool AArch64TargetInfo::validateBranchProtection(StringRef Spec,
113 BranchProtectionInfo &BPI,
114 StringRef &Err) const {
115 llvm::AArch64::ParsedBranchProtection PBP;
116 if (!llvm::AArch64::parseBranchProtection(Spec, PBP, Err))
117 return false;
118
119 BPI.SignReturnAddr =
120 llvm::StringSwitch<CodeGenOptions::SignReturnAddressScope>(PBP.Scope)
121 .Case("non-leaf", CodeGenOptions::SignReturnAddressScope::NonLeaf)
122 .Case("all", CodeGenOptions::SignReturnAddressScope::All)
123 .Default(CodeGenOptions::SignReturnAddressScope::None);
124
125 if (PBP.Key == "a_key")
126 BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::AKey;
127 else
128 BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::BKey;
129
130 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
131 return true;
132}
133
Tim Northoverad4c5db2017-07-24 17:06:23 +0000134bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
135 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000136 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000137}
138
139bool AArch64TargetInfo::setCPU(const std::string &Name) {
140 return isValidCPUName(Name);
141}
142
Erich Keane3ec17432018-02-08 23:14:15 +0000143void AArch64TargetInfo::fillValidCPUList(
144 SmallVectorImpl<StringRef> &Values) const {
145 llvm::AArch64::fillValidCPUArchList(Values);
146}
147
Tim Northoverad4c5db2017-07-24 17:06:23 +0000148void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
149 MacroBuilder &Builder) const {
150 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
151}
152
153void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
154 MacroBuilder &Builder) const {
155 // Also include the ARMv8.1 defines
156 getTargetDefinesARMV81A(Opts, Builder);
157}
158
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000159void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
160 MacroBuilder &Builder) const {
Victor Camposdcf11c5e2019-12-02 12:13:04 +0000161 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000162 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
163 // Also include the Armv8.2 defines
164 getTargetDefinesARMV82A(Opts, Builder);
165}
166
167void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
168 MacroBuilder &Builder) const {
169 // Also include the Armv8.3 defines
170 // FIXME: Armv8.4 makes some extensions mandatory. Handle them here.
171 getTargetDefinesARMV83A(Opts, Builder);
172}
173
174void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
175 MacroBuilder &Builder) const {
176 // Also include the Armv8.4 defines
177 // FIXME: Armv8.5 makes some extensions mandatory. Handle them here.
178 getTargetDefinesARMV84A(Opts, Builder);
179}
180
181
Tim Northoverad4c5db2017-07-24 17:06:23 +0000182void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
183 MacroBuilder &Builder) const {
184 // Target identification.
185 Builder.defineMacro("__aarch64__");
Eli Friedman39ceea32018-10-17 21:07:11 +0000186 // For bare-metal.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000187 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
Eli Friedman39ceea32018-10-17 21:07:11 +0000188 getTriple().isOSBinFormatELF())
Tim Northoverad4c5db2017-07-24 17:06:23 +0000189 Builder.defineMacro("__ELF__");
190
191 // Target properties.
Tim Northover44e58792018-09-18 10:34:39 +0100192 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
Martin Storsjo588a3e52017-07-31 20:40:53 +0000193 Builder.defineMacro("_LP64");
194 Builder.defineMacro("__LP64__");
195 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000196
197 // ACLE predefines. Many can only have one possible value on v8 AArch64.
198 Builder.defineMacro("__ARM_ACLE", "200");
199 Builder.defineMacro("__ARM_ARCH", "8");
200 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
201
202 Builder.defineMacro("__ARM_64BIT_STATE", "1");
203 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
204 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
205
206 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
207 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
208 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
209 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
210 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
211 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
212 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
213
214 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
215
216 // 0xe implies support for half, single and double precision operations.
217 Builder.defineMacro("__ARM_FP", "0xE");
218
219 // PCS specifies this for SysV variants, which is all we support. Other ABIs
220 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
221 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
222 Builder.defineMacro("__ARM_FP16_ARGS", "1");
223
224 if (Opts.UnsafeFPMath)
225 Builder.defineMacro("__ARM_FP_FAST", "1");
226
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000227 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000228 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000229
230 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
231
232 if (FPU & NeonMode) {
233 Builder.defineMacro("__ARM_NEON", "1");
234 // 64-bit NEON supports half, single and double precision operations.
235 Builder.defineMacro("__ARM_NEON_FP", "0xE");
236 }
237
Momchil Velikove14cfe22019-07-17 11:24:37 +0000238 if (HasCRC)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000239 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
240
Momchil Velikove14cfe22019-07-17 11:24:37 +0000241 if (HasCrypto)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000242 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
243
Momchil Velikove14cfe22019-07-17 11:24:37 +0000244 if (HasUnaligned)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000245 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
246
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000247 if ((FPU & NeonMode) && HasFullFP16)
248 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000249 if (HasFullFP16)
250 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000251
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000252 if (HasDotProd)
253 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
254
Javed Absar18b0c402019-04-26 21:08:11 +0000255 if (HasMTE)
256 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
257
Momchil Velikova36d3142019-07-31 12:52:17 +0000258 if (HasTME)
259 Builder.defineMacro("__ARM_FEATURE_TME", "1");
260
Bryan Chan223307b2018-10-25 23:47:00 +0000261 if ((FPU & NeonMode) && HasFP16FML)
262 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
263
Tim Northoverad4c5db2017-07-24 17:06:23 +0000264 switch (ArchKind) {
265 default:
266 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000267 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000268 getTargetDefinesARMV81A(Opts, Builder);
269 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000270 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000271 getTargetDefinesARMV82A(Opts, Builder);
272 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000273 case llvm::AArch64::ArchKind::ARMV8_3A:
274 getTargetDefinesARMV83A(Opts, Builder);
275 break;
276 case llvm::AArch64::ArchKind::ARMV8_4A:
277 getTargetDefinesARMV84A(Opts, Builder);
278 break;
279 case llvm::AArch64::ArchKind::ARMV8_5A:
280 getTargetDefinesARMV85A(Opts, Builder);
281 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000282 }
283
284 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
285 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
286 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
287 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
288 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
289}
290
291ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
292 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
293 Builtin::FirstTSBuiltin);
294}
295
296bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
297 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
298 (Feature == "neon" && (FPU & NeonMode)) ||
299 (Feature == "sve" && (FPU & SveMode));
300}
301
302bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
303 DiagnosticsEngine &Diags) {
304 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000305 HasCRC = false;
306 HasCrypto = false;
307 HasUnaligned = true;
308 HasFullFP16 = false;
309 HasDotProd = false;
310 HasFP16FML = false;
311 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000312 HasTME = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000313 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000314
315 for (const auto &Feature : Features) {
316 if (Feature == "+neon")
317 FPU |= NeonMode;
318 if (Feature == "+sve")
319 FPU |= SveMode;
320 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000321 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000322 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000323 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000324 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000325 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000326 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000327 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000328 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000329 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000330 if (Feature == "+v8.3a")
331 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
332 if (Feature == "+v8.4a")
333 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
334 if (Feature == "+v8.5a")
335 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000336 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000337 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000338 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000339 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000340 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000341 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000342 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000343 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000344 if (Feature == "+tme")
345 HasTME = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000346 }
347
348 setDataLayout();
349
350 return true;
351}
352
353TargetInfo::CallingConvCheckResult
354AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
355 switch (CC) {
356 case CC_C:
357 case CC_Swift:
358 case CC_PreserveMost:
359 case CC_PreserveAll:
360 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000361 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000362 case CC_Win64:
363 return CCCR_OK;
364 default:
365 return CCCR_Warning;
366 }
367}
368
369bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
370
371TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
372 return TargetInfo::AArch64ABIBuiltinVaList;
373}
374
Erich Keaneebba5922017-07-21 22:37:03 +0000375const char *const AArch64TargetInfo::GCCRegNames[] = {
376 // 32-bit Integer registers
377 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
378 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
379 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
380
381 // 64-bit Integer registers
382 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
383 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
384 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
385
386 // 32-bit floating point regsisters
387 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
388 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
389 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
390
391 // 64-bit floating point regsisters
392 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
393 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
394 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
395
Sander de Smalen2b290882019-07-24 08:42:34 +0000396 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000397 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
398 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000399 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
400
401 // SVE vector registers
402 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
403 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
404 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
405
406 // SVE predicate registers
407 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
408 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000409};
410
411ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
412 return llvm::makeArrayRef(GCCRegNames);
413}
414
415const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000416 {{"w31"}, "wsp"},
417 {{"x31"}, "sp"},
418 // GCC rN registers are aliases of xN registers.
419 {{"r0"}, "x0"},
420 {{"r1"}, "x1"},
421 {{"r2"}, "x2"},
422 {{"r3"}, "x3"},
423 {{"r4"}, "x4"},
424 {{"r5"}, "x5"},
425 {{"r6"}, "x6"},
426 {{"r7"}, "x7"},
427 {{"r8"}, "x8"},
428 {{"r9"}, "x9"},
429 {{"r10"}, "x10"},
430 {{"r11"}, "x11"},
431 {{"r12"}, "x12"},
432 {{"r13"}, "x13"},
433 {{"r14"}, "x14"},
434 {{"r15"}, "x15"},
435 {{"r16"}, "x16"},
436 {{"r17"}, "x17"},
437 {{"r18"}, "x18"},
438 {{"r19"}, "x19"},
439 {{"r20"}, "x20"},
440 {{"r21"}, "x21"},
441 {{"r22"}, "x22"},
442 {{"r23"}, "x23"},
443 {{"r24"}, "x24"},
444 {{"r25"}, "x25"},
445 {{"r26"}, "x26"},
446 {{"r27"}, "x27"},
447 {{"r28"}, "x28"},
448 {{"r29", "x29"}, "fp"},
449 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000450 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
451 // don't want to substitute one of these for a different-sized one.
452};
453
454ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
455 return llvm::makeArrayRef(GCCRegAliases);
456}
457
Tim Northoverad4c5db2017-07-24 17:06:23 +0000458bool AArch64TargetInfo::validateAsmConstraint(
459 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
460 switch (*Name) {
461 default:
462 return false;
463 case 'w': // Floating point and SIMD registers (V0-V31)
464 Info.setAllowsRegister();
465 return true;
466 case 'I': // Constant that can be used with an ADD instruction
467 case 'J': // Constant that can be used with a SUB instruction
468 case 'K': // Constant that can be used with a 32-bit logical instruction
469 case 'L': // Constant that can be used with a 64-bit logical instruction
470 case 'M': // Constant that can be used as a 32-bit MOV immediate
471 case 'N': // Constant that can be used as a 64-bit MOV immediate
472 case 'Y': // Floating point constant zero
473 case 'Z': // Integer constant zero
474 return true;
475 case 'Q': // A memory reference with base register and no offset
476 Info.setAllowsMemory();
477 return true;
478 case 'S': // A symbolic address
479 Info.setAllowsRegister();
480 return true;
481 case 'U':
482 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
483 // Utf: A memory address suitable for ldp/stp in TF mode.
484 // Usa: An absolute symbolic address.
485 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
486 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
487 case 'z': // Zero register, wzr or xzr
488 Info.setAllowsRegister();
489 return true;
490 case 'x': // Floating point and SIMD registers (V0-V15)
491 Info.setAllowsRegister();
492 return true;
493 }
494 return false;
495}
Erich Keaneebba5922017-07-21 22:37:03 +0000496
Tim Northoverad4c5db2017-07-24 17:06:23 +0000497bool AArch64TargetInfo::validateConstraintModifier(
498 StringRef Constraint, char Modifier, unsigned Size,
499 std::string &SuggestedModifier) const {
500 // Strip off constraint modifiers.
501 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
502 Constraint = Constraint.substr(1);
503
504 switch (Constraint[0]) {
505 default:
506 return true;
507 case 'z':
508 case 'r': {
509 switch (Modifier) {
510 case 'x':
511 case 'w':
512 // For now assume that the person knows what they're
513 // doing with the modifier.
514 return true;
515 default:
516 // By default an 'r' constraint will be in the 'x'
517 // registers.
518 if (Size == 64)
519 return true;
520
521 SuggestedModifier = "w";
522 return false;
523 }
524 }
525 }
526}
527
528const char *AArch64TargetInfo::getClobbers() const { return ""; }
529
530int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
531 if (RegNo == 0)
532 return 0;
533 if (RegNo == 1)
534 return 1;
535 return -1;
536}
537
Tim Northover44e58792018-09-18 10:34:39 +0100538bool AArch64TargetInfo::hasInt128Type() const { return true; }
539
Tim Northoverad4c5db2017-07-24 17:06:23 +0000540AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
541 const TargetOptions &Opts)
542 : AArch64TargetInfo(Triple, Opts) {}
543
544void AArch64leTargetInfo::setDataLayout() {
Tim Northover44e58792018-09-18 10:34:39 +0100545 if (getTriple().isOSBinFormatMachO()) {
546 if(getTriple().isArch32Bit())
547 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
548 else
549 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
550 } else
Tim Northoverad4c5db2017-07-24 17:06:23 +0000551 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
552}
553
554void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
555 MacroBuilder &Builder) const {
556 Builder.defineMacro("__AARCH64EL__");
557 AArch64TargetInfo::getTargetDefines(Opts, Builder);
558}
559
560AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
561 const TargetOptions &Opts)
562 : AArch64TargetInfo(Triple, Opts) {}
563
564void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
565 MacroBuilder &Builder) const {
566 Builder.defineMacro("__AARCH64EB__");
567 Builder.defineMacro("__AARCH_BIG_ENDIAN");
568 Builder.defineMacro("__ARM_BIG_ENDIAN");
569 AArch64TargetInfo::getTargetDefines(Opts, Builder);
570}
571
572void AArch64beTargetInfo::setDataLayout() {
573 assert(!getTriple().isOSBinFormatMachO());
574 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
575}
576
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000577WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
578 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000579 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
580
581 // This is an LLP64 platform.
582 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000583 IntWidth = IntAlign = 32;
584 LongWidth = LongAlign = 32;
585 DoubleAlign = LongLongAlign = 64;
586 LongDoubleWidth = LongDoubleAlign = 64;
587 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
588 IntMaxType = SignedLongLong;
589 Int64Type = SignedLongLong;
590 SizeType = UnsignedLongLong;
591 PtrDiffType = SignedLongLong;
592 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000593}
594
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000595void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000596 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
597}
598
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000599TargetInfo::BuiltinVaListKind
600WindowsARM64TargetInfo::getBuiltinVaListKind() const {
601 return TargetInfo::CharPtrBuiltinVaList;
602}
603
604TargetInfo::CallingConvCheckResult
605WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
606 switch (CC) {
607 case CC_X86StdCall:
608 case CC_X86ThisCall:
609 case CC_X86FastCall:
610 case CC_X86VectorCall:
611 return CCCR_Ignore;
612 case CC_C:
613 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000614 case CC_PreserveMost:
615 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000616 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000617 case CC_Win64:
618 return CCCR_OK;
619 default:
620 return CCCR_Warning;
621 }
622}
623
624MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
625 const TargetOptions &Opts)
626 : WindowsARM64TargetInfo(Triple, Opts) {
627 TheCXXABI.set(TargetCXXABI::Microsoft);
628}
629
Tim Northoverad4c5db2017-07-24 17:06:23 +0000630void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
631 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000632 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
633 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000634}
635
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000636TargetInfo::CallingConvKind
637MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
638 return CCK_MicrosoftWin64;
639}
640
Tom Tanb7c6d952019-05-02 00:38:14 +0000641unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
642 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
643
644 // MSVC does size based alignment for arm64 based on alignment section in
645 // below document, replicate that to keep alignment consistent with object
646 // files compiled by MSVC.
647 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
648 if (TypeSize >= 512) { // TypeSize >= 64 bytes
649 Align = std::max(Align, 128u); // align type at least 16 bytes
650 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
651 Align = std::max(Align, 64u); // align type at least 8 butes
652 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
653 Align = std::max(Align, 32u); // align type at least 4 bytes
654 }
655 return Align;
656}
657
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000658MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
659 const TargetOptions &Opts)
660 : WindowsARM64TargetInfo(Triple, Opts) {
661 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000662}
663
664DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
665 const TargetOptions &Opts)
666 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
667 Int64Type = SignedLongLong;
Tim Northover44e58792018-09-18 10:34:39 +0100668 if (getTriple().isArch32Bit())
669 IntMaxType = SignedLongLong;
670
671 WCharType = SignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000672 UseSignedCharForObjCBool = false;
673
674 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
675 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
676
Tim Northover44e58792018-09-18 10:34:39 +0100677 UseZeroLengthBitfieldAlignment = false;
678
679 if (getTriple().isArch32Bit()) {
680 UseBitFieldTypeAlignment = false;
681 ZeroLengthBitfieldBoundary = 32;
682 UseZeroLengthBitfieldAlignment = true;
683 TheCXXABI.set(TargetCXXABI::WatchOS);
684 } else
685 TheCXXABI.set(TargetCXXABI::iOS64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000686}
687
688void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
689 const llvm::Triple &Triple,
690 MacroBuilder &Builder) const {
691 Builder.defineMacro("__AARCH64_SIMD__");
Tim Northover44e58792018-09-18 10:34:39 +0100692 if (Triple.isArch32Bit())
693 Builder.defineMacro("__ARM64_ARCH_8_32__");
694 else
695 Builder.defineMacro("__ARM64_ARCH_8__");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000696 Builder.defineMacro("__ARM_NEON__");
697 Builder.defineMacro("__LITTLE_ENDIAN__");
698 Builder.defineMacro("__REGISTER_PREFIX__", "");
699 Builder.defineMacro("__arm64", "1");
700 Builder.defineMacro("__arm64__", "1");
701
702 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
703}
704
705TargetInfo::BuiltinVaListKind
706DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
707 return TargetInfo::CharPtrBuiltinVaList;
708}
709
710// 64-bit RenderScript is aarch64
711RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
712 const TargetOptions &Opts)
713 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
714 Triple.getOSName(),
715 Triple.getEnvironmentName()),
716 Opts) {
717 IsRenderScriptTarget = true;
718}
719
720void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
721 MacroBuilder &Builder) const {
722 Builder.defineMacro("__RENDERSCRIPT__");
723 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
724}