1 //===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements AArch64 TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "AArch64.h"
14 #include "clang/Basic/LangOptions.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 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/TargetParser/AArch64TargetParser.h"
21 #include "llvm/TargetParser/ARMTargetParserCommon.h"
22 #include <optional>
23
24 using namespace clang;
25 using namespace clang::targets;
26
27 static constexpr Builtin::Info BuiltinInfo[] = {
28 #define BUILTIN(ID, TYPE, ATTRS) \
29 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
30 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
31 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
32 #include "clang/Basic/BuiltinsNEON.def"
33
34 #define BUILTIN(ID, TYPE, ATTRS) \
35 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
36 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
37 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
38 #include "clang/Basic/BuiltinsSVE.def"
39
40 #define BUILTIN(ID, TYPE, ATTRS) \
41 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
42 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
43 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
44 #include "clang/Basic/BuiltinsSME.def"
45
46 #define BUILTIN(ID, TYPE, ATTRS) \
47 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
48 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
49 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
50 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
51 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
52 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
53 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
54 #include "clang/Basic/BuiltinsAArch64.def"
55 };
56
setArchFeatures()57 void AArch64TargetInfo::setArchFeatures() {
58 if (*ArchInfo == llvm::AArch64::ARMV8R) {
59 HasDotProd = true;
60 HasDIT = true;
61 HasFlagM = true;
62 HasRCPC = true;
63 FPU |= NeonMode;
64 HasCCPP = true;
65 HasCRC = true;
66 HasLSE = true;
67 HasRDM = true;
68 } else if (ArchInfo->Version.getMajor() == 8) {
69 if (ArchInfo->Version.getMinor() >= 7u) {
70 HasWFxT = true;
71 }
72 if (ArchInfo->Version.getMinor() >= 6u) {
73 HasBFloat16 = true;
74 HasMatMul = true;
75 }
76 if (ArchInfo->Version.getMinor() >= 5u) {
77 HasAlternativeNZCV = true;
78 HasFRInt3264 = true;
79 HasSSBS = true;
80 HasSB = true;
81 HasPredRes = true;
82 HasBTI = true;
83 }
84 if (ArchInfo->Version.getMinor() >= 4u) {
85 HasDotProd = true;
86 HasDIT = true;
87 HasFlagM = true;
88 }
89 if (ArchInfo->Version.getMinor() >= 3u) {
90 HasRCPC = true;
91 FPU |= NeonMode;
92 }
93 if (ArchInfo->Version.getMinor() >= 2u) {
94 HasCCPP = true;
95 }
96 if (ArchInfo->Version.getMinor() >= 1u) {
97 HasCRC = true;
98 HasLSE = true;
99 HasRDM = true;
100 }
101 } else if (ArchInfo->Version.getMajor() == 9) {
102 if (ArchInfo->Version.getMinor() >= 2u) {
103 HasWFxT = true;
104 }
105 if (ArchInfo->Version.getMinor() >= 1u) {
106 HasBFloat16 = true;
107 HasMatMul = true;
108 }
109 FPU |= SveMode;
110 HasSVE2 = true;
111 HasFullFP16 = true;
112 HasAlternativeNZCV = true;
113 HasFRInt3264 = true;
114 HasSSBS = true;
115 HasSB = true;
116 HasPredRes = true;
117 HasBTI = true;
118 HasDotProd = true;
119 HasDIT = true;
120 HasFlagM = true;
121 HasRCPC = true;
122 FPU |= NeonMode;
123 HasCCPP = true;
124 HasCRC = true;
125 HasLSE = true;
126 HasRDM = true;
127 }
128 }
129
AArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)130 AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
131 const TargetOptions &Opts)
132 : TargetInfo(Triple), ABI("aapcs") {
133 if (getTriple().isOSOpenBSD()) {
134 Int64Type = SignedLongLong;
135 IntMaxType = SignedLongLong;
136 } else {
137 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
138 WCharType = UnsignedInt;
139
140 Int64Type = SignedLong;
141 IntMaxType = SignedLong;
142 }
143
144 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
145 HasLegalHalfType = true;
146 HalfArgsAndReturns = true;
147 HasFloat16 = true;
148 HasStrictFP = true;
149
150 if (Triple.isArch64Bit())
151 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
152 else
153 LongWidth = LongAlign = PointerWidth = PointerAlign = 32;
154
155 MaxVectorAlign = 128;
156 MaxAtomicInlineWidth = 128;
157 MaxAtomicPromoteWidth = 128;
158
159 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
160 LongDoubleFormat = &llvm::APFloat::IEEEquad();
161
162 BFloat16Width = BFloat16Align = 16;
163 BFloat16Format = &llvm::APFloat::BFloat();
164
165 // Make __builtin_ms_va_list available.
166 HasBuiltinMSVaList = true;
167
168 // Make the SVE types available. Note that this deliberately doesn't
169 // depend on SveMode, since in principle it should be possible to turn
170 // SVE on and off within a translation unit. It should also be possible
171 // to compile the global declaration:
172 //
173 // __SVInt8_t *ptr;
174 //
175 // even without SVE.
176 HasAArch64SVETypes = true;
177
178 // {} in inline assembly are neon specifiers, not assembly variant
179 // specifiers.
180 NoAsmVariants = true;
181
182 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
183 // contributes to the alignment of the containing aggregate in the same way
184 // a plain (non bit-field) member of that type would, without exception for
185 // zero-sized or anonymous bit-fields."
186 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
187 UseZeroLengthBitfieldAlignment = true;
188
189 // AArch64 targets default to using the ARM C++ ABI.
190 TheCXXABI.set(TargetCXXABI::GenericAArch64);
191
192 if (Triple.getOS() == llvm::Triple::Linux)
193 this->MCountName = "\01_mcount";
194 else if (Triple.getOS() == llvm::Triple::UnknownOS)
195 this->MCountName =
196 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
197 }
198
getABI() const199 StringRef AArch64TargetInfo::getABI() const { return ABI; }
200
setABI(const std::string & Name)201 bool AArch64TargetInfo::setABI(const std::string &Name) {
202 if (Name != "aapcs" && Name != "darwinpcs")
203 return false;
204
205 ABI = Name;
206 return true;
207 }
208
validateBranchProtection(StringRef Spec,StringRef,BranchProtectionInfo & BPI,StringRef & Err) const209 bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
210 BranchProtectionInfo &BPI,
211 StringRef &Err) const {
212 llvm::ARM::ParsedBranchProtection PBP;
213 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
214 return false;
215
216 BPI.SignReturnAddr =
217 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
218 .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
219 .Case("all", LangOptions::SignReturnAddressScopeKind::All)
220 .Default(LangOptions::SignReturnAddressScopeKind::None);
221
222 if (PBP.Key == "a_key")
223 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
224 else
225 BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
226
227 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
228 BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
229 BPI.GuardedControlStack = PBP.GuardedControlStack;
230 return true;
231 }
232
isValidCPUName(StringRef Name) const233 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
234 return Name == "generic" || llvm::AArch64::parseCpu(Name);
235 }
236
setCPU(const std::string & Name)237 bool AArch64TargetInfo::setCPU(const std::string &Name) {
238 return isValidCPUName(Name);
239 }
240
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const241 void AArch64TargetInfo::fillValidCPUList(
242 SmallVectorImpl<StringRef> &Values) const {
243 llvm::AArch64::fillValidCPUArchList(Values);
244 }
245
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const246 void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
247 MacroBuilder &Builder) const {
248 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
249 }
250
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const251 void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
252 MacroBuilder &Builder) const {
253 // Also include the ARMv8.1 defines
254 getTargetDefinesARMV81A(Opts, Builder);
255 }
256
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const257 void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
258 MacroBuilder &Builder) const {
259 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
260 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
261 // Also include the Armv8.2 defines
262 getTargetDefinesARMV82A(Opts, Builder);
263 }
264
getTargetDefinesARMV84A(const LangOptions & Opts,MacroBuilder & Builder) const265 void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
266 MacroBuilder &Builder) const {
267 // Also include the Armv8.3 defines
268 getTargetDefinesARMV83A(Opts, Builder);
269 }
270
getTargetDefinesARMV85A(const LangOptions & Opts,MacroBuilder & Builder) const271 void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
272 MacroBuilder &Builder) const {
273 Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
274 Builder.defineMacro("__ARM_FEATURE_BTI", "1");
275 // Also include the Armv8.4 defines
276 getTargetDefinesARMV84A(Opts, Builder);
277 }
278
getTargetDefinesARMV86A(const LangOptions & Opts,MacroBuilder & Builder) const279 void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts,
280 MacroBuilder &Builder) const {
281 // Also include the Armv8.5 defines
282 // FIXME: Armv8.6 makes the following extensions mandatory:
283 // - __ARM_FEATURE_BF16
284 // - __ARM_FEATURE_MATMUL_INT8
285 // Handle them here.
286 getTargetDefinesARMV85A(Opts, Builder);
287 }
288
getTargetDefinesARMV87A(const LangOptions & Opts,MacroBuilder & Builder) const289 void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
290 MacroBuilder &Builder) const {
291 // Also include the Armv8.6 defines
292 getTargetDefinesARMV86A(Opts, Builder);
293 }
294
getTargetDefinesARMV88A(const LangOptions & Opts,MacroBuilder & Builder) const295 void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
296 MacroBuilder &Builder) const {
297 // Also include the Armv8.7 defines
298 getTargetDefinesARMV87A(Opts, Builder);
299 }
300
getTargetDefinesARMV89A(const LangOptions & Opts,MacroBuilder & Builder) const301 void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
302 MacroBuilder &Builder) const {
303 // Also include the Armv8.8 defines
304 getTargetDefinesARMV88A(Opts, Builder);
305 }
306
getTargetDefinesARMV9A(const LangOptions & Opts,MacroBuilder & Builder) const307 void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
308 MacroBuilder &Builder) const {
309 // Armv9-A maps to Armv8.5-A
310 getTargetDefinesARMV85A(Opts, Builder);
311 }
312
getTargetDefinesARMV91A(const LangOptions & Opts,MacroBuilder & Builder) const313 void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
314 MacroBuilder &Builder) const {
315 // Armv9.1-A maps to Armv8.6-A
316 getTargetDefinesARMV86A(Opts, Builder);
317 }
318
getTargetDefinesARMV92A(const LangOptions & Opts,MacroBuilder & Builder) const319 void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
320 MacroBuilder &Builder) const {
321 // Armv9.2-A maps to Armv8.7-A
322 getTargetDefinesARMV87A(Opts, Builder);
323 }
324
getTargetDefinesARMV93A(const LangOptions & Opts,MacroBuilder & Builder) const325 void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
326 MacroBuilder &Builder) const {
327 // Armv9.3-A maps to Armv8.8-A
328 getTargetDefinesARMV88A(Opts, Builder);
329 }
330
getTargetDefinesARMV94A(const LangOptions & Opts,MacroBuilder & Builder) const331 void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
332 MacroBuilder &Builder) const {
333 // Armv9.4-A maps to Armv8.9-A
334 getTargetDefinesARMV89A(Opts, Builder);
335 }
336
getTargetDefinesARMV95A(const LangOptions & Opts,MacroBuilder & Builder) const337 void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
338 MacroBuilder &Builder) const {
339 // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
340 getTargetDefinesARMV94A(Opts, Builder);
341 }
342
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const343 void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
344 MacroBuilder &Builder) const {
345 // Target identification.
346 if (getTriple().isWindowsArm64EC()) {
347 // Define the same set of macros as would be defined on x86_64 to ensure that
348 // ARM64EC datatype layouts match those of x86_64 compiled code
349 Builder.defineMacro("__amd64__");
350 Builder.defineMacro("__amd64");
351 Builder.defineMacro("__x86_64");
352 Builder.defineMacro("__x86_64__");
353 Builder.defineMacro("__arm64ec__");
354 } else {
355 Builder.defineMacro("__aarch64__");
356 }
357
358 // Inline assembly supports AArch64 flag outputs.
359 Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
360
361 std::string CodeModel = getTargetOpts().CodeModel;
362 if (CodeModel == "default")
363 CodeModel = "small";
364 for (char &c : CodeModel)
365 c = toupper(c);
366 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
367
368 // ACLE predefines. Many can only have one possible value on v8 AArch64.
369 Builder.defineMacro("__ARM_ACLE", "200");
370 Builder.defineMacro("__ARM_ARCH",
371 std::to_string(ArchInfo->Version.getMajor()));
372 Builder.defineMacro("__ARM_ARCH_PROFILE",
373 std::string("'") + (char)ArchInfo->Profile + "'");
374
375 Builder.defineMacro("__ARM_64BIT_STATE", "1");
376 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
377 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
378
379 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
380 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
381 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
382 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
383 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
384 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
385 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
386
387 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
388
389 // These macros are set when Clang can parse declarations with these
390 // attributes.
391 Builder.defineMacro("__ARM_STATE_ZA", "1");
392 Builder.defineMacro("__ARM_STATE_ZT0", "1");
393
394 // 0xe implies support for half, single and double precision operations.
395 if (FPU & FPUMode)
396 Builder.defineMacro("__ARM_FP", "0xE");
397
398 // PCS specifies this for SysV variants, which is all we support. Other ABIs
399 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
400 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
401 Builder.defineMacro("__ARM_FP16_ARGS", "1");
402
403 if (Opts.UnsafeFPMath)
404 Builder.defineMacro("__ARM_FP_FAST", "1");
405
406 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
407 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
408
409 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
410
411 if (FPU & NeonMode) {
412 Builder.defineMacro("__ARM_NEON", "1");
413 // 64-bit NEON supports half, single and double precision operations.
414 Builder.defineMacro("__ARM_NEON_FP", "0xE");
415 }
416
417 if (FPU & SveMode)
418 Builder.defineMacro("__ARM_FEATURE_SVE", "1");
419
420 if ((FPU & NeonMode) && (FPU & SveMode))
421 Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
422
423 if (HasSVE2)
424 Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
425
426 if (HasSVE2 && HasSVE2AES)
427 Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
428
429 if (HasSVE2 && HasSVE2BitPerm)
430 Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
431
432 if (HasSVE2 && HasSVE2SHA3)
433 Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
434
435 if (HasSVE2 && HasSVE2SM4)
436 Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
437
438 if (HasSME) {
439 Builder.defineMacro("__ARM_FEATURE_SME");
440 Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
441 }
442
443 if (HasSME2) {
444 Builder.defineMacro("__ARM_FEATURE_SME");
445 Builder.defineMacro("__ARM_FEATURE_SME2");
446 Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
447 }
448
449 if (HasCRC)
450 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
451
452 if (HasRCPC3)
453 Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
454 else if (HasRCPC)
455 Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
456
457 if (HasFMV)
458 Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
459
460 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
461 // macros for AES, SHA2, SHA3 and SM4
462 if (HasAES && HasSHA2)
463 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
464
465 if (HasAES)
466 Builder.defineMacro("__ARM_FEATURE_AES", "1");
467
468 if (HasSHA2)
469 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
470
471 if (HasSHA3) {
472 Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
473 Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
474 }
475
476 if (HasSM4) {
477 Builder.defineMacro("__ARM_FEATURE_SM3", "1");
478 Builder.defineMacro("__ARM_FEATURE_SM4", "1");
479 }
480
481 if (HasPAuth)
482 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
483
484 if (HasUnaligned)
485 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
486
487 if ((FPU & NeonMode) && HasFullFP16)
488 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
489 if (HasFullFP16)
490 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
491
492 if (HasDotProd)
493 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
494
495 if (HasMTE)
496 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
497
498 if (HasTME)
499 Builder.defineMacro("__ARM_FEATURE_TME", "1");
500
501 if (HasMatMul)
502 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
503
504 if (HasLSE)
505 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
506
507 if (HasBFloat16) {
508 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
509 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
510 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
511 Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
512 }
513
514 if ((FPU & SveMode) && HasBFloat16) {
515 Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
516 }
517
518 if ((FPU & SveMode) && HasMatmulFP64)
519 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
520
521 if ((FPU & SveMode) && HasMatmulFP32)
522 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
523
524 if ((FPU & SveMode) && HasMatMul)
525 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
526
527 if ((FPU & NeonMode) && HasFP16FML)
528 Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
529
530 if (Opts.hasSignReturnAddress()) {
531 // Bitmask:
532 // 0: Protection using the A key
533 // 1: Protection using the B key
534 // 2: Protection including leaf functions
535 unsigned Value = 0;
536
537 if (Opts.isSignReturnAddressWithAKey())
538 Value |= (1 << 0);
539 else
540 Value |= (1 << 1);
541
542 if (Opts.isSignReturnAddressScopeAll())
543 Value |= (1 << 2);
544
545 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
546 }
547
548 if (Opts.BranchTargetEnforcement)
549 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
550
551 if (Opts.GuardedControlStack)
552 Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
553
554 if (HasLS64)
555 Builder.defineMacro("__ARM_FEATURE_LS64", "1");
556
557 if (HasRandGen)
558 Builder.defineMacro("__ARM_FEATURE_RNG", "1");
559
560 if (HasMOPS)
561 Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
562
563 if (HasD128)
564 Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
565
566 if (HasGCS)
567 Builder.defineMacro("__ARM_FEATURE_GCS", "1");
568
569 if (*ArchInfo == llvm::AArch64::ARMV8_1A)
570 getTargetDefinesARMV81A(Opts, Builder);
571 else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
572 getTargetDefinesARMV82A(Opts, Builder);
573 else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
574 getTargetDefinesARMV83A(Opts, Builder);
575 else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
576 getTargetDefinesARMV84A(Opts, Builder);
577 else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
578 getTargetDefinesARMV85A(Opts, Builder);
579 else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
580 getTargetDefinesARMV86A(Opts, Builder);
581 else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
582 getTargetDefinesARMV87A(Opts, Builder);
583 else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
584 getTargetDefinesARMV88A(Opts, Builder);
585 else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
586 getTargetDefinesARMV89A(Opts, Builder);
587 else if (*ArchInfo == llvm::AArch64::ARMV9A)
588 getTargetDefinesARMV9A(Opts, Builder);
589 else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
590 getTargetDefinesARMV91A(Opts, Builder);
591 else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
592 getTargetDefinesARMV92A(Opts, Builder);
593 else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
594 getTargetDefinesARMV93A(Opts, Builder);
595 else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
596 getTargetDefinesARMV94A(Opts, Builder);
597 else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
598 getTargetDefinesARMV95A(Opts, Builder);
599
600 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
601 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
602 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
603 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
604 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
605 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
606
607 // Allow detection of fast FMA support.
608 Builder.defineMacro("__FP_FAST_FMA", "1");
609 Builder.defineMacro("__FP_FAST_FMAF", "1");
610
611 // C/C++ operators work on both VLS and VLA SVE types
612 if (FPU & SveMode)
613 Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
614
615 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
616 Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
617 }
618 }
619
getTargetBuiltins() const620 ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
621 return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
622 Builtin::FirstTSBuiltin);
623 }
624
625 std::optional<std::pair<unsigned, unsigned>>
getVScaleRange(const LangOptions & LangOpts) const626 AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
627 if (LangOpts.VScaleMin || LangOpts.VScaleMax)
628 return std::pair<unsigned, unsigned>(
629 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
630
631 if (hasFeature("sve"))
632 return std::pair<unsigned, unsigned>(1, 16);
633
634 return std::nullopt;
635 }
636
multiVersionSortPriority(StringRef Name) const637 unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
638 if (Name == "default")
639 return 0;
640 if (auto Ext = llvm::AArch64::parseArchExtension(Name))
641 return Ext->FmvPriority;
642 return 0;
643 }
644
multiVersionFeatureCost() const645 unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
646 // Take the maximum priority as per feature cost, so more features win.
647 return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
648 }
649
doesFeatureAffectCodeGen(StringRef Name) const650 bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
651 if (auto Ext = llvm::AArch64::parseArchExtension(Name))
652 return !Ext->DependentFeatures.empty();
653 return false;
654 }
655
getFeatureDependencies(StringRef Name) const656 StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
657 if (auto Ext = llvm::AArch64::parseArchExtension(Name))
658 return Ext->DependentFeatures;
659 return StringRef();
660 }
661
validateCpuSupports(StringRef FeatureStr) const662 bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
663 return llvm::AArch64::parseArchExtension(FeatureStr).has_value();
664 }
665
hasFeature(StringRef Feature) const666 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
667 return llvm::StringSwitch<bool>(Feature)
668 .Cases("aarch64", "arm64", "arm", true)
669 .Case("fmv", HasFMV)
670 .Cases("neon", "fp", "simd", FPU & NeonMode)
671 .Case("jscvt", HasJSCVT)
672 .Case("fcma", HasFCMA)
673 .Case("rng", HasRandGen)
674 .Case("flagm", HasFlagM)
675 .Case("flagm2", HasAlternativeNZCV)
676 .Case("fp16fml", HasFP16FML)
677 .Case("dotprod", HasDotProd)
678 .Case("sm4", HasSM4)
679 .Case("rdm", HasRDM)
680 .Case("lse", HasLSE)
681 .Case("crc", HasCRC)
682 .Case("sha2", HasSHA2)
683 .Case("sha3", HasSHA3)
684 .Cases("aes", "pmull", HasAES)
685 .Cases("fp16", "fullfp16", HasFullFP16)
686 .Case("dit", HasDIT)
687 .Case("dpb", HasCCPP)
688 .Case("dpb2", HasCCDP)
689 .Case("rcpc", HasRCPC)
690 .Case("frintts", HasFRInt3264)
691 .Case("i8mm", HasMatMul)
692 .Case("bf16", HasBFloat16)
693 .Case("sve", FPU & SveMode)
694 .Case("sve-bf16", FPU & SveMode && HasBFloat16)
695 .Case("sve-i8mm", FPU & SveMode && HasMatMul)
696 .Case("f32mm", FPU & SveMode && HasMatmulFP32)
697 .Case("f64mm", FPU & SveMode && HasMatmulFP64)
698 .Case("sve2", FPU & SveMode && HasSVE2)
699 .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
700 .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
701 .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
702 .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
703 .Case("sme", HasSME)
704 .Case("sme2", HasSME2)
705 .Case("sme-f64f64", HasSMEF64F64)
706 .Case("sme-i16i64", HasSMEI16I64)
707 .Case("sme-fa64", HasSMEFA64)
708 .Cases("memtag", "memtag2", HasMTE)
709 .Case("sb", HasSB)
710 .Case("predres", HasPredRes)
711 .Cases("ssbs", "ssbs2", HasSSBS)
712 .Case("bti", HasBTI)
713 .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
714 .Case("wfxt", HasWFxT)
715 .Case("rcpc3", HasRCPC3)
716 .Default(false);
717 }
718
setFeatureEnabled(llvm::StringMap<bool> & Features,StringRef Name,bool Enabled) const719 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
720 StringRef Name, bool Enabled) const {
721 Features[Name] = Enabled;
722 // If the feature is an architecture feature (like v8.2a), add all previous
723 // architecture versions and any dependant target features.
724 const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
725 llvm::AArch64::ArchInfo::findBySubArch(Name);
726
727 if (!ArchInfo)
728 return; // Not an architecture, nothing more to do.
729
730 // Disabling an architecture feature does not affect dependent features
731 if (!Enabled)
732 return;
733
734 for (const auto *OtherArch : llvm::AArch64::ArchInfos)
735 if (ArchInfo->implies(*OtherArch))
736 Features[OtherArch->getSubArch()] = true;
737
738 // Set any features implied by the architecture
739 std::vector<StringRef> CPUFeats;
740 if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
741 for (auto F : CPUFeats) {
742 assert(F[0] == '+' && "Expected + in target feature!");
743 Features[F.drop_front(1)] = true;
744 }
745 }
746 }
747
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)748 bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
749 DiagnosticsEngine &Diags) {
750 for (const auto &Feature : Features) {
751 if (Feature == "-fp-armv8")
752 HasNoFP = true;
753 if (Feature == "-neon")
754 HasNoNeon = true;
755 if (Feature == "-sve")
756 HasNoSVE = true;
757
758 if (Feature == "+neon" || Feature == "+fp-armv8")
759 FPU |= NeonMode;
760 if (Feature == "+jscvt") {
761 HasJSCVT = true;
762 FPU |= NeonMode;
763 }
764 if (Feature == "+fcma") {
765 HasFCMA = true;
766 FPU |= NeonMode;
767 }
768
769 if (Feature == "+sve") {
770 FPU |= NeonMode;
771 FPU |= SveMode;
772 HasFullFP16 = true;
773 }
774 if (Feature == "+sve2") {
775 FPU |= NeonMode;
776 FPU |= SveMode;
777 HasFullFP16 = true;
778 HasSVE2 = true;
779 }
780 if (Feature == "+sve2-aes") {
781 FPU |= NeonMode;
782 FPU |= SveMode;
783 HasFullFP16 = true;
784 HasSVE2 = true;
785 HasSVE2AES = true;
786 }
787 if (Feature == "+sve2-sha3") {
788 FPU |= NeonMode;
789 FPU |= SveMode;
790 HasFullFP16 = true;
791 HasSVE2 = true;
792 HasSVE2SHA3 = true;
793 }
794 if (Feature == "+sve2-sm4") {
795 FPU |= NeonMode;
796 FPU |= SveMode;
797 HasFullFP16 = true;
798 HasSVE2 = true;
799 HasSVE2SM4 = true;
800 }
801 if (Feature == "+sve2-bitperm") {
802 FPU |= NeonMode;
803 FPU |= SveMode;
804 HasFullFP16 = true;
805 HasSVE2 = true;
806 HasSVE2BitPerm = true;
807 }
808 if (Feature == "+f32mm") {
809 FPU |= NeonMode;
810 FPU |= SveMode;
811 HasFullFP16 = true;
812 HasMatmulFP32 = true;
813 }
814 if (Feature == "+f64mm") {
815 FPU |= NeonMode;
816 FPU |= SveMode;
817 HasFullFP16 = true;
818 HasMatmulFP64 = true;
819 }
820 if (Feature == "+sme") {
821 HasSME = true;
822 HasBFloat16 = true;
823 HasFullFP16 = true;
824 }
825 if (Feature == "+sme2") {
826 HasSME = true;
827 HasSME2 = true;
828 HasBFloat16 = true;
829 HasFullFP16 = true;
830 }
831 if (Feature == "+sme-f64f64") {
832 HasSME = true;
833 HasSMEF64F64 = true;
834 HasBFloat16 = true;
835 HasFullFP16 = true;
836 }
837 if (Feature == "+sme-i16i64") {
838 HasSME = true;
839 HasSMEI16I64 = true;
840 HasBFloat16 = true;
841 HasFullFP16 = true;
842 }
843 if (Feature == "+sme-fa64") {
844 FPU |= NeonMode;
845 FPU |= SveMode;
846 HasSME = true;
847 HasSVE2 = true;
848 HasSMEFA64 = true;
849 }
850 if (Feature == "+sb")
851 HasSB = true;
852 if (Feature == "+predres")
853 HasPredRes = true;
854 if (Feature == "+ssbs")
855 HasSSBS = true;
856 if (Feature == "+bti")
857 HasBTI = true;
858 if (Feature == "+wfxt")
859 HasWFxT = true;
860 if (Feature == "-fmv")
861 HasFMV = false;
862 if (Feature == "+crc")
863 HasCRC = true;
864 if (Feature == "+rcpc")
865 HasRCPC = true;
866 if (Feature == "+aes") {
867 FPU |= NeonMode;
868 HasAES = true;
869 }
870 if (Feature == "+sha2") {
871 FPU |= NeonMode;
872 HasSHA2 = true;
873 }
874 if (Feature == "+sha3") {
875 FPU |= NeonMode;
876 HasSHA2 = true;
877 HasSHA3 = true;
878 }
879 if (Feature == "+rdm") {
880 FPU |= NeonMode;
881 HasRDM = true;
882 }
883 if (Feature == "+dit")
884 HasDIT = true;
885 if (Feature == "+cccp")
886 HasCCPP = true;
887 if (Feature == "+ccdp") {
888 HasCCPP = true;
889 HasCCDP = true;
890 }
891 if (Feature == "+fptoint")
892 HasFRInt3264 = true;
893 if (Feature == "+sm4") {
894 FPU |= NeonMode;
895 HasSM4 = true;
896 }
897 if (Feature == "+strict-align")
898 HasUnaligned = false;
899 // All predecessor archs are added but select the latest one for ArchKind.
900 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
901 ArchInfo = &llvm::AArch64::ARMV8A;
902 if (Feature == "+v8.1a" &&
903 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
904 ArchInfo = &llvm::AArch64::ARMV8_1A;
905 if (Feature == "+v8.2a" &&
906 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
907 ArchInfo = &llvm::AArch64::ARMV8_2A;
908 if (Feature == "+v8.3a" &&
909 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
910 ArchInfo = &llvm::AArch64::ARMV8_3A;
911 if (Feature == "+v8.4a" &&
912 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
913 ArchInfo = &llvm::AArch64::ARMV8_4A;
914 if (Feature == "+v8.5a" &&
915 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
916 ArchInfo = &llvm::AArch64::ARMV8_5A;
917 if (Feature == "+v8.6a" &&
918 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
919 ArchInfo = &llvm::AArch64::ARMV8_6A;
920 if (Feature == "+v8.7a" &&
921 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
922 ArchInfo = &llvm::AArch64::ARMV8_7A;
923 if (Feature == "+v8.8a" &&
924 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
925 ArchInfo = &llvm::AArch64::ARMV8_8A;
926 if (Feature == "+v8.9a" &&
927 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
928 ArchInfo = &llvm::AArch64::ARMV8_9A;
929 if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
930 ArchInfo = &llvm::AArch64::ARMV9A;
931 if (Feature == "+v9.1a" &&
932 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
933 ArchInfo = &llvm::AArch64::ARMV9_1A;
934 if (Feature == "+v9.2a" &&
935 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
936 ArchInfo = &llvm::AArch64::ARMV9_2A;
937 if (Feature == "+v9.3a" &&
938 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
939 ArchInfo = &llvm::AArch64::ARMV9_3A;
940 if (Feature == "+v9.4a" &&
941 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
942 ArchInfo = &llvm::AArch64::ARMV9_4A;
943 if (Feature == "+v9.5a" &&
944 ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
945 ArchInfo = &llvm::AArch64::ARMV9_5A;
946 if (Feature == "+v8r")
947 ArchInfo = &llvm::AArch64::ARMV8R;
948 if (Feature == "+fullfp16") {
949 FPU |= NeonMode;
950 HasFullFP16 = true;
951 }
952 if (Feature == "+dotprod") {
953 FPU |= NeonMode;
954 HasDotProd = true;
955 }
956 if (Feature == "+fp16fml") {
957 FPU |= NeonMode;
958 HasFullFP16 = true;
959 HasFP16FML = true;
960 }
961 if (Feature == "+mte")
962 HasMTE = true;
963 if (Feature == "+tme")
964 HasTME = true;
965 if (Feature == "+pauth")
966 HasPAuth = true;
967 if (Feature == "+i8mm")
968 HasMatMul = true;
969 if (Feature == "+bf16")
970 HasBFloat16 = true;
971 if (Feature == "+lse")
972 HasLSE = true;
973 if (Feature == "+ls64")
974 HasLS64 = true;
975 if (Feature == "+rand")
976 HasRandGen = true;
977 if (Feature == "+flagm")
978 HasFlagM = true;
979 if (Feature == "+altnzcv") {
980 HasFlagM = true;
981 HasAlternativeNZCV = true;
982 }
983 if (Feature == "+mops")
984 HasMOPS = true;
985 if (Feature == "+d128")
986 HasD128 = true;
987 if (Feature == "+gcs")
988 HasGCS = true;
989 if (Feature == "+rcpc3")
990 HasRCPC3 = true;
991 }
992
993 // Check features that are manually disabled by command line options.
994 // This needs to be checked after architecture-related features are handled,
995 // making sure they are properly disabled when required.
996 for (const auto &Feature : Features) {
997 if (Feature == "-d128")
998 HasD128 = false;
999 }
1000
1001 setDataLayout();
1002 setArchFeatures();
1003
1004 if (HasNoFP) {
1005 FPU &= ~FPUMode;
1006 FPU &= ~NeonMode;
1007 FPU &= ~SveMode;
1008 }
1009 if (HasNoNeon) {
1010 FPU &= ~NeonMode;
1011 FPU &= ~SveMode;
1012 }
1013 if (HasNoSVE)
1014 FPU &= ~SveMode;
1015
1016 return true;
1017 }
1018
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const1019 bool AArch64TargetInfo::initFeatureMap(
1020 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
1021 const std::vector<std::string> &FeaturesVec) const {
1022 std::vector<std::string> UpdatedFeaturesVec;
1023 // Parse the CPU and add any implied features.
1024 std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
1025 if (CpuInfo) {
1026 auto Exts = CpuInfo->getImpliedExtensions();
1027 std::vector<StringRef> CPUFeats;
1028 llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
1029 for (auto F : CPUFeats) {
1030 assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!");
1031 UpdatedFeaturesVec.push_back(F.str());
1032 }
1033 }
1034
1035 // Process target and dependent features. This is done in two loops collecting
1036 // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
1037 // add target '+/-'features that can later disable some of features added on
1038 // the first loop. Function Multi Versioning features begin with '?'.
1039 for (const auto &Feature : FeaturesVec)
1040 if (((Feature[0] == '?' || Feature[0] == '+')) &&
1041 AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) {
1042 StringRef DepFeatures =
1043 AArch64TargetInfo::getFeatureDependencies(Feature.substr(1));
1044 SmallVector<StringRef, 1> AttrFeatures;
1045 DepFeatures.split(AttrFeatures, ",");
1046 for (auto F : AttrFeatures)
1047 UpdatedFeaturesVec.push_back(F.str());
1048 }
1049 for (const auto &Feature : FeaturesVec)
1050 if (Feature[0] != '?') {
1051 std::string UpdatedFeature = Feature;
1052 if (Feature[0] == '+') {
1053 std::optional<llvm::AArch64::ExtensionInfo> Extension =
1054 llvm::AArch64::parseArchExtension(Feature.substr(1));
1055 if (Extension)
1056 UpdatedFeature = Extension->Feature.str();
1057 }
1058 UpdatedFeaturesVec.push_back(UpdatedFeature);
1059 }
1060
1061 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
1062 }
1063
1064 // Parse AArch64 Target attributes, which are a comma separated list of:
1065 // "arch=<arch>" - parsed to features as per -march=..
1066 // "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1067 // "tune=<cpu>" - TuneCPU set to <cpu>
1068 // "feature", "no-feature" - Add (or remove) feature.
1069 // "+feature", "+nofeature" - Add (or remove) feature.
parseTargetAttr(StringRef Features) const1070 ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
1071 ParsedTargetAttr Ret;
1072 if (Features == "default")
1073 return Ret;
1074 SmallVector<StringRef, 1> AttrFeatures;
1075 Features.split(AttrFeatures, ",");
1076 bool FoundArch = false;
1077
1078 auto SplitAndAddFeatures = [](StringRef FeatString,
1079 std::vector<std::string> &Features) {
1080 SmallVector<StringRef, 8> SplitFeatures;
1081 FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1082 for (StringRef Feature : SplitFeatures) {
1083 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1084 if (!FeatureName.empty())
1085 Features.push_back(FeatureName.str());
1086 else
1087 // Pushing the original feature string to give a sema error later on
1088 // when they get checked.
1089 if (Feature.starts_with("no"))
1090 Features.push_back("-" + Feature.drop_front(2).str());
1091 else
1092 Features.push_back("+" + Feature.str());
1093 }
1094 };
1095
1096 for (auto &Feature : AttrFeatures) {
1097 Feature = Feature.trim();
1098 if (Feature.starts_with("fpmath="))
1099 continue;
1100
1101 if (Feature.starts_with("branch-protection=")) {
1102 Ret.BranchProtection = Feature.split('=').second.trim();
1103 continue;
1104 }
1105
1106 if (Feature.starts_with("arch=")) {
1107 if (FoundArch)
1108 Ret.Duplicate = "arch=";
1109 FoundArch = true;
1110 std::pair<StringRef, StringRef> Split =
1111 Feature.split("=").second.trim().split("+");
1112 const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1113
1114 // Parse the architecture version, adding the required features to
1115 // Ret.Features.
1116 if (!AI)
1117 continue;
1118 Ret.Features.push_back(AI->ArchFeature.str());
1119 // Add any extra features, after the +
1120 SplitAndAddFeatures(Split.second, Ret.Features);
1121 } else if (Feature.starts_with("cpu=")) {
1122 if (!Ret.CPU.empty())
1123 Ret.Duplicate = "cpu=";
1124 else {
1125 // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1126 // "+feat" features.
1127 std::pair<StringRef, StringRef> Split =
1128 Feature.split("=").second.trim().split("+");
1129 Ret.CPU = Split.first;
1130 SplitAndAddFeatures(Split.second, Ret.Features);
1131 }
1132 } else if (Feature.starts_with("tune=")) {
1133 if (!Ret.Tune.empty())
1134 Ret.Duplicate = "tune=";
1135 else
1136 Ret.Tune = Feature.split("=").second.trim();
1137 } else if (Feature.starts_with("+")) {
1138 SplitAndAddFeatures(Feature, Ret.Features);
1139 } else if (Feature.starts_with("no-")) {
1140 StringRef FeatureName =
1141 llvm::AArch64::getArchExtFeature(Feature.split("-").second);
1142 if (!FeatureName.empty())
1143 Ret.Features.push_back("-" + FeatureName.drop_front(1).str());
1144 else
1145 Ret.Features.push_back("-" + Feature.split("-").second.str());
1146 } else {
1147 // Try parsing the string to the internal target feature name. If it is
1148 // invalid, add the original string (which could already be an internal
1149 // name). These should be checked later by isValidFeatureName.
1150 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1151 if (!FeatureName.empty())
1152 Ret.Features.push_back(FeatureName.str());
1153 else
1154 Ret.Features.push_back("+" + Feature.str());
1155 }
1156 }
1157 return Ret;
1158 }
1159
hasBFloat16Type() const1160 bool AArch64TargetInfo::hasBFloat16Type() const {
1161 return true;
1162 }
1163
1164 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1165 AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
1166 switch (CC) {
1167 case CC_C:
1168 case CC_Swift:
1169 case CC_SwiftAsync:
1170 case CC_PreserveMost:
1171 case CC_PreserveAll:
1172 case CC_OpenCLKernel:
1173 case CC_AArch64VectorCall:
1174 case CC_AArch64SVEPCS:
1175 case CC_Win64:
1176 return CCCR_OK;
1177 default:
1178 return CCCR_Warning;
1179 }
1180 }
1181
isCLZForZeroUndef() const1182 bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1183
getBuiltinVaListKind() const1184 TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
1185 return TargetInfo::AArch64ABIBuiltinVaList;
1186 }
1187
1188 const char *const AArch64TargetInfo::GCCRegNames[] = {
1189 // clang-format off
1190
1191 // 32-bit Integer registers
1192 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1193 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1194 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1195
1196 // 64-bit Integer registers
1197 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1198 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1199 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1200
1201 // 32-bit floating point regsisters
1202 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1203 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1204 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1205
1206 // 64-bit floating point regsisters
1207 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1208 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1209 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1210
1211 // Neon vector registers
1212 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1213 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1214 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1215
1216 // SVE vector registers
1217 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
1218 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1219 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1220
1221 // SVE predicate registers
1222 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
1223 "p11", "p12", "p13", "p14", "p15",
1224
1225 // SVE predicate-as-counter registers
1226 "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",
1227 "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
1228
1229 // SME registers
1230 "za", "zt0",
1231
1232 // clang-format on
1233 };
1234
getGCCRegNames() const1235 ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
1236 return llvm::ArrayRef(GCCRegNames);
1237 }
1238
1239 const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1240 {{"w31"}, "wsp"},
1241 {{"x31"}, "sp"},
1242 // GCC rN registers are aliases of xN registers.
1243 {{"r0"}, "x0"},
1244 {{"r1"}, "x1"},
1245 {{"r2"}, "x2"},
1246 {{"r3"}, "x3"},
1247 {{"r4"}, "x4"},
1248 {{"r5"}, "x5"},
1249 {{"r6"}, "x6"},
1250 {{"r7"}, "x7"},
1251 {{"r8"}, "x8"},
1252 {{"r9"}, "x9"},
1253 {{"r10"}, "x10"},
1254 {{"r11"}, "x11"},
1255 {{"r12"}, "x12"},
1256 {{"r13"}, "x13"},
1257 {{"r14"}, "x14"},
1258 {{"r15"}, "x15"},
1259 {{"r16"}, "x16"},
1260 {{"r17"}, "x17"},
1261 {{"r18"}, "x18"},
1262 {{"r19"}, "x19"},
1263 {{"r20"}, "x20"},
1264 {{"r21"}, "x21"},
1265 {{"r22"}, "x22"},
1266 {{"r23"}, "x23"},
1267 {{"r24"}, "x24"},
1268 {{"r25"}, "x25"},
1269 {{"r26"}, "x26"},
1270 {{"r27"}, "x27"},
1271 {{"r28"}, "x28"},
1272 {{"r29", "x29"}, "fp"},
1273 {{"r30", "x30"}, "lr"},
1274 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1275 // don't want to substitute one of these for a different-sized one.
1276 };
1277
getGCCRegAliases() const1278 ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
1279 return llvm::ArrayRef(GCCRegAliases);
1280 }
1281
1282 // Returns the length of cc constraint.
matchAsmCCConstraint(const char * Name)1283 static unsigned matchAsmCCConstraint(const char *Name) {
1284 constexpr unsigned len = 5;
1285 auto RV = llvm::StringSwitch<unsigned>(Name)
1286 .Case("@cceq", len)
1287 .Case("@ccne", len)
1288 .Case("@cchs", len)
1289 .Case("@cccs", len)
1290 .Case("@cccc", len)
1291 .Case("@cclo", len)
1292 .Case("@ccmi", len)
1293 .Case("@ccpl", len)
1294 .Case("@ccvs", len)
1295 .Case("@ccvc", len)
1296 .Case("@cchi", len)
1297 .Case("@ccls", len)
1298 .Case("@ccge", len)
1299 .Case("@cclt", len)
1300 .Case("@ccgt", len)
1301 .Case("@ccle", len)
1302 .Default(0);
1303 return RV;
1304 }
1305
1306 std::string
convertConstraint(const char * & Constraint) const1307 AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
1308 std::string R;
1309 switch (*Constraint) {
1310 case 'U': // Three-character constraint; add "@3" hint for later parsing.
1311 R = std::string("@3") + std::string(Constraint, 3);
1312 Constraint += 2;
1313 break;
1314 case '@':
1315 if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
1316 std::string Converted = "{" + std::string(Constraint, Len) + "}";
1317 Constraint += Len - 1;
1318 return Converted;
1319 }
1320 return std::string(1, *Constraint);
1321 default:
1322 R = TargetInfo::convertConstraint(Constraint);
1323 break;
1324 }
1325 return R;
1326 }
1327
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1328 bool AArch64TargetInfo::validateAsmConstraint(
1329 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1330 switch (*Name) {
1331 default:
1332 return false;
1333 case 'w': // Floating point and SIMD registers (V0-V31)
1334 Info.setAllowsRegister();
1335 return true;
1336 case 'I': // Constant that can be used with an ADD instruction
1337 case 'J': // Constant that can be used with a SUB instruction
1338 case 'K': // Constant that can be used with a 32-bit logical instruction
1339 case 'L': // Constant that can be used with a 64-bit logical instruction
1340 case 'M': // Constant that can be used as a 32-bit MOV immediate
1341 case 'N': // Constant that can be used as a 64-bit MOV immediate
1342 case 'Y': // Floating point constant zero
1343 case 'Z': // Integer constant zero
1344 return true;
1345 case 'Q': // A memory reference with base register and no offset
1346 Info.setAllowsMemory();
1347 return true;
1348 case 'S': // A symbolic address
1349 Info.setAllowsRegister();
1350 return true;
1351 case 'U':
1352 if (Name[1] == 'p' &&
1353 (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
1354 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
1355 Info.setAllowsRegister();
1356 Name += 2;
1357 return true;
1358 }
1359 if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
1360 // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
1361 Info.setAllowsRegister();
1362 Name += 2;
1363 return true;
1364 }
1365 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1366 // Utf: A memory address suitable for ldp/stp in TF mode.
1367 // Usa: An absolute symbolic address.
1368 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1369
1370 // Better to return an error saying that it's an unrecognised constraint
1371 // even if this is a valid constraint in gcc.
1372 return false;
1373 case 'z': // Zero register, wzr or xzr
1374 Info.setAllowsRegister();
1375 return true;
1376 case 'x': // Floating point and SIMD registers (V0-V15)
1377 Info.setAllowsRegister();
1378 return true;
1379 case 'y': // SVE registers (V0-V7)
1380 Info.setAllowsRegister();
1381 return true;
1382 case '@':
1383 // CC condition
1384 if (const unsigned Len = matchAsmCCConstraint(Name)) {
1385 Name += Len - 1;
1386 Info.setAllowsRegister();
1387 return true;
1388 }
1389 }
1390 return false;
1391 }
1392
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const1393 bool AArch64TargetInfo::validateConstraintModifier(
1394 StringRef Constraint, char Modifier, unsigned Size,
1395 std::string &SuggestedModifier) const {
1396 // Strip off constraint modifiers.
1397 Constraint = Constraint.ltrim("=+&");
1398
1399 switch (Constraint[0]) {
1400 default:
1401 return true;
1402 case 'z':
1403 case 'r': {
1404 switch (Modifier) {
1405 case 'x':
1406 case 'w':
1407 // For now assume that the person knows what they're
1408 // doing with the modifier.
1409 return true;
1410 default:
1411 // By default an 'r' constraint will be in the 'x'
1412 // registers.
1413 if (Size == 64)
1414 return true;
1415
1416 if (Size == 512)
1417 return HasLS64;
1418
1419 SuggestedModifier = "w";
1420 return false;
1421 }
1422 }
1423 }
1424 }
1425
getClobbers() const1426 std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1427
getEHDataRegisterNumber(unsigned RegNo) const1428 int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1429 if (RegNo == 0)
1430 return 0;
1431 if (RegNo == 1)
1432 return 1;
1433 return -1;
1434 }
1435
hasInt128Type() const1436 bool AArch64TargetInfo::hasInt128Type() const { return true; }
1437
AArch64leTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1438 AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple,
1439 const TargetOptions &Opts)
1440 : AArch64TargetInfo(Triple, Opts) {}
1441
setDataLayout()1442 void AArch64leTargetInfo::setDataLayout() {
1443 if (getTriple().isOSBinFormatMachO()) {
1444 if(getTriple().isArch32Bit())
1445 resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_");
1446 else
1447 resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_");
1448 } else
1449 resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1450 }
1451
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1452 void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts,
1453 MacroBuilder &Builder) const {
1454 Builder.defineMacro("__AARCH64EL__");
1455 AArch64TargetInfo::getTargetDefines(Opts, Builder);
1456 }
1457
AArch64beTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1458 AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple,
1459 const TargetOptions &Opts)
1460 : AArch64TargetInfo(Triple, Opts) {}
1461
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1462 void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts,
1463 MacroBuilder &Builder) const {
1464 Builder.defineMacro("__AARCH64EB__");
1465 Builder.defineMacro("__AARCH_BIG_ENDIAN");
1466 Builder.defineMacro("__ARM_BIG_ENDIAN");
1467 AArch64TargetInfo::getTargetDefines(Opts, Builder);
1468 }
1469
setDataLayout()1470 void AArch64beTargetInfo::setDataLayout() {
1471 assert(!getTriple().isOSBinFormatMachO());
1472 resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1473 }
1474
WindowsARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1475 WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple,
1476 const TargetOptions &Opts)
1477 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1478
1479 // This is an LLP64 platform.
1480 // int:4, long:4, long long:8, long double:8.
1481 IntWidth = IntAlign = 32;
1482 LongWidth = LongAlign = 32;
1483 DoubleAlign = LongLongAlign = 64;
1484 LongDoubleWidth = LongDoubleAlign = 64;
1485 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1486 IntMaxType = SignedLongLong;
1487 Int64Type = SignedLongLong;
1488 SizeType = UnsignedLongLong;
1489 PtrDiffType = SignedLongLong;
1490 IntPtrType = SignedLongLong;
1491 }
1492
setDataLayout()1493 void WindowsARM64TargetInfo::setDataLayout() {
1494 resetDataLayout(Triple.isOSBinFormatMachO()
1495 ? "e-m:o-i64:64-i128:128-n32:64-S128"
1496 : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128",
1497 Triple.isOSBinFormatMachO() ? "_" : "");
1498 }
1499
1500 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1501 WindowsARM64TargetInfo::getBuiltinVaListKind() const {
1502 return TargetInfo::CharPtrBuiltinVaList;
1503 }
1504
1505 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1506 WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
1507 switch (CC) {
1508 case CC_X86StdCall:
1509 case CC_X86ThisCall:
1510 case CC_X86FastCall:
1511 case CC_X86VectorCall:
1512 return CCCR_Ignore;
1513 case CC_C:
1514 case CC_OpenCLKernel:
1515 case CC_PreserveMost:
1516 case CC_PreserveAll:
1517 case CC_Swift:
1518 case CC_SwiftAsync:
1519 case CC_Win64:
1520 return CCCR_OK;
1521 default:
1522 return CCCR_Warning;
1523 }
1524 }
1525
MicrosoftARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1526 MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
1527 const TargetOptions &Opts)
1528 : WindowsARM64TargetInfo(Triple, Opts) {
1529 TheCXXABI.set(TargetCXXABI::Microsoft);
1530 }
1531
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1532 void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
1533 MacroBuilder &Builder) const {
1534 WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
1535 if (getTriple().isWindowsArm64EC()) {
1536 Builder.defineMacro("_M_X64", "100");
1537 Builder.defineMacro("_M_AMD64", "100");
1538 Builder.defineMacro("_M_ARM64EC", "1");
1539 } else {
1540 Builder.defineMacro("_M_ARM64", "1");
1541 }
1542 }
1543
1544 TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const1545 MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
1546 return CCK_MicrosoftWin64;
1547 }
1548
getMinGlobalAlign(uint64_t TypeSize) const1549 unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
1550 unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
1551
1552 // MSVC does size based alignment for arm64 based on alignment section in
1553 // below document, replicate that to keep alignment consistent with object
1554 // files compiled by MSVC.
1555 // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
1556 if (TypeSize >= 512) { // TypeSize >= 64 bytes
1557 Align = std::max(Align, 128u); // align type at least 16 bytes
1558 } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
1559 Align = std::max(Align, 64u); // align type at least 8 butes
1560 } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
1561 Align = std::max(Align, 32u); // align type at least 4 bytes
1562 }
1563 return Align;
1564 }
1565
MinGWARM64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1566 MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
1567 const TargetOptions &Opts)
1568 : WindowsARM64TargetInfo(Triple, Opts) {
1569 TheCXXABI.set(TargetCXXABI::GenericAArch64);
1570 }
1571
DarwinAArch64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1572 DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple,
1573 const TargetOptions &Opts)
1574 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1575 Int64Type = SignedLongLong;
1576 if (getTriple().isArch32Bit())
1577 IntMaxType = SignedLongLong;
1578
1579 WCharType = SignedInt;
1580 UseSignedCharForObjCBool = false;
1581
1582 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1583 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1584
1585 UseZeroLengthBitfieldAlignment = false;
1586
1587 if (getTriple().isArch32Bit()) {
1588 UseBitFieldTypeAlignment = false;
1589 ZeroLengthBitfieldBoundary = 32;
1590 UseZeroLengthBitfieldAlignment = true;
1591 TheCXXABI.set(TargetCXXABI::WatchOS);
1592 } else
1593 TheCXXABI.set(TargetCXXABI::AppleARM64);
1594 }
1595
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1596 void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
1597 const llvm::Triple &Triple,
1598 MacroBuilder &Builder) const {
1599 Builder.defineMacro("__AARCH64_SIMD__");
1600 if (Triple.isArch32Bit())
1601 Builder.defineMacro("__ARM64_ARCH_8_32__");
1602 else
1603 Builder.defineMacro("__ARM64_ARCH_8__");
1604 Builder.defineMacro("__ARM_NEON__");
1605 Builder.defineMacro("__REGISTER_PREFIX__", "");
1606 Builder.defineMacro("__arm64", "1");
1607 Builder.defineMacro("__arm64__", "1");
1608
1609 if (Triple.isArm64e())
1610 Builder.defineMacro("__arm64e__", "1");
1611
1612 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1613 }
1614
1615 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1616 DarwinAArch64TargetInfo::getBuiltinVaListKind() const {
1617 return TargetInfo::CharPtrBuiltinVaList;
1618 }
1619
1620 // 64-bit RenderScript is aarch64
RenderScript64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1621 RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple,
1622 const TargetOptions &Opts)
1623 : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(),
1624 Triple.getOSName(),
1625 Triple.getEnvironmentName()),
1626 Opts) {
1627 IsRenderScriptTarget = true;
1628 }
1629
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1630 void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts,
1631 MacroBuilder &Builder) const {
1632 Builder.defineMacro("__RENDERSCRIPT__");
1633 AArch64leTargetInfo::getTargetDefines(Opts, Builder);
1634 }
1635