blob: a02530ad06756d58aef14d0736fc6d3aa3ff1073 [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
199 if (FPU & SveMode)
200 Builder.defineMacro("__ARM_FEATURE_SVE", "1");
201
202 if (CRC)
203 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
204
205 if (Crypto)
206 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
207
208 if (Unaligned)
209 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
210
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000211 if ((FPU & NeonMode) && HasFullFP16)
212 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000213 if (HasFullFP16)
214 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000215
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000216 if (HasDotProd)
217 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
218
Javed Absar18b0c402019-04-26 21:08:11 +0000219 if (HasMTE)
220 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "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;
266 CRC = 0;
267 Crypto = 0;
268 Unaligned = 1;
269 HasFullFP16 = 0;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000270 HasDotProd = 0;
Bryan Chan223307b2018-10-25 23:47:00 +0000271 HasFP16FML = 0;
Vitaly Bukaae019812019-04-27 02:40:01 +0000272 HasMTE = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000273 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000274
275 for (const auto &Feature : Features) {
276 if (Feature == "+neon")
277 FPU |= NeonMode;
278 if (Feature == "+sve")
279 FPU |= SveMode;
280 if (Feature == "+crc")
281 CRC = 1;
282 if (Feature == "+crypto")
283 Crypto = 1;
284 if (Feature == "+strict-align")
285 Unaligned = 0;
286 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000287 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000288 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000289 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Kyrylo Tkachoveb721382019-07-16 09:27:39 +0000290 if (Feature == "+v8.3a")
291 ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
292 if (Feature == "+v8.4a")
293 ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
294 if (Feature == "+v8.5a")
295 ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000296 if (Feature == "+fullfp16")
297 HasFullFP16 = 1;
Junmo Park4b9b9fb2018-04-17 22:38:40 +0000298 if (Feature == "+dotprod")
299 HasDotProd = 1;
Bryan Chan223307b2018-10-25 23:47:00 +0000300 if (Feature == "+fp16fml")
301 HasFP16FML = 1;
Javed Absar18b0c402019-04-26 21:08:11 +0000302 if (Feature == "+mte")
303 HasMTE = 1;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000304 }
305
306 setDataLayout();
307
308 return true;
309}
310
311TargetInfo::CallingConvCheckResult
312AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
313 switch (CC) {
314 case CC_C:
315 case CC_Swift:
316 case CC_PreserveMost:
317 case CC_PreserveAll:
318 case CC_OpenCLKernel:
Sander de Smalen44a22532018-11-26 16:38:37 +0000319 case CC_AArch64VectorCall:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000320 case CC_Win64:
321 return CCCR_OK;
322 default:
323 return CCCR_Warning;
324 }
325}
326
327bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
328
329TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
330 return TargetInfo::AArch64ABIBuiltinVaList;
331}
332
Erich Keaneebba5922017-07-21 22:37:03 +0000333const char *const AArch64TargetInfo::GCCRegNames[] = {
334 // 32-bit Integer registers
335 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
336 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
337 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
338
339 // 64-bit Integer registers
340 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
341 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
342 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
343
344 // 32-bit floating point regsisters
345 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
346 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
347 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
348
349 // 64-bit floating point regsisters
350 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
351 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
352 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
353
354 // Vector registers
355 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
356 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
357 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
358};
359
360ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
361 return llvm::makeArrayRef(GCCRegNames);
362}
363
364const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000365 {{"w31"}, "wsp"},
366 {{"x31"}, "sp"},
367 // GCC rN registers are aliases of xN registers.
368 {{"r0"}, "x0"},
369 {{"r1"}, "x1"},
370 {{"r2"}, "x2"},
371 {{"r3"}, "x3"},
372 {{"r4"}, "x4"},
373 {{"r5"}, "x5"},
374 {{"r6"}, "x6"},
375 {{"r7"}, "x7"},
376 {{"r8"}, "x8"},
377 {{"r9"}, "x9"},
378 {{"r10"}, "x10"},
379 {{"r11"}, "x11"},
380 {{"r12"}, "x12"},
381 {{"r13"}, "x13"},
382 {{"r14"}, "x14"},
383 {{"r15"}, "x15"},
384 {{"r16"}, "x16"},
385 {{"r17"}, "x17"},
386 {{"r18"}, "x18"},
387 {{"r19"}, "x19"},
388 {{"r20"}, "x20"},
389 {{"r21"}, "x21"},
390 {{"r22"}, "x22"},
391 {{"r23"}, "x23"},
392 {{"r24"}, "x24"},
393 {{"r25"}, "x25"},
394 {{"r26"}, "x26"},
395 {{"r27"}, "x27"},
396 {{"r28"}, "x28"},
397 {{"r29", "x29"}, "fp"},
398 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000399 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
400 // don't want to substitute one of these for a different-sized one.
401};
402
403ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
404 return llvm::makeArrayRef(GCCRegAliases);
405}
406
Tim Northoverad4c5db2017-07-24 17:06:23 +0000407bool AArch64TargetInfo::validateAsmConstraint(
408 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
409 switch (*Name) {
410 default:
411 return false;
412 case 'w': // Floating point and SIMD registers (V0-V31)
413 Info.setAllowsRegister();
414 return true;
415 case 'I': // Constant that can be used with an ADD instruction
416 case 'J': // Constant that can be used with a SUB instruction
417 case 'K': // Constant that can be used with a 32-bit logical instruction
418 case 'L': // Constant that can be used with a 64-bit logical instruction
419 case 'M': // Constant that can be used as a 32-bit MOV immediate
420 case 'N': // Constant that can be used as a 64-bit MOV immediate
421 case 'Y': // Floating point constant zero
422 case 'Z': // Integer constant zero
423 return true;
424 case 'Q': // A memory reference with base register and no offset
425 Info.setAllowsMemory();
426 return true;
427 case 'S': // A symbolic address
428 Info.setAllowsRegister();
429 return true;
430 case 'U':
431 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
432 // Utf: A memory address suitable for ldp/stp in TF mode.
433 // Usa: An absolute symbolic address.
434 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
435 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
436 case 'z': // Zero register, wzr or xzr
437 Info.setAllowsRegister();
438 return true;
439 case 'x': // Floating point and SIMD registers (V0-V15)
440 Info.setAllowsRegister();
441 return true;
442 }
443 return false;
444}
Erich Keaneebba5922017-07-21 22:37:03 +0000445
Tim Northoverad4c5db2017-07-24 17:06:23 +0000446bool AArch64TargetInfo::validateConstraintModifier(
447 StringRef Constraint, char Modifier, unsigned Size,
448 std::string &SuggestedModifier) const {
449 // Strip off constraint modifiers.
450 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
451 Constraint = Constraint.substr(1);
452
453 switch (Constraint[0]) {
454 default:
455 return true;
456 case 'z':
457 case 'r': {
458 switch (Modifier) {
459 case 'x':
460 case 'w':
461 // For now assume that the person knows what they're
462 // doing with the modifier.
463 return true;
464 default:
465 // By default an 'r' constraint will be in the 'x'
466 // registers.
467 if (Size == 64)
468 return true;
469
470 SuggestedModifier = "w";
471 return false;
472 }
473 }
474 }
475}
476
477const char *AArch64TargetInfo::getClobbers() const { return ""; }
478
479int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
480 if (RegNo == 0)
481 return 0;
482 if (RegNo == 1)
483 return 1;
484 return -1;
485}
486
487AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
488 const TargetOptions &Opts)
489 : AArch64TargetInfo(Triple, Opts) {}
490
491void AArch64leTargetInfo::setDataLayout() {
492 if (getTriple().isOSBinFormatMachO())
493 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
494 else
495 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
496}
497
498void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
499 MacroBuilder &Builder) const {
500 Builder.defineMacro("__AARCH64EL__");
501 AArch64TargetInfo::getTargetDefines(Opts, Builder);
502}
503
504AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
505 const TargetOptions &Opts)
506 : AArch64TargetInfo(Triple, Opts) {}
507
508void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
509 MacroBuilder &Builder) const {
510 Builder.defineMacro("__AARCH64EB__");
511 Builder.defineMacro("__AARCH_BIG_ENDIAN");
512 Builder.defineMacro("__ARM_BIG_ENDIAN");
513 AArch64TargetInfo::getTargetDefines(Opts, Builder);
514}
515
516void AArch64beTargetInfo::setDataLayout() {
517 assert(!getTriple().isOSBinFormatMachO());
518 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
519}
520
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000521WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
522 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000523 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
524
525 // This is an LLP64 platform.
526 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000527 IntWidth = IntAlign = 32;
528 LongWidth = LongAlign = 32;
529 DoubleAlign = LongLongAlign = 64;
530 LongDoubleWidth = LongDoubleAlign = 64;
531 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
532 IntMaxType = SignedLongLong;
533 Int64Type = SignedLongLong;
534 SizeType = UnsignedLongLong;
535 PtrDiffType = SignedLongLong;
536 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000537}
538
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000539void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000540 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
541}
542
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000543TargetInfo::BuiltinVaListKind
544WindowsARM64TargetInfo::getBuiltinVaListKind() const {
545 return TargetInfo::CharPtrBuiltinVaList;
546}
547
548TargetInfo::CallingConvCheckResult
549WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
550 switch (CC) {
551 case CC_X86StdCall:
552 case CC_X86ThisCall:
553 case CC_X86FastCall:
554 case CC_X86VectorCall:
555 return CCCR_Ignore;
556 case CC_C:
557 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000558 case CC_PreserveMost:
559 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000560 case CC_Swift:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000561 case CC_Win64:
562 return CCCR_OK;
563 default:
564 return CCCR_Warning;
565 }
566}
567
568MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
569 const TargetOptions &Opts)
570 : WindowsARM64TargetInfo(Triple, Opts) {
571 TheCXXABI.set(TargetCXXABI::Microsoft);
572}
573
Tim Northoverad4c5db2017-07-24 17:06:23 +0000574void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
575 MacroBuilder &Builder) const {
Reid Kleckner8777df52019-07-09 20:57:28 +0000576 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
577 Builder.defineMacro("_M_ARM64", "1");
Tim Northoverad4c5db2017-07-24 17:06:23 +0000578}
579
Sanjin Sijaric56391d62018-07-26 22:18:28 +0000580TargetInfo::CallingConvKind
581MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
582 return CCK_MicrosoftWin64;
583}
584
Tom Tanb7c6d952019-05-02 00:38:14 +0000585unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
586 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
587
588 // MSVC does size based alignment for arm64 based on alignment section in
589 // below document, replicate that to keep alignment consistent with object
590 // files compiled by MSVC.
591 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
592 if (TypeSize >= 512) { // TypeSize >= 64 bytes
593 Align = std::max(Align, 128u); // align type at least 16 bytes
594 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
595 Align = std::max(Align, 64u); // align type at least 8 butes
596 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
597 Align = std::max(Align, 32u); // align type at least 4 bytes
598 }
599 return Align;
600}
601
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000602MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
603 const TargetOptions &Opts)
604 : WindowsARM64TargetInfo(Triple, Opts) {
605 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000606}
607
608DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
609 const TargetOptions &Opts)
610 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
611 Int64Type = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000612 UseSignedCharForObjCBool = false;
613
614 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
615 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
616
617 TheCXXABI.set(TargetCXXABI::iOS64);
618}
619
620void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
621 const llvm::Triple &Triple,
622 MacroBuilder &Builder) const {
623 Builder.defineMacro("__AARCH64_SIMD__");
624 Builder.defineMacro("__ARM64_ARCH_8__");
625 Builder.defineMacro("__ARM_NEON__");
626 Builder.defineMacro("__LITTLE_ENDIAN__");
627 Builder.defineMacro("__REGISTER_PREFIX__", "");
628 Builder.defineMacro("__arm64", "1");
629 Builder.defineMacro("__arm64__", "1");
630
631 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
632}
633
634TargetInfo::BuiltinVaListKind
635DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
636 return TargetInfo::CharPtrBuiltinVaList;
637}
638
639// 64-bit RenderScript is aarch64
640RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
641 const TargetOptions &Opts)
642 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
643 Triple.getOSName(),
644 Triple.getEnvironmentName()),
645 Opts) {
646 IsRenderScriptTarget = true;
647}
648
649void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
650 MacroBuilder &Builder) const {
651 Builder.defineMacro("__RENDERSCRIPT__");
652 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
653}