blob: 394be5a9f10501feb801ce3e0a3efd48015bcaa5 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements AArch64 TargetInfo objects.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AArch64.h"
15#include "clang/Basic/TargetBuiltins.h"
16#include "clang/Basic/TargetInfo.h"
17#include "llvm/ADT/ArrayRef.h"
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000018#include "llvm/ADT/StringExtras.h"
Erich Keaneebba5922017-07-21 22:37:03 +000019
20using namespace clang;
21using namespace clang::targets;
22
Tim Northoverad4c5db2017-07-24 17:06:23 +000023const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
24#define BUILTIN(ID, TYPE, ATTRS) \
25 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
26#include "clang/Basic/BuiltinsNEON.def"
27
28#define BUILTIN(ID, TYPE, ATTRS) \
29 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
Martin Storsjod8a44ed2017-10-12 07:05:37 +000030#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
31 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
Tim Northoverad4c5db2017-07-24 17:06:23 +000032#include "clang/Basic/BuiltinsAArch64.def"
33};
34
35AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
36 const TargetOptions &Opts)
37 : TargetInfo(Triple), ABI("aapcs") {
38 if (getTriple().getOS() == llvm::Triple::NetBSD ||
39 getTriple().getOS() == llvm::Triple::OpenBSD) {
Tim Northoverad4c5db2017-07-24 17:06:23 +000040 // NetBSD apparently prefers consistency across ARM targets to
41 // consistency across 64-bit targets.
42 Int64Type = SignedLongLong;
43 IntMaxType = SignedLongLong;
44 } else {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000045 if (!getTriple().isOSDarwin())
46 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;
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000054
Tim Northoverad4c5db2017-07-24 17:06:23 +000055 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
56 MaxVectorAlign = 128;
57 MaxAtomicInlineWidth = 128;
58 MaxAtomicPromoteWidth = 128;
59
60 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
61 LongDoubleFormat = &llvm::APFloat::IEEEquad();
62
63 // Make __builtin_ms_va_list available.
64 HasBuiltinMSVaList = true;
65
66 // {} in inline assembly are neon specifiers, not assembly variant
67 // specifiers.
68 NoAsmVariants = true;
69
70 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
71 // contributes to the alignment of the containing aggregate in the same way
72 // a plain (non bit-field) member of that type would, without exception for
73 // zero-sized or anonymous bit-fields."
74 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
75 UseZeroLengthBitfieldAlignment = true;
76
77 // AArch64 targets default to using the ARM C++ ABI.
78 TheCXXABI.set(TargetCXXABI::GenericAArch64);
79
80 if (Triple.getOS() == llvm::Triple::Linux)
81 this->MCountName = "\01_mcount";
82 else if (Triple.getOS() == llvm::Triple::UnknownOS)
83 this->MCountName =
84 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
85}
86
87StringRef AArch64TargetInfo::getABI() const { return ABI; }
88
89bool AArch64TargetInfo::setABI(const std::string &Name) {
90 if (Name != "aapcs" && Name != "darwinpcs")
91 return false;
92
93 ABI = Name;
94 return true;
95}
96
97bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
98 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +000099 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000100}
101
102bool AArch64TargetInfo::setCPU(const std::string &Name) {
103 return isValidCPUName(Name);
104}
105
Erich Keane3ec17432018-02-08 23:14:15 +0000106void AArch64TargetInfo::fillValidCPUList(
107 SmallVectorImpl<StringRef> &Values) const {
108 llvm::AArch64::fillValidCPUArchList(Values);
109}
110
Tim Northoverad4c5db2017-07-24 17:06:23 +0000111void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
112 MacroBuilder &Builder) const {
113 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
114}
115
116void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
117 MacroBuilder &Builder) const {
118 // Also include the ARMv8.1 defines
119 getTargetDefinesARMV81A(Opts, Builder);
120}
121
122void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
123 MacroBuilder &Builder) const {
124 // Target identification.
125 Builder.defineMacro("__aarch64__");
126 // For bare-metal none-eabi.
127 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
128 (getTriple().getEnvironment() == llvm::Triple::EABI ||
129 getTriple().getEnvironment() == llvm::Triple::EABIHF))
130 Builder.defineMacro("__ELF__");
131
132 // Target properties.
Martin Storsjo588a3e52017-07-31 20:40:53 +0000133 if (!getTriple().isOSWindows()) {
134 Builder.defineMacro("_LP64");
135 Builder.defineMacro("__LP64__");
136 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000137
138 // ACLE predefines. Many can only have one possible value on v8 AArch64.
139 Builder.defineMacro("__ARM_ACLE", "200");
140 Builder.defineMacro("__ARM_ARCH", "8");
141 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
142
143 Builder.defineMacro("__ARM_64BIT_STATE", "1");
144 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
145 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
146
147 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
148 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
149 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
150 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
151 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
152 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
153 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
154
155 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
156
157 // 0xe implies support for half, single and double precision operations.
158 Builder.defineMacro("__ARM_FP", "0xE");
159
160 // PCS specifies this for SysV variants, which is all we support. Other ABIs
161 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
162 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
163 Builder.defineMacro("__ARM_FP16_ARGS", "1");
164
165 if (Opts.UnsafeFPMath)
166 Builder.defineMacro("__ARM_FP_FAST", "1");
167
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000168 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000169 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Tim Northoverad4c5db2017-07-24 17:06:23 +0000170
171 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
172
173 if (FPU & NeonMode) {
174 Builder.defineMacro("__ARM_NEON", "1");
175 // 64-bit NEON supports half, single and double precision operations.
176 Builder.defineMacro("__ARM_NEON_FP", "0xE");
177 }
178
179 if (FPU & SveMode)
180 Builder.defineMacro("__ARM_FEATURE_SVE", "1");
181
182 if (CRC)
183 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
184
185 if (Crypto)
186 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
187
188 if (Unaligned)
189 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
190
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000191 if ((FPU & NeonMode) && HasFullFP16)
192 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
Abderrazek Zaafranice8746d2018-01-19 23:11:18 +0000193 if (HasFullFP16)
194 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
Abderrazek Zaafranif58a1322017-12-21 19:20:01 +0000195
Tim Northoverad4c5db2017-07-24 17:06:23 +0000196 switch (ArchKind) {
197 default:
198 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000199 case llvm::AArch64::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000200 getTargetDefinesARMV81A(Opts, Builder);
201 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000202 case llvm::AArch64::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000203 getTargetDefinesARMV82A(Opts, Builder);
204 break;
205 }
206
207 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
208 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
209 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
210 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
211 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
212}
213
214ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
215 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
216 Builtin::FirstTSBuiltin);
217}
218
219bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
220 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
221 (Feature == "neon" && (FPU & NeonMode)) ||
222 (Feature == "sve" && (FPU & SveMode));
223}
224
225bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
226 DiagnosticsEngine &Diags) {
227 FPU = FPUMode;
228 CRC = 0;
229 Crypto = 0;
230 Unaligned = 1;
231 HasFullFP16 = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000232 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000233
234 for (const auto &Feature : Features) {
235 if (Feature == "+neon")
236 FPU |= NeonMode;
237 if (Feature == "+sve")
238 FPU |= SveMode;
239 if (Feature == "+crc")
240 CRC = 1;
241 if (Feature == "+crypto")
242 Crypto = 1;
243 if (Feature == "+strict-align")
244 Unaligned = 0;
245 if (Feature == "+v8.1a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000246 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000247 if (Feature == "+v8.2a")
Florian Hahnef5bbd62017-07-27 16:28:39 +0000248 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000249 if (Feature == "+fullfp16")
250 HasFullFP16 = 1;
251 }
252
253 setDataLayout();
254
255 return true;
256}
257
258TargetInfo::CallingConvCheckResult
259AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
260 switch (CC) {
261 case CC_C:
262 case CC_Swift:
263 case CC_PreserveMost:
264 case CC_PreserveAll:
265 case CC_OpenCLKernel:
266 case CC_Win64:
267 return CCCR_OK;
268 default:
269 return CCCR_Warning;
270 }
271}
272
273bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
274
275TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
276 return TargetInfo::AArch64ABIBuiltinVaList;
277}
278
Erich Keaneebba5922017-07-21 22:37:03 +0000279const char *const AArch64TargetInfo::GCCRegNames[] = {
280 // 32-bit Integer registers
281 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
282 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
283 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
284
285 // 64-bit Integer registers
286 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
287 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
288 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
289
290 // 32-bit floating point regsisters
291 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
292 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
293 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
294
295 // 64-bit floating point regsisters
296 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
297 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
298 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
299
300 // Vector registers
301 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
302 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
303 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
304};
305
306ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
307 return llvm::makeArrayRef(GCCRegNames);
308}
309
310const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
Manoj Guptacb668d82018-03-29 21:11:15 +0000311 {{"w31"}, "wsp"},
312 {{"x31"}, "sp"},
313 // GCC rN registers are aliases of xN registers.
314 {{"r0"}, "x0"},
315 {{"r1"}, "x1"},
316 {{"r2"}, "x2"},
317 {{"r3"}, "x3"},
318 {{"r4"}, "x4"},
319 {{"r5"}, "x5"},
320 {{"r6"}, "x6"},
321 {{"r7"}, "x7"},
322 {{"r8"}, "x8"},
323 {{"r9"}, "x9"},
324 {{"r10"}, "x10"},
325 {{"r11"}, "x11"},
326 {{"r12"}, "x12"},
327 {{"r13"}, "x13"},
328 {{"r14"}, "x14"},
329 {{"r15"}, "x15"},
330 {{"r16"}, "x16"},
331 {{"r17"}, "x17"},
332 {{"r18"}, "x18"},
333 {{"r19"}, "x19"},
334 {{"r20"}, "x20"},
335 {{"r21"}, "x21"},
336 {{"r22"}, "x22"},
337 {{"r23"}, "x23"},
338 {{"r24"}, "x24"},
339 {{"r25"}, "x25"},
340 {{"r26"}, "x26"},
341 {{"r27"}, "x27"},
342 {{"r28"}, "x28"},
343 {{"r29", "x29"}, "fp"},
344 {{"r30", "x30"}, "lr"},
Erich Keaneebba5922017-07-21 22:37:03 +0000345 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
346 // don't want to substitute one of these for a different-sized one.
347};
348
349ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
350 return llvm::makeArrayRef(GCCRegAliases);
351}
352
Tim Northoverad4c5db2017-07-24 17:06:23 +0000353bool AArch64TargetInfo::validateAsmConstraint(
354 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
355 switch (*Name) {
356 default:
357 return false;
358 case 'w': // Floating point and SIMD registers (V0-V31)
359 Info.setAllowsRegister();
360 return true;
361 case 'I': // Constant that can be used with an ADD instruction
362 case 'J': // Constant that can be used with a SUB instruction
363 case 'K': // Constant that can be used with a 32-bit logical instruction
364 case 'L': // Constant that can be used with a 64-bit logical instruction
365 case 'M': // Constant that can be used as a 32-bit MOV immediate
366 case 'N': // Constant that can be used as a 64-bit MOV immediate
367 case 'Y': // Floating point constant zero
368 case 'Z': // Integer constant zero
369 return true;
370 case 'Q': // A memory reference with base register and no offset
371 Info.setAllowsMemory();
372 return true;
373 case 'S': // A symbolic address
374 Info.setAllowsRegister();
375 return true;
376 case 'U':
377 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
378 // Utf: A memory address suitable for ldp/stp in TF mode.
379 // Usa: An absolute symbolic address.
380 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
381 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
382 case 'z': // Zero register, wzr or xzr
383 Info.setAllowsRegister();
384 return true;
385 case 'x': // Floating point and SIMD registers (V0-V15)
386 Info.setAllowsRegister();
387 return true;
388 }
389 return false;
390}
Erich Keaneebba5922017-07-21 22:37:03 +0000391
Tim Northoverad4c5db2017-07-24 17:06:23 +0000392bool AArch64TargetInfo::validateConstraintModifier(
393 StringRef Constraint, char Modifier, unsigned Size,
394 std::string &SuggestedModifier) const {
395 // Strip off constraint modifiers.
396 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
397 Constraint = Constraint.substr(1);
398
399 switch (Constraint[0]) {
400 default:
401 return true;
402 case 'z':
403 case 'r': {
404 switch (Modifier) {
405 case 'x':
406 case 'w':
407 // For now assume that the person knows what they're
408 // doing with the modifier.
409 return true;
410 default:
411 // By default an 'r' constraint will be in the 'x'
412 // registers.
413 if (Size == 64)
414 return true;
415
416 SuggestedModifier = "w";
417 return false;
418 }
419 }
420 }
421}
422
423const char *AArch64TargetInfo::getClobbers() const { return ""; }
424
425int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
426 if (RegNo == 0)
427 return 0;
428 if (RegNo == 1)
429 return 1;
430 return -1;
431}
432
433AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
434 const TargetOptions &Opts)
435 : AArch64TargetInfo(Triple, Opts) {}
436
437void AArch64leTargetInfo::setDataLayout() {
438 if (getTriple().isOSBinFormatMachO())
439 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
440 else
441 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
442}
443
444void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
445 MacroBuilder &Builder) const {
446 Builder.defineMacro("__AARCH64EL__");
447 AArch64TargetInfo::getTargetDefines(Opts, Builder);
448}
449
450AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
451 const TargetOptions &Opts)
452 : AArch64TargetInfo(Triple, Opts) {}
453
454void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
455 MacroBuilder &Builder) const {
456 Builder.defineMacro("__AARCH64EB__");
457 Builder.defineMacro("__AARCH_BIG_ENDIAN");
458 Builder.defineMacro("__ARM_BIG_ENDIAN");
459 AArch64TargetInfo::getTargetDefines(Opts, Builder);
460}
461
462void AArch64beTargetInfo::setDataLayout() {
463 assert(!getTriple().isOSBinFormatMachO());
464 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
465}
466
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000467WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
468 const TargetOptions &Opts)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000469 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
470
471 // This is an LLP64 platform.
472 // int:4, long:4, long long:8, long double:8.
Tim Northoverad4c5db2017-07-24 17:06:23 +0000473 IntWidth = IntAlign = 32;
474 LongWidth = LongAlign = 32;
475 DoubleAlign = LongLongAlign = 64;
476 LongDoubleWidth = LongDoubleAlign = 64;
477 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
478 IntMaxType = SignedLongLong;
479 Int64Type = SignedLongLong;
480 SizeType = UnsignedLongLong;
481 PtrDiffType = SignedLongLong;
482 IntPtrType = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000483}
484
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000485void WindowsARM64TargetInfo::setDataLayout() {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000486 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
487}
488
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000489TargetInfo::BuiltinVaListKind
490WindowsARM64TargetInfo::getBuiltinVaListKind() const {
491 return TargetInfo::CharPtrBuiltinVaList;
492}
493
494TargetInfo::CallingConvCheckResult
495WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
496 switch (CC) {
497 case CC_X86StdCall:
498 case CC_X86ThisCall:
499 case CC_X86FastCall:
500 case CC_X86VectorCall:
501 return CCCR_Ignore;
502 case CC_C:
503 case CC_OpenCLKernel:
Saleem Abdulrasool4d321332017-09-26 19:26:01 +0000504 case CC_PreserveMost:
505 case CC_PreserveAll:
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000506 case CC_Win64:
507 return CCCR_OK;
508 default:
509 return CCCR_Warning;
510 }
511}
512
513MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
514 const TargetOptions &Opts)
515 : WindowsARM64TargetInfo(Triple, Opts) {
516 TheCXXABI.set(TargetCXXABI::Microsoft);
517}
518
Tim Northoverad4c5db2017-07-24 17:06:23 +0000519void MicrosoftARM64TargetInfo::getVisualStudioDefines(
520 const LangOptions &Opts, MacroBuilder &Builder) const {
521 WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts, Builder);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000522 Builder.defineMacro("_M_ARM64", "1");
523}
524
525void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
526 MacroBuilder &Builder) const {
527 WindowsTargetInfo::getTargetDefines(Opts, Builder);
528 getVisualStudioDefines(Opts, Builder);
529}
530
Martin Storsjo31cac7a2017-08-13 19:42:17 +0000531MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
532 const TargetOptions &Opts)
533 : WindowsARM64TargetInfo(Triple, Opts) {
534 TheCXXABI.set(TargetCXXABI::GenericAArch64);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000535}
536
537DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
538 const TargetOptions &Opts)
539 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
540 Int64Type = SignedLongLong;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000541 UseSignedCharForObjCBool = false;
542
543 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
544 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
545
546 TheCXXABI.set(TargetCXXABI::iOS64);
547}
548
549void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
550 const llvm::Triple &Triple,
551 MacroBuilder &Builder) const {
552 Builder.defineMacro("__AARCH64_SIMD__");
553 Builder.defineMacro("__ARM64_ARCH_8__");
554 Builder.defineMacro("__ARM_NEON__");
555 Builder.defineMacro("__LITTLE_ENDIAN__");
556 Builder.defineMacro("__REGISTER_PREFIX__", "");
557 Builder.defineMacro("__arm64", "1");
558 Builder.defineMacro("__arm64__", "1");
559
560 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
561}
562
563TargetInfo::BuiltinVaListKind
564DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
565 return TargetInfo::CharPtrBuiltinVaList;
566}
567
568// 64-bit RenderScript is aarch64
569RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
570 const TargetOptions &Opts)
571 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
572 Triple.getOSName(),
573 Triple.getEnvironmentName()),
574 Opts) {
575 IsRenderScriptTarget = true;
576}
577
578void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
579 MacroBuilder &Builder) const {
580 Builder.defineMacro("__RENDERSCRIPT__");
581 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
582}