1 //===--- 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"
18 #include "llvm/ADT/StringExtras.h"
19
20 using namespace clang;
21 using namespace clang::targets;
22
23 const 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},
30 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
31 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
32 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
33 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
34 #include "clang/Basic/BuiltinsAArch64.def"
35 };
36
AArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)37 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
38 const TargetOptions &Opts)
39 : TargetInfo(Triple), ABI("aapcs") {
40 if (getTriple().isOSOpenBSD()) {
41 Int64Type = SignedLongLong;
42 IntMaxType = SignedLongLong;
43 } else {
44 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
45 WCharType = UnsignedInt;
46
47 Int64Type = SignedLong;
48 IntMaxType = SignedLong;
49 }
50
51 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
52 HasLegalHalfType = true;
53 HasFloat16 = true;
54
55 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
getABI() const87 StringRef AArch64TargetInfo::getABI() const { return ABI; }
88
setABI(const std::string & Name)89 bool AArch64TargetInfo::setABI(const std::string &Name) {
90 if (Name != "aapcs" && Name != "darwinpcs")
91 return false;
92
93 ABI = Name;
94 return true;
95 }
96
isValidCPUName(StringRef Name) const97 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
98 return Name == "generic" ||
99 llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
100 }
101
setCPU(const std::string & Name)102 bool AArch64TargetInfo::setCPU(const std::string &Name) {
103 return isValidCPUName(Name);
104 }
105
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const106 void AArch64TargetInfo::fillValidCPUList(
107 SmallVectorImpl<StringRef> &Values) const {
108 llvm::AArch64::fillValidCPUArchList(Values);
109 }
110
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const111 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
112 MacroBuilder &Builder) const {
113 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
114 }
115
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const116 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
117 MacroBuilder &Builder) const {
118 // Also include the ARMv8.1 defines
119 getTargetDefinesARMV81A(Opts, Builder);
120 }
121
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const122 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
123 MacroBuilder &Builder) const {
124 // Target identification.
125 Builder.defineMacro("__aarch64__");
126 // For bare-metal.
127 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
128 getTriple().isOSBinFormatELF())
129 Builder.defineMacro("__ELF__");
130
131 // Target properties.
132 if (!getTriple().isOSWindows()) {
133 Builder.defineMacro("_LP64");
134 Builder.defineMacro("__LP64__");
135 }
136
137 // ACLE predefines. Many can only have one possible value on v8 AArch64.
138 Builder.defineMacro("__ARM_ACLE", "200");
139 Builder.defineMacro("__ARM_ARCH", "8");
140 Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
141
142 Builder.defineMacro("__ARM_64BIT_STATE", "1");
143 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
144 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
145
146 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
147 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
148 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
149 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
150 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
151 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
152 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
153
154 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
155
156 // 0xe implies support for half, single and double precision operations.
157 Builder.defineMacro("__ARM_FP", "0xE");
158
159 // PCS specifies this for SysV variants, which is all we support. Other ABIs
160 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
161 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
162 Builder.defineMacro("__ARM_FP16_ARGS", "1");
163
164 if (Opts.UnsafeFPMath)
165 Builder.defineMacro("__ARM_FP_FAST", "1");
166
167 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
168 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
169
170 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
171
172 if (FPU & NeonMode) {
173 Builder.defineMacro("__ARM_NEON", "1");
174 // 64-bit NEON supports half, single and double precision operations.
175 Builder.defineMacro("__ARM_NEON_FP", "0xE");
176 }
177
178 if (FPU & SveMode)
179 Builder.defineMacro("__ARM_FEATURE_SVE", "1");
180
181 if (CRC)
182 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
183
184 if (Crypto)
185 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
186
187 if (Unaligned)
188 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
189
190 if ((FPU & NeonMode) && HasFullFP16)
191 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
192 if (HasFullFP16)
193 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
194
195 if (HasDotProd)
196 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
197
198 if ((FPU & NeonMode) && HasFP16FML)
199 Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
200
201 switch (ArchKind) {
202 default:
203 break;
204 case llvm::AArch64::ArchKind::ARMV8_1A:
205 getTargetDefinesARMV81A(Opts, Builder);
206 break;
207 case llvm::AArch64::ArchKind::ARMV8_2A:
208 getTargetDefinesARMV82A(Opts, Builder);
209 break;
210 }
211
212 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
213 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
214 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
215 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
216 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
217 }
218
getTargetBuiltins() const219 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
220 return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
221 Builtin::FirstTSBuiltin);
222 }
223
hasFeature(StringRef Feature) const224 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
225 return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
226 (Feature == "neon" && (FPU & NeonMode)) ||
227 (Feature == "sve" && (FPU & SveMode));
228 }
229
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)230 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
231 DiagnosticsEngine &Diags) {
232 FPU = FPUMode;
233 CRC = 0;
234 Crypto = 0;
235 Unaligned = 1;
236 HasFullFP16 = 0;
237 HasDotProd = 0;
238 HasFP16FML = 0;
239 ArchKind = llvm::AArch64::ArchKind::ARMV8A;
240
241 for (const auto &Feature : Features) {
242 if (Feature == "+neon")
243 FPU |= NeonMode;
244 if (Feature == "+sve")
245 FPU |= SveMode;
246 if (Feature == "+crc")
247 CRC = 1;
248 if (Feature == "+crypto")
249 Crypto = 1;
250 if (Feature == "+strict-align")
251 Unaligned = 0;
252 if (Feature == "+v8.1a")
253 ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
254 if (Feature == "+v8.2a")
255 ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
256 if (Feature == "+fullfp16")
257 HasFullFP16 = 1;
258 if (Feature == "+dotprod")
259 HasDotProd = 1;
260 if (Feature == "+fp16fml")
261 HasFP16FML = 1;
262 }
263
264 setDataLayout();
265
266 return true;
267 }
268
269 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const270 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
271 switch (CC) {
272 case CC_C:
273 case CC_Swift:
274 case CC_PreserveMost:
275 case CC_PreserveAll:
276 case CC_OpenCLKernel:
277 case CC_AArch64VectorCall:
278 case CC_Win64:
279 return CCCR_OK;
280 default:
281 return CCCR_Warning;
282 }
283 }
284
isCLZForZeroUndef() const285 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
286
getBuiltinVaListKind() const287 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
288 return TargetInfo::AArch64ABIBuiltinVaList;
289 }
290
291 const char *const AArch64TargetInfo::GCCRegNames[] = {
292 // 32-bit Integer registers
293 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
294 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
295 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
296
297 // 64-bit Integer registers
298 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
299 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
300 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
301
302 // 32-bit floating point regsisters
303 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
304 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
305 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
306
307 // 64-bit floating point regsisters
308 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
309 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
310 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
311
312 // Vector registers
313 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
314 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
315 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
316 };
317
getGCCRegNames() const318 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
319 return llvm::makeArrayRef(GCCRegNames);
320 }
321
322 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
323 {{"w31"}, "wsp"},
324 {{"x31"}, "sp"},
325 // GCC rN registers are aliases of xN registers.
326 {{"r0"}, "x0"},
327 {{"r1"}, "x1"},
328 {{"r2"}, "x2"},
329 {{"r3"}, "x3"},
330 {{"r4"}, "x4"},
331 {{"r5"}, "x5"},
332 {{"r6"}, "x6"},
333 {{"r7"}, "x7"},
334 {{"r8"}, "x8"},
335 {{"r9"}, "x9"},
336 {{"r10"}, "x10"},
337 {{"r11"}, "x11"},
338 {{"r12"}, "x12"},
339 {{"r13"}, "x13"},
340 {{"r14"}, "x14"},
341 {{"r15"}, "x15"},
342 {{"r16"}, "x16"},
343 {{"r17"}, "x17"},
344 {{"r18"}, "x18"},
345 {{"r19"}, "x19"},
346 {{"r20"}, "x20"},
347 {{"r21"}, "x21"},
348 {{"r22"}, "x22"},
349 {{"r23"}, "x23"},
350 {{"r24"}, "x24"},
351 {{"r25"}, "x25"},
352 {{"r26"}, "x26"},
353 {{"r27"}, "x27"},
354 {{"r28"}, "x28"},
355 {{"r29", "x29"}, "fp"},
356 {{"r30", "x30"}, "lr"},
357 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
358 // don't want to substitute one of these for a different-sized one.
359 };
360
getGCCRegAliases() const361 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
362 return llvm::makeArrayRef(GCCRegAliases);
363 }
364
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const365 bool AArch64TargetInfo::validateAsmConstraint(
366 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
367 switch (*Name) {
368 default:
369 return false;
370 case 'w': // Floating point and SIMD registers (V0-V31)
371 Info.setAllowsRegister();
372 return true;
373 case 'I': // Constant that can be used with an ADD instruction
374 case 'J': // Constant that can be used with a SUB instruction
375 case 'K': // Constant that can be used with a 32-bit logical instruction
376 case 'L': // Constant that can be used with a 64-bit logical instruction
377 case 'M': // Constant that can be used as a 32-bit MOV immediate
378 case 'N': // Constant that can be used as a 64-bit MOV immediate
379 case 'Y': // Floating point constant zero
380 case 'Z': // Integer constant zero
381 return true;
382 case 'Q': // A memory reference with base register and no offset
383 Info.setAllowsMemory();
384 return true;
385 case 'S': // A symbolic address
386 Info.setAllowsRegister();
387 return true;
388 case 'U':
389 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
390 // Utf: A memory address suitable for ldp/stp in TF mode.
391 // Usa: An absolute symbolic address.
392 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
393 llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
394 case 'z': // Zero register, wzr or xzr
395 Info.setAllowsRegister();
396 return true;
397 case 'x': // Floating point and SIMD registers (V0-V15)
398 Info.setAllowsRegister();
399 return true;
400 }
401 return false;
402 }
403
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const404 bool AArch64TargetInfo::validateConstraintModifier(
405 StringRef Constraint, char Modifier, unsigned Size,
406 std::string &SuggestedModifier) const {
407 // Strip off constraint modifiers.
408 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
409 Constraint = Constraint.substr(1);
410
411 switch (Constraint[0]) {
412 default:
413 return true;
414 case 'z':
415 case 'r': {
416 switch (Modifier) {
417 case 'x':
418 case 'w':
419 // For now assume that the person knows what they're
420 // doing with the modifier.
421 return true;
422 default:
423 // By default an 'r' constraint will be in the 'x'
424 // registers.
425 if (Size == 64)
426 return true;
427
428 SuggestedModifier = "w";
429 return false;
430 }
431 }
432 }
433 }
434
getClobbers() const435 const char *AArch64TargetInfo::getClobbers() const { return ""; }
436
getEHDataRegisterNumber(unsigned RegNo) const437 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
438 if (RegNo == 0)
439 return 0;
440 if (RegNo == 1)
441 return 1;
442 return -1;
443 }
444
AArch64leTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)445 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
446 const TargetOptions &Opts)
447 : AArch64TargetInfo(Triple, Opts) {}
448
setDataLayout()449 void AArch64leTargetInfo::setDataLayout() {
450 if (getTriple().isOSBinFormatMachO())
451 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128");
452 else
453 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
454 }
455
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const456 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
457 MacroBuilder &Builder) const {
458 Builder.defineMacro("__AARCH64EL__");
459 AArch64TargetInfo::getTargetDefines(Opts, Builder);
460 }
461
AArch64beTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)462 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
463 const TargetOptions &Opts)
464 : AArch64TargetInfo(Triple, Opts) {}
465
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const466 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
467 MacroBuilder &Builder) const {
468 Builder.defineMacro("__AARCH64EB__");
469 Builder.defineMacro("__AARCH_BIG_ENDIAN");
470 Builder.defineMacro("__ARM_BIG_ENDIAN");
471 AArch64TargetInfo::getTargetDefines(Opts, Builder);
472 }
473
setDataLayout()474 void AArch64beTargetInfo::setDataLayout() {
475 assert(!getTriple().isOSBinFormatMachO());
476 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
477 }
478
WindowsARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)479 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
480 const TargetOptions &Opts)
481 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
482
483 // This is an LLP64 platform.
484 // int:4, long:4, long long:8, long double:8.
485 IntWidth = IntAlign = 32;
486 LongWidth = LongAlign = 32;
487 DoubleAlign = LongLongAlign = 64;
488 LongDoubleWidth = LongDoubleAlign = 64;
489 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
490 IntMaxType = SignedLongLong;
491 Int64Type = SignedLongLong;
492 SizeType = UnsignedLongLong;
493 PtrDiffType = SignedLongLong;
494 IntPtrType = SignedLongLong;
495 }
496
setDataLayout()497 void WindowsARM64TargetInfo::setDataLayout() {
498 resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
499 }
500
501 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const502 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
503 return TargetInfo::CharPtrBuiltinVaList;
504 }
505
506 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const507 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
508 switch (CC) {
509 case CC_X86StdCall:
510 case CC_X86ThisCall:
511 case CC_X86FastCall:
512 case CC_X86VectorCall:
513 return CCCR_Ignore;
514 case CC_C:
515 case CC_OpenCLKernel:
516 case CC_PreserveMost:
517 case CC_PreserveAll:
518 case CC_Swift:
519 case CC_Win64:
520 return CCCR_OK;
521 default:
522 return CCCR_Warning;
523 }
524 }
525
MicrosoftARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)526 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
527 const TargetOptions &Opts)
528 : WindowsARM64TargetInfo(Triple, Opts) {
529 TheCXXABI.set(TargetCXXABI::Microsoft);
530 }
531
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const532 void MicrosoftARM64TargetInfo::getVisualStudioDefines(
533 const LangOptions &Opts, MacroBuilder &Builder) const {
534 WindowsTargetInfo<AArch64leTargetInfo>::getVisualStudioDefines(Opts, Builder);
535 Builder.defineMacro("_M_ARM64", "1");
536 }
537
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const538 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
539 MacroBuilder &Builder) const {
540 WindowsTargetInfo::getTargetDefines(Opts, Builder);
541 getVisualStudioDefines(Opts, Builder);
542 }
543
544 TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const545 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
546 return CCK_MicrosoftWin64;
547 }
548
MinGWARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)549 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
550 const TargetOptions &Opts)
551 : WindowsARM64TargetInfo(Triple, Opts) {
552 TheCXXABI.set(TargetCXXABI::GenericAArch64);
553 }
554
DarwinAArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)555 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
556 const TargetOptions &Opts)
557 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
558 Int64Type = SignedLongLong;
559 UseSignedCharForObjCBool = false;
560
561 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
562 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
563
564 TheCXXABI.set(TargetCXXABI::iOS64);
565 }
566
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const567 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
568 const llvm::Triple &Triple,
569 MacroBuilder &Builder) const {
570 Builder.defineMacro("__AARCH64_SIMD__");
571 Builder.defineMacro("__ARM64_ARCH_8__");
572 Builder.defineMacro("__ARM_NEON__");
573 Builder.defineMacro("__LITTLE_ENDIAN__");
574 Builder.defineMacro("__REGISTER_PREFIX__", "");
575 Builder.defineMacro("__arm64", "1");
576 Builder.defineMacro("__arm64__", "1");
577
578 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
579 }
580
581 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const582 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
583 return TargetInfo::CharPtrBuiltinVaList;
584 }
585
586 // 64-bit RenderScript is aarch64
RenderScript64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)587 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
588 const TargetOptions &Opts)
589 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
590 Triple.getOSName(),
591 Triple.getEnvironmentName()),
592 Opts) {
593 IsRenderScriptTarget = true;
594 }
595
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const596 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
597 MacroBuilder &Builder) const {
598 Builder.defineMacro("__RENDERSCRIPT__");
599 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
600 }
601