blob: 5214f7c30ee0a251cbe49627dc75b63c9d013345 [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 {
161 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
162 // Also include the Armv8.2 defines
163 getTargetDefinesARMV82A(Opts, Builder);
164}
165
166void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
167 MacroBuilder &Builder) const {
168 // Also include the Armv8.3 defines
169 // FIXME: Armv8.4 makes some extensions mandatory. Handle them here.
170 getTargetDefinesARMV83A(Opts, Builder);
171}
172
173void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
174 MacroBuilder &Builder) const {
175 // Also include the Armv8.4 defines
176 // FIXME: Armv8.5 makes some extensions mandatory. Handle them here.
177 getTargetDefinesARMV84A(Opts, Builder);
178}
179
180
Tim Northoverad4c5db2017-07-24 17:06:23 +0000181void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
182 MacroBuilder &Builder) const {
183 // Target identification.
184 Builder.defineMacro("__aarch64__");
Eli Friedman39ceea32018-10-17 21:07:11 +0000185 // For bare-metal.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000186 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
Eli Friedman39ceea32018-10-17 21:07:11 +0000187 getTriple().isOSBinFormatELF())
Tim Northoverad4c5db2017-07-24 17:06:23 +0000188 Builder.defineMacro("__ELF__");
189
190 // Target properties.
Tim Northover44e58792018-09-18 10:34:39 +0100191 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
Martin Storsjo588a3e52017-07-31 20:40:53 +0000192 Builder.defineMacro("_LP64");
193 Builder.defineMacro("__LP64__");
194 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195
196 // ACLE predefines. Many can only have one possible value on v8 AArch64.
197 Builder.defineMacro("__ARM_ACLE", "200");
198 Builder.defineMacro("__ARM_ARCH", "8");
199 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
200
201 Builder.defineMacro("__ARM_64BIT_STATE", "1");
202 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
203 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
204
205 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
206 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
207 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
208 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
209 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
210 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
211 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
212
213 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
214
215 // 0xe implies support for half, single and double precision operations.
216 Builder.defineMacro("__ARM_FP", "0xE");
217
218 // PCS specifies this for SysV variants, which is all we support. Other ABIs
219 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
220 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
221 Builder.defineMacro("__ARM_FP16_ARGS", "1");
222
223 if (Opts.UnsafeFPMath)
224 Builder.defineMacro("__ARM_FP_FAST", "1");
225
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000226 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000227 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000228
229 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
230
231 if (FPU & NeonMode) {
232 Builder.defineMacro("__ARM_NEON", "1");
233 // 64-bit NEON supports half, single and double precision operations.
234 Builder.defineMacro("__ARM_NEON_FP", "0xE");
235 }
236
Momchil Velikove14cfe22019-07-17 11:24:37 +0000237 if (HasCRC)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000238 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
239
Momchil Velikove14cfe22019-07-17 11:24:37 +0000240 if (HasCrypto)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000241 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
242
Momchil Velikove14cfe22019-07-17 11:24:37 +0000243 if (HasUnaligned)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000244 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
245
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000246 if ((FPU & NeonMode) && HasFullFP16)
247 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000248 if (HasFullFP16)
249 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000250
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000251 if (HasDotProd)
252 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
253
Javed Absar18b0c402019-04-26 21:08:11 +0000254 if (HasMTE)
255 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
256
Momchil Velikova36d3142019-07-31 12:52:17 +0000257 if (HasTME)
258 Builder.defineMacro("__ARM_FEATURE_TME", "1");
259
Bryan Chan223307b2018-10-25 23:47:00 +0000260 if ((FPU & NeonMode) && HasFP16FML)
261 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
262
Tim Northoverad4c5db2017-07-24 17:06:23 +0000263 switch (ArchKind) {
264 default:
265 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000266 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000267 getTargetDefinesARMV81A(Opts, Builder);
268 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000269 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000270 getTargetDefinesARMV82A(Opts, Builder);
271 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000272 case llvm::AArch64::ArchKind::ARMV8_3A:
273 getTargetDefinesARMV83A(Opts, Builder);
274 break;
275 case llvm::AArch64::ArchKind::ARMV8_4A:
276 getTargetDefinesARMV84A(Opts, Builder);
277 break;
278 case llvm::AArch64::ArchKind::ARMV8_5A:
279 getTargetDefinesARMV85A(Opts, Builder);
280 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000281 }
282
283 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
284 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
285 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
286 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
287 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
288}
289
290ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
291 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
292 Builtin::FirstTSBuiltin);
293}
294
295bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
296 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
297 (Feature == "neon" && (FPU & NeonMode)) ||
298 (Feature == "sve" && (FPU & SveMode));
299}
300
301bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
302 DiagnosticsEngine &Diags) {
303 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000304 HasCRC = false;
305 HasCrypto = false;
306 HasUnaligned = true;
307 HasFullFP16 = false;
308 HasDotProd = false;
309 HasFP16FML = false;
310 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000311 HasTME = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000312 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000313
314 for (const auto &Feature : Features) {
315 if (Feature == "+neon")
316 FPU |= NeonMode;
317 if (Feature == "+sve")
318 FPU |= SveMode;
319 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000320 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000321 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000322 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000323 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000324 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000325 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000326 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000327 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000328 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000329 if (Feature == "+v8.3a")
330 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
331 if (Feature == "+v8.4a")
332 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
333 if (Feature == "+v8.5a")
334 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000335 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000336 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000337 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000338 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000339 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000340 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000341 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000342 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000343 if (Feature == "+tme")
344 HasTME = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000345 }
346
347 setDataLayout();
348
349 return true;
350}
351
352TargetInfo::CallingConvCheckResult
353AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
354 switch (CC) {
355 case CC_C:
356 case CC_Swift:
357 case CC_PreserveMost:
358 case CC_PreserveAll:
359 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000360 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000361 case CC_Win64:
362 return CCCR_OK;
363 default:
364 return CCCR_Warning;
365 }
366}
367
368bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
369
370TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
371 return TargetInfo::AArch64ABIBuiltinVaList;
372}
373
Erich Keaneebba5922017-07-21 22:37:03 +0000374const char *const AArch64TargetInfo::GCCRegNames[] = {
375 // 32-bit Integer registers
376 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
377 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
378 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
379
380 // 64-bit Integer registers
381 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
382 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
383 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
384
385 // 32-bit floating point regsisters
386 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
387 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
388 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
389
390 // 64-bit floating point regsisters
391 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
392 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
393 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
394
Sander de Smalen2b290882019-07-24 08:42:34 +0000395 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000396 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
397 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000398 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
399
400 // SVE vector registers
401 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
402 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
403 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
404
405 // SVE predicate registers
406 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
407 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000408};
409
410ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
411 return llvm::makeArrayRef(GCCRegNames);
412}
413
414const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000415 {{"w31"}, "wsp"},
416 {{"x31"}, "sp"},
417 // GCC rN registers are aliases of xN registers.
418 {{"r0"}, "x0"},
419 {{"r1"}, "x1"},
420 {{"r2"}, "x2"},
421 {{"r3"}, "x3"},
422 {{"r4"}, "x4"},
423 {{"r5"}, "x5"},
424 {{"r6"}, "x6"},
425 {{"r7"}, "x7"},
426 {{"r8"}, "x8"},
427 {{"r9"}, "x9"},
428 {{"r10"}, "x10"},
429 {{"r11"}, "x11"},
430 {{"r12"}, "x12"},
431 {{"r13"}, "x13"},
432 {{"r14"}, "x14"},
433 {{"r15"}, "x15"},
434 {{"r16"}, "x16"},
435 {{"r17"}, "x17"},
436 {{"r18"}, "x18"},
437 {{"r19"}, "x19"},
438 {{"r20"}, "x20"},
439 {{"r21"}, "x21"},
440 {{"r22"}, "x22"},
441 {{"r23"}, "x23"},
442 {{"r24"}, "x24"},
443 {{"r25"}, "x25"},
444 {{"r26"}, "x26"},
445 {{"r27"}, "x27"},
446 {{"r28"}, "x28"},
447 {{"r29", "x29"}, "fp"},
448 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000449 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
450 // don't want to substitute one of these for a different-sized one.
451};
452
453ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
454 return llvm::makeArrayRef(GCCRegAliases);
455}
456
Tim Northoverad4c5db2017-07-24 17:06:23 +0000457bool AArch64TargetInfo::validateAsmConstraint(
458 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
459 switch (*Name) {
460 default:
461 return false;
462 case 'w': // Floating point and SIMD registers (V0-V31)
463 Info.setAllowsRegister();
464 return true;
465 case 'I': // Constant that can be used with an ADD instruction
466 case 'J': // Constant that can be used with a SUB instruction
467 case 'K': // Constant that can be used with a 32-bit logical instruction
468 case 'L': // Constant that can be used with a 64-bit logical instruction
469 case 'M': // Constant that can be used as a 32-bit MOV immediate
470 case 'N': // Constant that can be used as a 64-bit MOV immediate
471 case 'Y': // Floating point constant zero
472 case 'Z': // Integer constant zero
473 return true;
474 case 'Q': // A memory reference with base register and no offset
475 Info.setAllowsMemory();
476 return true;
477 case 'S': // A symbolic address
478 Info.setAllowsRegister();
479 return true;
480 case 'U':
481 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
482 // Utf: A memory address suitable for ldp/stp in TF mode.
483 // Usa: An absolute symbolic address.
484 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
485 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
486 case 'z': // Zero register, wzr or xzr
487 Info.setAllowsRegister();
488 return true;
489 case 'x': // Floating point and SIMD registers (V0-V15)
490 Info.setAllowsRegister();
491 return true;
492 }
493 return false;
494}
Erich Keaneebba5922017-07-21 22:37:03 +0000495
Tim Northoverad4c5db2017-07-24 17:06:23 +0000496bool AArch64TargetInfo::validateConstraintModifier(
497 StringRef Constraint, char Modifier, unsigned Size,
498 std::string &SuggestedModifier) const {
499 // Strip off constraint modifiers.
500 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
501 Constraint = Constraint.substr(1);
502
503 switch (Constraint[0]) {
504 default:
505 return true;
506 case 'z':
507 case 'r': {
508 switch (Modifier) {
509 case 'x':
510 case 'w':
511 // For now assume that the person knows what they're
512 // doing with the modifier.
513 return true;
514 default:
515 // By default an 'r' constraint will be in the 'x'
516 // registers.
517 if (Size == 64)
518 return true;
519
520 SuggestedModifier = "w";
521 return false;
522 }
523 }
524 }
525}
526
527const char *AArch64TargetInfo::getClobbers() const { return ""; }
528
529int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
530 if (RegNo == 0)
531 return 0;
532 if (RegNo == 1)
533 return 1;
534 return -1;
535}
536
Tim Northover44e58792018-09-18 10:34:39 +0100537bool AArch64TargetInfo::hasInt128Type() const { return true; }
538
Tim Northoverad4c5db2017-07-24 17:06:23 +0000539AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
540 const TargetOptions &Opts)
541 : AArch64TargetInfo(Triple, Opts) {}
542
543void AArch64leTargetInfo::setDataLayout() {
Tim Northover44e58792018-09-18 10:34:39 +0100544 if (getTriple().isOSBinFormatMachO()) {
545 if(getTriple().isArch32Bit())
546 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
547 else
548 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
549 } else
Tim Northoverad4c5db2017-07-24 17:06:23 +0000550 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
551}
552
553void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
554 MacroBuilder &Builder) const {
555 Builder.defineMacro("__AARCH64EL__");
556 AArch64TargetInfo::getTargetDefines(Opts, Builder);
557}
558
559AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
560 const TargetOptions &Opts)
561 : AArch64TargetInfo(Triple, Opts) {}
562
563void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
564 MacroBuilder &Builder) const {
565 Builder.defineMacro("__AARCH64EB__");
566 Builder.defineMacro("__AARCH_BIG_ENDIAN");
567 Builder.defineMacro("__ARM_BIG_ENDIAN");
568 AArch64TargetInfo::getTargetDefines(Opts, Builder);
569}
570
571void AArch64beTargetInfo::setDataLayout() {
572 assert(!getTriple().isOSBinFormatMachO());
573 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
574}
575
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000576WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
577 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000578 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
579
580 // This is an LLP64 platform.
581 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000582 IntWidth = IntAlign = 32;
583 LongWidth = LongAlign = 32;
584 DoubleAlign = LongLongAlign = 64;
585 LongDoubleWidth = LongDoubleAlign = 64;
586 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
587 IntMaxType = SignedLongLong;
588 Int64Type = SignedLongLong;
589 SizeType = UnsignedLongLong;
590 PtrDiffType = SignedLongLong;
591 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000592}
593
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000594void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000595 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
596}
597
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000598TargetInfo::BuiltinVaListKind
599WindowsARM64TargetInfo::getBuiltinVaListKind() const {
600 return TargetInfo::CharPtrBuiltinVaList;
601}
602
603TargetInfo::CallingConvCheckResult
604WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
605 switch (CC) {
606 case CC_X86StdCall:
607 case CC_X86ThisCall:
608 case CC_X86FastCall:
609 case CC_X86VectorCall:
610 return CCCR_Ignore;
611 case CC_C:
612 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000613 case CC_PreserveMost:
614 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000615 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000616 case CC_Win64:
617 return CCCR_OK;
618 default:
619 return CCCR_Warning;
620 }
621}
622
623MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
624 const TargetOptions &Opts)
625 : WindowsARM64TargetInfo(Triple, Opts) {
626 TheCXXABI.set(TargetCXXABI::Microsoft);
627}
628
Tim Northoverad4c5db2017-07-24 17:06:23 +0000629void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
630 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000631 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
632 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000633}
634
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000635TargetInfo::CallingConvKind
636MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
637 return CCK_MicrosoftWin64;
638}
639
Tom Tanb7c6d952019-05-02 00:38:14 +0000640unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
641 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
642
643 // MSVC does size based alignment for arm64 based on alignment section in
644 // below document, replicate that to keep alignment consistent with object
645 // files compiled by MSVC.
646 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
647 if (TypeSize >= 512) { // TypeSize >= 64 bytes
648 Align = std::max(Align, 128u); // align type at least 16 bytes
649 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
650 Align = std::max(Align, 64u); // align type at least 8 butes
651 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
652 Align = std::max(Align, 32u); // align type at least 4 bytes
653 }
654 return Align;
655}
656
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000657MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
658 const TargetOptions &Opts)
659 : WindowsARM64TargetInfo(Triple, Opts) {
660 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000661}
662
663DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
664 const TargetOptions &Opts)
665 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
666 Int64Type = SignedLongLong;
Tim Northover44e58792018-09-18 10:34:39 +0100667 if (getTriple().isArch32Bit())
668 IntMaxType = SignedLongLong;
669
670 WCharType = SignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000671 UseSignedCharForObjCBool = false;
672
673 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
674 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
675
Tim Northover44e58792018-09-18 10:34:39 +0100676 UseZeroLengthBitfieldAlignment = false;
677
678 if (getTriple().isArch32Bit()) {
679 UseBitFieldTypeAlignment = false;
680 ZeroLengthBitfieldBoundary = 32;
681 UseZeroLengthBitfieldAlignment = true;
682 TheCXXABI.set(TargetCXXABI::WatchOS);
683 } else
684 TheCXXABI.set(TargetCXXABI::iOS64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000685}
686
687void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
688 const llvm::Triple &Triple,
689 MacroBuilder &Builder) const {
690 Builder.defineMacro("__AARCH64_SIMD__");
Tim Northover44e58792018-09-18 10:34:39 +0100691 if (Triple.isArch32Bit())
692 Builder.defineMacro("__ARM64_ARCH_8_32__");
693 else
694 Builder.defineMacro("__ARM64_ARCH_8__");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000695 Builder.defineMacro("__ARM_NEON__");
696 Builder.defineMacro("__LITTLE_ENDIAN__");
697 Builder.defineMacro("__REGISTER_PREFIX__", "");
698 Builder.defineMacro("__arm64", "1");
699 Builder.defineMacro("__arm64__", "1");
700
701 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
702}
703
704TargetInfo::BuiltinVaListKind
705DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
706 return TargetInfo::CharPtrBuiltinVaList;
707}
708
709// 64-bit RenderScript is aarch64
710RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
711 const TargetOptions &Opts)
712 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
713 Triple.getOSName(),
714 Triple.getEnvironmentName()),
715 Opts) {
716 IsRenderScriptTarget = true;
717}
718
719void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
720 MacroBuilder &Builder) const {
721 Builder.defineMacro("__RENDERSCRIPT__");
722 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
723}