blob: 93a525b09d8d44e3fd89211d66ef5800045c7145 [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 Northoverad4c5db2017-07-24 17:06:23 +000054 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
55 MaxVectorAlign = 128;
56 MaxAtomicInlineWidth = 128;
57 MaxAtomicPromoteWidth = 128;
58
59 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
60 LongDoubleFormat = &llvm::APFloat::IEEEquad();
61
62 // Make __builtin_ms_va_list available.
63 HasBuiltinMSVaList = true;
64
65 // {} in inline assembly are neon specifiers, not assembly variant
66 // specifiers.
67 NoAsmVariants = true;
68
69 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
70 // contributes to the alignment of the containing aggregate in the same way
71 // a plain (non bit-field) member of that type would, without exception for
72 // zero-sized or anonymous bit-fields."
73 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
74 UseZeroLengthBitfieldAlignment = true;
75
76 // AArch64 targets default to using the ARM C++ ABI.
77 TheCXXABI.set(TargetCXXABI::GenericAArch64);
78
79 if (Triple.getOS() == llvm::Triple::Linux)
80 this->MCountName = "\01_mcount";
81 else if (Triple.getOS() == llvm::Triple::UnknownOS)
82 this->MCountName =
83 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
84}
85
86StringRef AArch64TargetInfo::getABI() const { return ABI; }
87
88bool AArch64TargetInfo::setABI(const std::string &Name) {
89 if (Name != "aapcs" && Name != "darwinpcs")
90 return false;
91
92 ABI = Name;
93 return true;
94}
95
96bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
97 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +000098 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +000099}
100
101bool AArch64TargetInfo::setCPU(const std::string &Name) {
102 return isValidCPUName(Name);
103}
104
Erich Keane3ec17432018-02-08 23:14:15 +0000105void AArch64TargetInfo::fillValidCPUList(
106 SmallVectorImpl<StringRef> &Values) const {
107 llvm::AArch64::fillValidCPUArchList(Values);
108}
109
Tim Northoverad4c5db2017-07-24 17:06:23 +0000110void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
111 MacroBuilder &Builder) const {
112 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
113}
114
115void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
116 MacroBuilder &Builder) const {
117 // Also include the ARMv8.1 defines
118 getTargetDefinesARMV81A(Opts, Builder);
119}
120
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000121void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
122 MacroBuilder &Builder) const {
123 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
124 // Also include the Armv8.2 defines
125 getTargetDefinesARMV82A(Opts, Builder);
126}
127
128void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
129 MacroBuilder &Builder) const {
130 // Also include the Armv8.3 defines
131 // FIXME: Armv8.4 makes some extensions mandatory. Handle them here.
132 getTargetDefinesARMV83A(Opts, Builder);
133}
134
135void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
136 MacroBuilder &Builder) const {
137 // Also include the Armv8.4 defines
138 // FIXME: Armv8.5 makes some extensions mandatory. Handle them here.
139 getTargetDefinesARMV84A(Opts, Builder);
140}
141
142
Tim Northoverad4c5db2017-07-24 17:06:23 +0000143void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
144 MacroBuilder &Builder) const {
145 // Target identification.
146 Builder.defineMacro("__aarch64__");
Eli Friedman39ceea32018-10-17 21:07:11 +0000147 // For bare-metal.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000148 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
Eli Friedman39ceea32018-10-17 21:07:11 +0000149 getTriple().isOSBinFormatELF())
Tim Northoverad4c5db2017-07-24 17:06:23 +0000150 Builder.defineMacro("__ELF__");
151
152 // Target properties.
Martin Storsjo588a3e52017-07-31 20:40:53 +0000153 if (!getTriple().isOSWindows()) {
154 Builder.defineMacro("_LP64");
155 Builder.defineMacro("__LP64__");
156 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000157
158 // ACLE predefines. Many can only have one possible value on v8 AArch64.
159 Builder.defineMacro("__ARM_ACLE", "200");
160 Builder.defineMacro("__ARM_ARCH", "8");
161 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
162
163 Builder.defineMacro("__ARM_64BIT_STATE", "1");
164 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
165 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
166
167 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
168 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
169 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
170 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
171 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
172 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
173 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
174
175 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
176
177 // 0xe implies support for half, single and double precision operations.
178 Builder.defineMacro("__ARM_FP", "0xE");
179
180 // PCS specifies this for SysV variants, which is all we support. Other ABIs
181 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
182 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
183 Builder.defineMacro("__ARM_FP16_ARGS", "1");
184
185 if (Opts.UnsafeFPMath)
186 Builder.defineMacro("__ARM_FP_FAST", "1");
187
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000188 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000189 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000190
191 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
192
193 if (FPU & NeonMode) {
194 Builder.defineMacro("__ARM_NEON", "1");
195 // 64-bit NEON supports half, single and double precision operations.
196 Builder.defineMacro("__ARM_NEON_FP", "0xE");
197 }
198
Momchil Velikove14cfe22019-07-17 11:24:37 +0000199 if (HasCRC)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000200 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
201
Momchil Velikove14cfe22019-07-17 11:24:37 +0000202 if (HasCrypto)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000203 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
204
Momchil Velikove14cfe22019-07-17 11:24:37 +0000205 if (HasUnaligned)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000206 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
207
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000208 if ((FPU & NeonMode) && HasFullFP16)
209 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000210 if (HasFullFP16)
211 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000212
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000213 if (HasDotProd)
214 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
215
Javed Absar18b0c402019-04-26 21:08:11 +0000216 if (HasMTE)
217 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
218
Momchil Velikova36d3142019-07-31 12:52:17 +0000219 if (HasTME)
220 Builder.defineMacro("__ARM_FEATURE_TME", "1");
221
Bryan Chan223307b2018-10-25 23:47:00 +0000222 if ((FPU & NeonMode) && HasFP16FML)
223 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
224
Tim Northoverad4c5db2017-07-24 17:06:23 +0000225 switch (ArchKind) {
226 default:
227 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000228 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000229 getTargetDefinesARMV81A(Opts, Builder);
230 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000231 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000232 getTargetDefinesARMV82A(Opts, Builder);
233 break;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000234 case llvm::AArch64::ArchKind::ARMV8_3A:
235 getTargetDefinesARMV83A(Opts, Builder);
236 break;
237 case llvm::AArch64::ArchKind::ARMV8_4A:
238 getTargetDefinesARMV84A(Opts, Builder);
239 break;
240 case llvm::AArch64::ArchKind::ARMV8_5A:
241 getTargetDefinesARMV85A(Opts, Builder);
242 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000243 }
244
245 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
246 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
247 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
248 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
249 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
250}
251
252ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
253 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
254 Builtin::FirstTSBuiltin);
255}
256
257bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
258 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
259 (Feature == "neon" && (FPU & NeonMode)) ||
260 (Feature == "sve" && (FPU & SveMode));
261}
262
263bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
264 DiagnosticsEngine &Diags) {
265 FPU = FPUMode;
Momchil Velikove14cfe22019-07-17 11:24:37 +0000266 HasCRC = false;
267 HasCrypto = false;
268 HasUnaligned = true;
269 HasFullFP16 = false;
270 HasDotProd = false;
271 HasFP16FML = false;
272 HasMTE = false;
Momchil Velikova36d3142019-07-31 12:52:17 +0000273 HasTME = false;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000274 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000275
276 for (const auto &Feature : Features) {
277 if (Feature == "+neon")
278 FPU |= NeonMode;
279 if (Feature == "+sve")
280 FPU |= SveMode;
281 if (Feature == "+crc")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000282 HasCRC = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000283 if (Feature == "+crypto")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000284 HasCrypto = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000285 if (Feature == "+strict-align")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000286 HasUnaligned = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000287 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000288 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000289 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000290 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000291 if (Feature == "+v8.3a")
292 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
293 if (Feature == "+v8.4a")
294 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
295 if (Feature == "+v8.5a")
296 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000297 if (Feature == "+fullfp16")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000298 HasFullFP16 = true;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000299 if (Feature == "+dotprod")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000300 HasDotProd = true;
Bryan Chan223307b2018-10-25 23:47:00 +0000301 if (Feature == "+fp16fml")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000302 HasFP16FML = true;
Javed Absar18b0c402019-04-26 21:08:11 +0000303 if (Feature == "+mte")
Momchil Velikove14cfe22019-07-17 11:24:37 +0000304 HasMTE = true;
Momchil Velikova36d3142019-07-31 12:52:17 +0000305 if (Feature == "+tme")
306 HasTME = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000307 }
308
309 setDataLayout();
310
311 return true;
312}
313
314TargetInfo::CallingConvCheckResult
315AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
316 switch (CC) {
317 case CC_C:
318 case CC_Swift:
319 case CC_PreserveMost:
320 case CC_PreserveAll:
321 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000322 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000323 case CC_Win64:
324 return CCCR_OK;
325 default:
326 return CCCR_Warning;
327 }
328}
329
330bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
331
332TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
333 return TargetInfo::AArch64ABIBuiltinVaList;
334}
335
Erich Keaneebba5922017-07-21 22:37:03 +0000336const char *const AArch64TargetInfo::GCCRegNames[] = {
337 // 32-bit Integer registers
338 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
339 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
340 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
341
342 // 64-bit Integer registers
343 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
344 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
345 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
346
347 // 32-bit floating point regsisters
348 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
349 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
350 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
351
352 // 64-bit floating point regsisters
353 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
354 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
355 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
356
Sander de Smalen2b290882019-07-24 08:42:34 +0000357 // Neon vector registers
Erich Keaneebba5922017-07-21 22:37:03 +0000358 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
359 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
Sander de Smalen2b290882019-07-24 08:42:34 +0000360 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
361
362 // SVE vector registers
363 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
364 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
365 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
366
367 // SVE predicate registers
368 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
369 "p11", "p12", "p13", "p14", "p15"
Erich Keaneebba5922017-07-21 22:37:03 +0000370};
371
372ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
373 return llvm::makeArrayRef(GCCRegNames);
374}
375
376const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000377 {{"w31"}, "wsp"},
378 {{"x31"}, "sp"},
379 // GCC rN registers are aliases of xN registers.
380 {{"r0"}, "x0"},
381 {{"r1"}, "x1"},
382 {{"r2"}, "x2"},
383 {{"r3"}, "x3"},
384 {{"r4"}, "x4"},
385 {{"r5"}, "x5"},
386 {{"r6"}, "x6"},
387 {{"r7"}, "x7"},
388 {{"r8"}, "x8"},
389 {{"r9"}, "x9"},
390 {{"r10"}, "x10"},
391 {{"r11"}, "x11"},
392 {{"r12"}, "x12"},
393 {{"r13"}, "x13"},
394 {{"r14"}, "x14"},
395 {{"r15"}, "x15"},
396 {{"r16"}, "x16"},
397 {{"r17"}, "x17"},
398 {{"r18"}, "x18"},
399 {{"r19"}, "x19"},
400 {{"r20"}, "x20"},
401 {{"r21"}, "x21"},
402 {{"r22"}, "x22"},
403 {{"r23"}, "x23"},
404 {{"r24"}, "x24"},
405 {{"r25"}, "x25"},
406 {{"r26"}, "x26"},
407 {{"r27"}, "x27"},
408 {{"r28"}, "x28"},
409 {{"r29", "x29"}, "fp"},
410 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000411 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
412 // don't want to substitute one of these for a different-sized one.
413};
414
415ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
416 return llvm::makeArrayRef(GCCRegAliases);
417}
418
Tim Northoverad4c5db2017-07-24 17:06:23 +0000419bool AArch64TargetInfo::validateAsmConstraint(
420 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
421 switch (*Name) {
422 default:
423 return false;
424 case 'w': // Floating point and SIMD registers (V0-V31)
425 Info.setAllowsRegister();
426 return true;
427 case 'I': // Constant that can be used with an ADD instruction
428 case 'J': // Constant that can be used with a SUB instruction
429 case 'K': // Constant that can be used with a 32-bit logical instruction
430 case 'L': // Constant that can be used with a 64-bit logical instruction
431 case 'M': // Constant that can be used as a 32-bit MOV immediate
432 case 'N': // Constant that can be used as a 64-bit MOV immediate
433 case 'Y': // Floating point constant zero
434 case 'Z': // Integer constant zero
435 return true;
436 case 'Q': // A memory reference with base register and no offset
437 Info.setAllowsMemory();
438 return true;
439 case 'S': // A symbolic address
440 Info.setAllowsRegister();
441 return true;
442 case 'U':
443 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
444 // Utf: A memory address suitable for ldp/stp in TF mode.
445 // Usa: An absolute symbolic address.
446 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
447 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
448 case 'z': // Zero register, wzr or xzr
449 Info.setAllowsRegister();
450 return true;
451 case 'x': // Floating point and SIMD registers (V0-V15)
452 Info.setAllowsRegister();
453 return true;
454 }
455 return false;
456}
Erich Keaneebba5922017-07-21 22:37:03 +0000457
Tim Northoverad4c5db2017-07-24 17:06:23 +0000458bool AArch64TargetInfo::validateConstraintModifier(
459 StringRef Constraint, char Modifier, unsigned Size,
460 std::string &SuggestedModifier) const {
461 // Strip off constraint modifiers.
462 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
463 Constraint = Constraint.substr(1);
464
465 switch (Constraint[0]) {
466 default:
467 return true;
468 case 'z':
469 case 'r': {
470 switch (Modifier) {
471 case 'x':
472 case 'w':
473 // For now assume that the person knows what they're
474 // doing with the modifier.
475 return true;
476 default:
477 // By default an 'r' constraint will be in the 'x'
478 // registers.
479 if (Size == 64)
480 return true;
481
482 SuggestedModifier = "w";
483 return false;
484 }
485 }
486 }
487}
488
489const char *AArch64TargetInfo::getClobbers() const { return ""; }
490
491int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
492 if (RegNo == 0)
493 return 0;
494 if (RegNo == 1)
495 return 1;
496 return -1;
497}
498
499AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
500 const TargetOptions &Opts)
501 : AArch64TargetInfo(Triple, Opts) {}
502
503void AArch64leTargetInfo::setDataLayout() {
504 if (getTriple().isOSBinFormatMachO())
505 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
506 else
507 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
508}
509
510void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
511 MacroBuilder &Builder) const {
512 Builder.defineMacro("__AARCH64EL__");
513 AArch64TargetInfo::getTargetDefines(Opts, Builder);
514}
515
516AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
517 const TargetOptions &Opts)
518 : AArch64TargetInfo(Triple, Opts) {}
519
520void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
521 MacroBuilder &Builder) const {
522 Builder.defineMacro("__AARCH64EB__");
523 Builder.defineMacro("__AARCH_BIG_ENDIAN");
524 Builder.defineMacro("__ARM_BIG_ENDIAN");
525 AArch64TargetInfo::getTargetDefines(Opts, Builder);
526}
527
528void AArch64beTargetInfo::setDataLayout() {
529 assert(!getTriple().isOSBinFormatMachO());
530 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
531}
532
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000533WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
534 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000535 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
536
537 // This is an LLP64 platform.
538 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000539 IntWidth = IntAlign = 32;
540 LongWidth = LongAlign = 32;
541 DoubleAlign = LongLongAlign = 64;
542 LongDoubleWidth = LongDoubleAlign = 64;
543 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
544 IntMaxType = SignedLongLong;
545 Int64Type = SignedLongLong;
546 SizeType = UnsignedLongLong;
547 PtrDiffType = SignedLongLong;
548 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000549}
550
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000551void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000552 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
553}
554
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000555TargetInfo::BuiltinVaListKind
556WindowsARM64TargetInfo::getBuiltinVaListKind() const {
557 return TargetInfo::CharPtrBuiltinVaList;
558}
559
560TargetInfo::CallingConvCheckResult
561WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
562 switch (CC) {
563 case CC_X86StdCall:
564 case CC_X86ThisCall:
565 case CC_X86FastCall:
566 case CC_X86VectorCall:
567 return CCCR_Ignore;
568 case CC_C:
569 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000570 case CC_PreserveMost:
571 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000572 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000573 case CC_Win64:
574 return CCCR_OK;
575 default:
576 return CCCR_Warning;
577 }
578}
579
580MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
581 const TargetOptions &Opts)
582 : WindowsARM64TargetInfo(Triple, Opts) {
583 TheCXXABI.set(TargetCXXABI::Microsoft);
584}
585
Tim Northoverad4c5db2017-07-24 17:06:23 +0000586void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
587 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000588 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
589 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000590}
591
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000592TargetInfo::CallingConvKind
593MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
594 return CCK_MicrosoftWin64;
595}
596
Tom Tanb7c6d952019-05-02 00:38:14 +0000597unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
598 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
599
600 // MSVC does size based alignment for arm64 based on alignment section in
601 // below document, replicate that to keep alignment consistent with object
602 // files compiled by MSVC.
603 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
604 if (TypeSize >= 512) { // TypeSize >= 64 bytes
605 Align = std::max(Align, 128u); // align type at least 16 bytes
606 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
607 Align = std::max(Align, 64u); // align type at least 8 butes
608 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
609 Align = std::max(Align, 32u); // align type at least 4 bytes
610 }
611 return Align;
612}
613
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000614MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
615 const TargetOptions &Opts)
616 : WindowsARM64TargetInfo(Triple, Opts) {
617 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000618}
619
620DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
621 const TargetOptions &Opts)
622 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
623 Int64Type = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000624 UseSignedCharForObjCBool = false;
625
626 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
627 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
628
629 TheCXXABI.set(TargetCXXABI::iOS64);
630}
631
632void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
633 const llvm::Triple &Triple,
634 MacroBuilder &Builder) const {
635 Builder.defineMacro("__AARCH64_SIMD__");
636 Builder.defineMacro("__ARM64_ARCH_8__");
637 Builder.defineMacro("__ARM_NEON__");
638 Builder.defineMacro("__LITTLE_ENDIAN__");
639 Builder.defineMacro("__REGISTER_PREFIX__", "");
640 Builder.defineMacro("__arm64", "1");
641 Builder.defineMacro("__arm64__", "1");
642
643 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
644}
645
646TargetInfo::BuiltinVaListKind
647DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
648 return TargetInfo::CharPtrBuiltinVaList;
649}
650
651// 64-bit RenderScript is aarch64
652RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
653 const TargetOptions &Opts)
654 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
655 Triple.getOSName(),
656 Triple.getEnvironmentName()),
657 Opts) {
658 IsRenderScriptTarget = true;
659}
660
661void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
662 MacroBuilder &Builder) const {
663 Builder.defineMacro("__RENDERSCRIPT__");
664 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
665}