blob: bdfb5700b46ac448e7087fff6a959f4283de9431 [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"
Erich Keaneebba5922017-07-21 22:37:03 +000018
19using namespace clang;
20using namespace clang::targets;
21
Tim Northoverad4c5db2017-07-24 17:06:23 +000022const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
23#define BUILTIN(ID, TYPE, ATTRS) \
24 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
25#include "clang/Basic/BuiltinsNEON.def"
26
27#define BUILTIN(ID, TYPE, ATTRS) \
28 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
Martin Storsjod8a44ed2017-10-12 07:05:37 +000029#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
30 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
Martin Storsjo17c0f722018-07-18 06:15:09 +000031#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
32 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
Tim Northoverad4c5db2017-07-24 17:06:23 +000033#include "clang/Basic/BuiltinsAArch64.def"
34};
35
36AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
37 const TargetOptions &Opts)
38 : TargetInfo(Triple), ABI("aapcs") {
Michal Gorny5a409d02018-12-20 13:09:30 +000039 if (getTriple().isOSOpenBSD()) {
Tim Northoverad4c5db2017-07-24 17:06:23 +000040 Int64Type = SignedLongLong;
41 IntMaxType = SignedLongLong;
42 } else {
Michal Gorny5a409d02018-12-20 13:09:30 +000043 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000044 WCharType = UnsignedInt;
45
Tim Northoverad4c5db2017-07-24 17:06:23 +000046 Int64Type = SignedLong;
47 IntMaxType = SignedLong;
48 }
49
Sjoerd Meijer87793e72018-03-19 13:22:49 +000050 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
51 HasLegalHalfType = true;
Erich Keane1d1d4382019-01-25 17:27:57 +000052 HasFloat16 = true;
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000053
Tim Northover44e58792018-09-18 10:34:39 +010054 if (Triple.isArch64Bit())
55 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
56 else
57 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
58
Tim Northoverad4c5db2017-07-24 17:06:23 +000059 MaxVectorAlign = 128;
60 MaxAtomicInlineWidth = 128;
61 MaxAtomicPromoteWidth = 128;
62
63 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
64 LongDoubleFormat = &llvm::APFloat::IEEEquad();
65
66 // Make __builtin_ms_va_list available.
67 HasBuiltinMSVaList = true;
68
Richard Sandifordeb485fb2019-08-09 08:52:54 +000069 // Make the SVE types available. Note that this deliberately doesn't
70 // depend on SveMode, since in principle it should be possible to turn
71 // SVE on and off within a translation unit. It should also be possible
72 // to compile the global declaration:
73 //
74 // __SVInt8_t *ptr;
75 //
76 // even without SVE.
77 HasAArch64SVETypes = true;
78
Tim Northoverad4c5db2017-07-24 17:06:23 +000079 // {} in inline assembly are neon specifiers, not assembly variant
80 // specifiers.
81 NoAsmVariants = true;
82
83 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
84 // contributes to the alignment of the containing aggregate in the same way
85 // a plain (non bit-field) member of that type would, without exception for
86 // zero-sized or anonymous bit-fields."
87 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
88 UseZeroLengthBitfieldAlignment = true;
89
90 // AArch64 targets default to using the ARM C++ ABI.
91 TheCXXABI.set(TargetCXXABI::GenericAArch64);
92
93 if (Triple.getOS() == llvm::Triple::Linux)
94 this->MCountName = "\01_mcount";
95 else if (Triple.getOS() == llvm::Triple::UnknownOS)
96 this->MCountName =
97 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
98}
99
100StringRef AArch64TargetInfo::getABI() const { return ABI; }
101
102bool AArch64TargetInfo::setABI(const std::string &Name) {
103 if (Name != "aapcs" && Name != "darwinpcs")
104 return false;
105
106 ABI = Name;
107 return true;
108}
109
110bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
111 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000112 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000113}
114
115bool AArch64TargetInfo::setCPU(const std::string &Name) {
116 return isValidCPUName(Name);
117}
118
Erich Keane3ec17432018-02-08 23:14:15 +0000119void AArch64TargetInfo::fillValidCPUList(
120 SmallVectorImpl<StringRef> &Values) const {
121 llvm::AArch64::fillValidCPUArchList(Values);
122}
123
Tim Northoverad4c5db2017-07-24 17:06:23 +0000124void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
125 MacroBuilder &Builder) const {
126 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
127}
128
129void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
130 MacroBuilder &Builder) const {
131 // Also include the ARMv8.1 defines
132 getTargetDefinesARMV81A(Opts, Builder);
133}
134
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000135void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
136 MacroBuilder &Builder) const {
137 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
138 // Also include the Armv8.2 defines
139 getTargetDefinesARMV82A(Opts, Builder);
140}
141
142void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
143 MacroBuilder &Builder) const {
144 // Also include the Armv8.3 defines
145 // FIXME: Armv8.4 makes some extensions mandatory. Handle them here.
146 getTargetDefinesARMV83A(Opts, Builder);
147}
148
149void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
150 MacroBuilder &Builder) const {
151 // Also include the Armv8.4 defines
152 // FIXME: Armv8.5 makes some extensions mandatory. Handle them here.
153 getTargetDefinesARMV84A(Opts, Builder);
154}
155
156
Tim Northoverad4c5db2017-07-24 17:06:23 +0000157void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
158 MacroBuilder &Builder) const {
159 // Target identification.
160 Builder.defineMacro("__aarch64__");
Eli Friedman39ceea32018-10-17 21:07:11 +0000161 // For bare-metal.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000162 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
Eli Friedman39ceea32018-10-17 21:07:11 +0000163 getTriple().isOSBinFormatELF())
Tim Northoverad4c5db2017-07-24 17:06:23 +0000164 Builder.defineMacro("__ELF__");
165
166 // Target properties.
Tim Northover44e58792018-09-18 10:34:39 +0100167 if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
Martin Storsjo588a3e52017-07-31 20:40:53 +0000168 Builder.defineMacro("_LP64");
169 Builder.defineMacro("__LP64__");
170 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000171
172 // ACLE predefines. Many can only have one possible value on v8 AArch64.
173 Builder.defineMacro("__ARM_ACLE", "200");
174 Builder.defineMacro("__ARM_ARCH", "8");
175 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
176
177 Builder.defineMacro("__ARM_64BIT_STATE", "1");
178 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
179 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
180
181 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
182 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
183 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
184 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
185 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
186 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
187 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
188
189 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
190
191 // 0xe implies support for half, single and double precision operations.
192 Builder.defineMacro("__ARM_FP", "0xE");
193
194 // PCS specifies this for SysV variants, which is all we support. Other ABIs
195 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
196 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
197 Builder.defineMacro("__ARM_FP16_ARGS", "1");
198
199 if (Opts.UnsafeFPMath)
200 Builder.defineMacro("__ARM_FP_FAST", "1");
201
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000202 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000203 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000204
205 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
206
207 if (FPU & NeonMode) {
208 Builder.defineMacro("__ARM_NEON", "1");
209 // 64-bit NEON supports half, single and double precision operations.
210 Builder.defineMacro("__ARM_NEON_FP", "0xE");
211 }
212
Momchil Velikove14cfe22019-07-17 11:24:37 +0000213 if (HasCRC)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000214 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
215
Momchil Velikove14cfe22019-07-17 11:24:37 +0000216 if (HasCrypto)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000217 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
218
Momchil Velikove14cfe22019-07-17 11:24:37 +0000219 if (HasUnaligned)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000220 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
221
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000222 if ((FPU & NeonMode) && HasFullFP16)
223 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000224 if (HasFullFP16)
225 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000226
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000227 if (HasDotProd)
228 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
229
Javed Absar18b0c402019-04-26 21:08:11 +0000230 if (HasMTE)
231 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
232
Momchil Velikova36d3142019-07-31 12:52:17 +0000233 if (HasTME)
234 Builder.defineMacro("__ARM_FEATURE_TME", "1");
235
Bryan Chan223307b2018-10-25 23:47:00 +0000236 if ((FPU & NeonMode) && HasFP16FML)
237 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
238
Tim Northoverad4c5db2017-07-24 17:06:23 +0000239 switch (ArchKind) {
240 default:
241 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000242 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000243 getTargetDefinesARMV81A(Opts, Builder);
244 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000245 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000246 getTargetDefinesARMV82A(Opts, Builder);
247 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000248 case llvm::AArch64::ArchKind::ARMV8_3A:
249 getTargetDefinesARMV83A(Opts, Builder);
250 break;
251 case llvm::AArch64::ArchKind::ARMV8_4A:
252 getTargetDefinesARMV84A(Opts, Builder);
253 break;
254 case llvm::AArch64::ArchKind::ARMV8_5A:
255 getTargetDefinesARMV85A(Opts, Builder);
256 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000257 }
258
259 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
260 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
261 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
262 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
263 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
264}
265
266ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
267 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
268 Builtin::FirstTSBuiltin);
269}
270
271bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
272 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
273 (Feature == "neon" && (FPU & NeonMode)) ||
274 (Feature == "sve" && (FPU & SveMode));
275}
276
277bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
278 DiagnosticsEngine &Diags) {
279 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000280 HasCRC = false;
281 HasCrypto = false;
282 HasUnaligned = true;
283 HasFullFP16 = false;
284 HasDotProd = false;
285 HasFP16FML = false;
286 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000287 HasTME = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000288 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000289
290 for (const auto &Feature : Features) {
291 if (Feature == "+neon")
292 FPU |= NeonMode;
293 if (Feature == "+sve")
294 FPU |= SveMode;
295 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000296 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000297 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000298 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000299 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000300 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000301 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000302 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000303 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000304 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000305 if (Feature == "+v8.3a")
306 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
307 if (Feature == "+v8.4a")
308 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
309 if (Feature == "+v8.5a")
310 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000311 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000312 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000313 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000314 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000315 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000316 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000317 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000318 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000319 if (Feature == "+tme")
320 HasTME = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000321 }
322
323 setDataLayout();
324
325 return true;
326}
327
328TargetInfo::CallingConvCheckResult
329AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
330 switch (CC) {
331 case CC_C:
332 case CC_Swift:
333 case CC_PreserveMost:
334 case CC_PreserveAll:
335 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000336 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000337 case CC_Win64:
338 return CCCR_OK;
339 default:
340 return CCCR_Warning;
341 }
342}
343
344bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
345
346TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
347 return TargetInfo::AArch64ABIBuiltinVaList;
348}
349
Erich Keaneebba5922017-07-21 22:37:03 +0000350const char *const AArch64TargetInfo::GCCRegNames[] = {
351 // 32-bit Integer registers
352 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
353 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
354 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
355
356 // 64-bit Integer registers
357 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
358 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
359 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
360
361 // 32-bit floating point regsisters
362 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
363 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
364 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
365
366 // 64-bit floating point regsisters
367 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
368 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
369 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
370
Sander de Smalen2b290882019-07-24 08:42:34 +0000371 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000372 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
373 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000374 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
375
376 // SVE vector registers
377 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
378 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
379 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
380
381 // SVE predicate registers
382 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
383 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000384};
385
386ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
387 return llvm::makeArrayRef(GCCRegNames);
388}
389
390const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000391 {{"w31"}, "wsp"},
392 {{"x31"}, "sp"},
393 // GCC rN registers are aliases of xN registers.
394 {{"r0"}, "x0"},
395 {{"r1"}, "x1"},
396 {{"r2"}, "x2"},
397 {{"r3"}, "x3"},
398 {{"r4"}, "x4"},
399 {{"r5"}, "x5"},
400 {{"r6"}, "x6"},
401 {{"r7"}, "x7"},
402 {{"r8"}, "x8"},
403 {{"r9"}, "x9"},
404 {{"r10"}, "x10"},
405 {{"r11"}, "x11"},
406 {{"r12"}, "x12"},
407 {{"r13"}, "x13"},
408 {{"r14"}, "x14"},
409 {{"r15"}, "x15"},
410 {{"r16"}, "x16"},
411 {{"r17"}, "x17"},
412 {{"r18"}, "x18"},
413 {{"r19"}, "x19"},
414 {{"r20"}, "x20"},
415 {{"r21"}, "x21"},
416 {{"r22"}, "x22"},
417 {{"r23"}, "x23"},
418 {{"r24"}, "x24"},
419 {{"r25"}, "x25"},
420 {{"r26"}, "x26"},
421 {{"r27"}, "x27"},
422 {{"r28"}, "x28"},
423 {{"r29", "x29"}, "fp"},
424 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000425 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
426 // don't want to substitute one of these for a different-sized one.
427};
428
429ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
430 return llvm::makeArrayRef(GCCRegAliases);
431}
432
Tim Northoverad4c5db2017-07-24 17:06:23 +0000433bool AArch64TargetInfo::validateAsmConstraint(
434 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
435 switch (*Name) {
436 default:
437 return false;
438 case 'w': // Floating point and SIMD registers (V0-V31)
439 Info.setAllowsRegister();
440 return true;
441 case 'I': // Constant that can be used with an ADD instruction
442 case 'J': // Constant that can be used with a SUB instruction
443 case 'K': // Constant that can be used with a 32-bit logical instruction
444 case 'L': // Constant that can be used with a 64-bit logical instruction
445 case 'M': // Constant that can be used as a 32-bit MOV immediate
446 case 'N': // Constant that can be used as a 64-bit MOV immediate
447 case 'Y': // Floating point constant zero
448 case 'Z': // Integer constant zero
449 return true;
450 case 'Q': // A memory reference with base register and no offset
451 Info.setAllowsMemory();
452 return true;
453 case 'S': // A symbolic address
454 Info.setAllowsRegister();
455 return true;
456 case 'U':
457 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
458 // Utf: A memory address suitable for ldp/stp in TF mode.
459 // Usa: An absolute symbolic address.
460 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
461 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
462 case 'z': // Zero register, wzr or xzr
463 Info.setAllowsRegister();
464 return true;
465 case 'x': // Floating point and SIMD registers (V0-V15)
466 Info.setAllowsRegister();
467 return true;
468 }
469 return false;
470}
Erich Keaneebba5922017-07-21 22:37:03 +0000471
Tim Northoverad4c5db2017-07-24 17:06:23 +0000472bool AArch64TargetInfo::validateConstraintModifier(
473 StringRef Constraint, char Modifier, unsigned Size,
474 std::string &SuggestedModifier) const {
475 // Strip off constraint modifiers.
476 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
477 Constraint = Constraint.substr(1);
478
479 switch (Constraint[0]) {
480 default:
481 return true;
482 case 'z':
483 case 'r': {
484 switch (Modifier) {
485 case 'x':
486 case 'w':
487 // For now assume that the person knows what they're
488 // doing with the modifier.
489 return true;
490 default:
491 // By default an 'r' constraint will be in the 'x'
492 // registers.
493 if (Size == 64)
494 return true;
495
496 SuggestedModifier = "w";
497 return false;
498 }
499 }
500 }
501}
502
503const char *AArch64TargetInfo::getClobbers() const { return ""; }
504
505int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
506 if (RegNo == 0)
507 return 0;
508 if (RegNo == 1)
509 return 1;
510 return -1;
511}
512
Tim Northover44e58792018-09-18 10:34:39 +0100513bool AArch64TargetInfo::hasInt128Type() const { return true; }
514
Tim Northoverad4c5db2017-07-24 17:06:23 +0000515AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
516 const TargetOptions &Opts)
517 : AArch64TargetInfo(Triple, Opts) {}
518
519void AArch64leTargetInfo::setDataLayout() {
Tim Northover44e58792018-09-18 10:34:39 +0100520 if (getTriple().isOSBinFormatMachO()) {
521 if(getTriple().isArch32Bit())
522 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128");
523 else
524 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
525 } else
Tim Northoverad4c5db2017-07-24 17:06:23 +0000526 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
527}
528
529void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
530 MacroBuilder &Builder) const {
531 Builder.defineMacro("__AARCH64EL__");
532 AArch64TargetInfo::getTargetDefines(Opts, Builder);
533}
534
535AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
536 const TargetOptions &Opts)
537 : AArch64TargetInfo(Triple, Opts) {}
538
539void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
540 MacroBuilder &Builder) const {
541 Builder.defineMacro("__AARCH64EB__");
542 Builder.defineMacro("__AARCH_BIG_ENDIAN");
543 Builder.defineMacro("__ARM_BIG_ENDIAN");
544 AArch64TargetInfo::getTargetDefines(Opts, Builder);
545}
546
547void AArch64beTargetInfo::setDataLayout() {
548 assert(!getTriple().isOSBinFormatMachO());
549 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
550}
551
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000552WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
553 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000554 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
555
556 // This is an LLP64 platform.
557 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000558 IntWidth = IntAlign = 32;
559 LongWidth = LongAlign = 32;
560 DoubleAlign = LongLongAlign = 64;
561 LongDoubleWidth = LongDoubleAlign = 64;
562 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
563 IntMaxType = SignedLongLong;
564 Int64Type = SignedLongLong;
565 SizeType = UnsignedLongLong;
566 PtrDiffType = SignedLongLong;
567 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000568}
569
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000570void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000571 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
572}
573
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000574TargetInfo::BuiltinVaListKind
575WindowsARM64TargetInfo::getBuiltinVaListKind() const {
576 return TargetInfo::CharPtrBuiltinVaList;
577}
578
579TargetInfo::CallingConvCheckResult
580WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
581 switch (CC) {
582 case CC_X86StdCall:
583 case CC_X86ThisCall:
584 case CC_X86FastCall:
585 case CC_X86VectorCall:
586 return CCCR_Ignore;
587 case CC_C:
588 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000589 case CC_PreserveMost:
590 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000591 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000592 case CC_Win64:
593 return CCCR_OK;
594 default:
595 return CCCR_Warning;
596 }
597}
598
599MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
600 const TargetOptions &Opts)
601 : WindowsARM64TargetInfo(Triple, Opts) {
602 TheCXXABI.set(TargetCXXABI::Microsoft);
603}
604
Tim Northoverad4c5db2017-07-24 17:06:23 +0000605void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
606 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000607 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
608 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000609}
610
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000611TargetInfo::CallingConvKind
612MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
613 return CCK_MicrosoftWin64;
614}
615
Tom Tanb7c6d952019-05-02 00:38:14 +0000616unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
617 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
618
619 // MSVC does size based alignment for arm64 based on alignment section in
620 // below document, replicate that to keep alignment consistent with object
621 // files compiled by MSVC.
622 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
623 if (TypeSize >= 512) { // TypeSize >= 64 bytes
624 Align = std::max(Align, 128u); // align type at least 16 bytes
625 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
626 Align = std::max(Align, 64u); // align type at least 8 butes
627 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
628 Align = std::max(Align, 32u); // align type at least 4 bytes
629 }
630 return Align;
631}
632
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000633MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
634 const TargetOptions &Opts)
635 : WindowsARM64TargetInfo(Triple, Opts) {
636 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000637}
638
639DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
640 const TargetOptions &Opts)
641 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
642 Int64Type = SignedLongLong;
Tim Northover44e58792018-09-18 10:34:39 +0100643 if (getTriple().isArch32Bit())
644 IntMaxType = SignedLongLong;
645
646 WCharType = SignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000647 UseSignedCharForObjCBool = false;
648
649 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
650 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
651
Tim Northover44e58792018-09-18 10:34:39 +0100652 UseZeroLengthBitfieldAlignment = false;
653
654 if (getTriple().isArch32Bit()) {
655 UseBitFieldTypeAlignment = false;
656 ZeroLengthBitfieldBoundary = 32;
657 UseZeroLengthBitfieldAlignment = true;
658 TheCXXABI.set(TargetCXXABI::WatchOS);
659 } else
660 TheCXXABI.set(TargetCXXABI::iOS64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000661}
662
663void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
664 const llvm::Triple &Triple,
665 MacroBuilder &Builder) const {
666 Builder.defineMacro("__AARCH64_SIMD__");
Tim Northover44e58792018-09-18 10:34:39 +0100667 if (Triple.isArch32Bit())
668 Builder.defineMacro("__ARM64_ARCH_8_32__");
669 else
670 Builder.defineMacro("__ARM64_ARCH_8__");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000671 Builder.defineMacro("__ARM_NEON__");
672 Builder.defineMacro("__LITTLE_ENDIAN__");
673 Builder.defineMacro("__REGISTER_PREFIX__", "");
674 Builder.defineMacro("__arm64", "1");
675 Builder.defineMacro("__arm64__", "1");
676
677 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
678}
679
680TargetInfo::BuiltinVaListKind
681DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
682 return TargetInfo::CharPtrBuiltinVaList;
683}
684
685// 64-bit RenderScript is aarch64
686RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
687 const TargetOptions &Opts)
688 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
689 Triple.getOSName(),
690 Triple.getEnvironmentName()),
691 Opts) {
692 IsRenderScriptTarget = true;
693}
694
695void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
696 MacroBuilder &Builder) const {
697 Builder.defineMacro("__RENDERSCRIPT__");
698 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
699}