clang 23.0.0git
AArch64.cpp
Go to the documentation of this file.
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"
18#include "llvm/ADT/APSInt.h"
19#include "llvm/ADT/ArrayRef.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/TargetParser/AArch64TargetParser.h"
22#include "llvm/TargetParser/ARMTargetParserCommon.h"
23#include <optional>
24
25using namespace clang;
26using namespace clang::targets;
27
28static constexpr int NumNeonBuiltins =
30static constexpr int NumFp16Builtins =
32static constexpr int NumSVEBuiltins =
34static constexpr int NumSVENeonBridgeBuiltins =
37static constexpr int NumAArch64Builtins =
39static constexpr int NumBuiltins =
41static_assert(NumBuiltins ==
44
45namespace clang {
46namespace AArch64 {
47#define GET_BUILTIN_STR_TABLE
48#include "clang/Basic/BuiltinsAArch64.inc"
49#undef GET_BUILTIN_STR_TABLE
50
51static constexpr Builtin::Info BuiltinInfos[] = {
52#define GET_BUILTIN_INFOS
53#include "clang/Basic/BuiltinsAArch64.inc"
54#undef GET_BUILTIN_INFOS
55};
56
57static constexpr Builtin::Info PrefixedBuiltinInfos[] = {
58#define GET_BUILTIN_PREFIXED_INFOS
59#include "clang/Basic/BuiltinsAArch64.inc"
60#undef GET_BUILTIN_PREFIXED_INFOS
61};
62static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) ==
64} // namespace AArch64
65
66namespace NEON {
67#define GET_NEON_BUILTIN_STR_TABLE
68#include "clang/Basic/arm_neon.inc"
69#undef GET_NEON_BUILTIN_STR_TABLE
70
71static constexpr std::array<Builtin::Info, NumNeonBuiltins> BuiltinInfos = {
72#define GET_NEON_BUILTIN_INFOS
73#include "clang/Basic/arm_neon.inc"
74#undef GET_NEON_BUILTIN_INFOS
75};
76
77namespace FP16 {
78#define GET_NEON_BUILTIN_STR_TABLE
79#include "clang/Basic/arm_fp16.inc"
80#undef GET_NEON_BUILTIN_STR_TABLE
81
82static constexpr std::array<Builtin::Info, NumFp16Builtins> BuiltinInfos = {
83#define GET_NEON_BUILTIN_INFOS
84#include "clang/Basic/arm_fp16.inc"
85#undef GET_NEON_BUILTIN_INFOS
86};
87} // namespace FP16
88} // namespace NEON
89
90namespace SVE {
91#define GET_SVE_BUILTIN_STR_TABLE
92#include "clang/Basic/arm_sve_builtins.inc"
93#undef GET_SVE_BUILTIN_STR_TABLE
94
95static constexpr std::array<Builtin::Info, NumSVEBuiltins> BuiltinInfos = {
96#define GET_SVE_BUILTIN_INFOS
97#include "clang/Basic/arm_sve_builtins.inc"
98#undef GET_SVE_BUILTIN_INFOS
99};
100} // namespace SVE
101
102namespace SME {
103#define GET_SME_BUILTIN_STR_TABLE
104#include "clang/Basic/arm_sme_builtins.inc"
105#undef GET_SME_BUILTIN_STR_TABLE
106
107static constexpr std::array<Builtin::Info, NumSMEBuiltins> BuiltinInfos = {
108#define GET_SME_BUILTIN_INFOS
109#include "clang/Basic/arm_sme_builtins.inc"
110#undef GET_SME_BUILTIN_INFOS
111};
112} // namespace SME
113} // namespace clang
114
115static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings =
117#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
118#define GET_SVE_BUILTINS
119#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
120#undef GET_SVE_BUILTINS
121#undef TARGET_BUILTIN
122 ;
123
124static constexpr auto BuiltinSVENeonBridgeInfos =
126#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
127#define GET_SVE_BUILTINS
128#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
129#undef GET_SVE_BUILTINS
130#undef TARGET_BUILTIN
131 });
132
133AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
134 const TargetOptions &Opts)
135 : TargetInfo(Triple), ABI("aapcs") {
136 if (getTriple().isOSOpenBSD()) {
139 } else {
140 if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD())
142
145 }
146
148
149 // All AArch64 implementations support ARMv8 FP, which makes half a legal type.
150 HasFastHalfType = true;
151 HalfArgsAndReturns = true;
152 HasFloat16 = true;
153 HasStrictFP = true;
154
155 if (Triple.isArch64Bit())
157 else
159
160 BitIntMaxAlign = 128;
161 MaxVectorAlign = 128;
164
166 LongDoubleFormat = &llvm::APFloat::IEEEquad();
167
169 BFloat16Format = &llvm::APFloat::BFloat();
170
171 // Make __builtin_ms_va_list available.
172 HasBuiltinMSVaList = true;
173
174 // Make the Neon ACLE and SVE types available. Note that this deliberately
175 // doesn't depend on SveMode, since in principle it should be possible to turn
176 // SVE on and off within a translation unit. It should also be possible
177 // to compile the global declaration:
178 //
179 // __SVInt8_t *ptr;
180 //
181 // even without SVE.
182 HasAArch64ACLETypes = true;
183
184 // {} in inline assembly are neon specifiers, not assembly variant
185 // specifiers.
186 NoAsmVariants = true;
187
188 // AAPCS gives rules for bitfields. 7.1.7 says: "The container type
189 // contributes to the alignment of the containing aggregate in the same way
190 // a plain (non bit-field) member of that type would, without exception for
191 // zero-sized or anonymous bit-fields."
192 assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
194
195 // AAPCS64 allows any "fundamental integer data type" to be used for
196 // over-sized bitfields, which includes 128-bit integers.
198
199 HasUnalignedAccess = true;
200
201 // AArch64 targets default to using the ARM C++ ABI.
202 TheCXXABI.set(TargetCXXABI::GenericAArch64);
203
204 if (Triple.getOS() == llvm::Triple::Linux)
205 this->MCountName = "\01_mcount";
206 else if (Triple.getOS() == llvm::Triple::UnknownOS)
207 this->MCountName =
208 Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount" : "mcount";
209}
210
211StringRef AArch64TargetInfo::getABI() const { return ABI; }
212
213bool AArch64TargetInfo::setABI(const std::string &Name) {
214 if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")
215 return false;
216
217 ABI = Name;
218 return true;
219}
220
222 if (hasFeature("fp") && ABI == "aapcs-soft") {
223 // aapcs-soft is not allowed for targets with an FPU, to avoid there being
224 // two incomatible ABIs.
225 Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
226 return false;
227 }
228 return true;
229}
230
232 StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const {
233 if (RegName == "sp") {
234 HasSizeMismatch = RegSize != 64;
235 return true;
236 }
237 if (RegName.starts_with("w"))
238 HasSizeMismatch = RegSize != 32;
239 else if (RegName.starts_with("x"))
240 HasSizeMismatch = RegSize != 64;
241 else
242 return false;
243 StringRef RegNum = RegName.drop_front();
244 // Check if the register is reserved. See also
245 // AArch64TargetLowering::getRegisterByName().
246 return RegNum == "0" ||
247 (RegNum == "18" &&
248 llvm::AArch64::isX18ReservedByDefault(getTriple())) ||
249 getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str());
250}
251
252bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
254 const LangOptions &LO,
255 StringRef &Err) const {
256 llvm::ARM::ParsedBranchProtection PBP;
257 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR))
258 return false;
259
260 // GCS is currently untested with ptrauth-returns, but enabling this could be
261 // allowed in future after testing with a suitable system.
262 if (LO.PointerAuthReturns &&
263 (PBP.Scope != "none" || PBP.BranchProtectionPAuthLR ||
264 PBP.GuardedControlStack))
265 return false;
266
267 BPI.SignReturnAddr =
268 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
272
273 if (PBP.Key == "a_key")
275 else
277
278 BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
279 BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
280 BPI.GuardedControlStack = PBP.GuardedControlStack;
281 return true;
282}
283
284bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
285 return llvm::AArch64::parseCpu(Name).has_value();
286}
287
288bool AArch64TargetInfo::setCPU(StringRef Name) { return isValidCPUName(Name); }
289
291 SmallVectorImpl<StringRef> &Values) const {
292 llvm::AArch64::fillValidCPUArchList(Values);
293}
294
296 MacroBuilder &Builder) const {
297 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
298}
299
301 MacroBuilder &Builder) const {
302 // Also include the ARMv8.1 defines
303 getTargetDefinesARMV81A(Opts, Builder);
304}
305
307 MacroBuilder &Builder) const {
308 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
309 Builder.defineMacro("__ARM_FEATURE_JCVT", "1");
310 // Also include the Armv8.2 defines
311 getTargetDefinesARMV82A(Opts, Builder);
312}
313
315 MacroBuilder &Builder) const {
316 // Also include the Armv8.3 defines
317 getTargetDefinesARMV83A(Opts, Builder);
318}
319
321 MacroBuilder &Builder) const {
322 Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
323 // Also include the Armv8.4 defines
324 getTargetDefinesARMV84A(Opts, Builder);
325}
326
328 MacroBuilder &Builder) const {
329 // Also include the Armv8.5 defines
330 // FIXME: Armv8.6 makes the following extensions mandatory:
331 // - __ARM_FEATURE_BF16
332 // - __ARM_FEATURE_MATMUL_INT8
333 // Handle them here.
334 getTargetDefinesARMV85A(Opts, Builder);
335}
336
338 MacroBuilder &Builder) const {
339 // Also include the Armv8.6 defines
340 getTargetDefinesARMV86A(Opts, Builder);
341}
342
344 MacroBuilder &Builder) const {
345 // Also include the Armv8.7 defines
346 getTargetDefinesARMV87A(Opts, Builder);
347}
348
350 MacroBuilder &Builder) const {
351 // Also include the Armv8.8 defines
352 getTargetDefinesARMV88A(Opts, Builder);
353}
354
356 MacroBuilder &Builder) const {
357 // Armv9-A maps to Armv8.5-A
358 getTargetDefinesARMV85A(Opts, Builder);
359}
360
362 MacroBuilder &Builder) const {
363 // Armv9.1-A maps to Armv8.6-A
364 getTargetDefinesARMV86A(Opts, Builder);
365}
366
368 MacroBuilder &Builder) const {
369 // Armv9.2-A maps to Armv8.7-A
370 getTargetDefinesARMV87A(Opts, Builder);
371}
372
374 MacroBuilder &Builder) const {
375 // Armv9.3-A maps to Armv8.8-A
376 getTargetDefinesARMV88A(Opts, Builder);
377}
378
380 MacroBuilder &Builder) const {
381 // Armv9.4-A maps to Armv8.9-A
382 getTargetDefinesARMV89A(Opts, Builder);
383}
384
386 MacroBuilder &Builder) const {
387 // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
388 getTargetDefinesARMV94A(Opts, Builder);
389}
390
392 MacroBuilder &Builder) const {
393 // Armv9.6-A does not have a v8.* equivalent, but is a superset of v9.5-A.
394 getTargetDefinesARMV95A(Opts, Builder);
395}
396
398 MacroBuilder &Builder) const {
399 // Armv9.7-A does not have a v8.* equivalent, but is a superset of v9.6-A.
400 getTargetDefinesARMV96A(Opts, Builder);
401}
402
404 MacroBuilder &Builder) const {
405 // Target identification.
406 if (getTriple().isWindowsArm64EC()) {
407 // Define the same set of macros as would be defined on x86_64 to ensure that
408 // ARM64EC datatype layouts match those of x86_64 compiled code
409 Builder.defineMacro("__amd64__");
410 Builder.defineMacro("__amd64");
411 Builder.defineMacro("__x86_64");
412 Builder.defineMacro("__x86_64__");
413 Builder.defineMacro("__arm64ec__");
414 } else {
415 Builder.defineMacro("__aarch64__");
416 }
417
418 if (getTriple().isLFI())
419 Builder.defineMacro("__LFI__");
420
421 // Inline assembly supports AArch64 flag outputs.
422 Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
423
424 std::string CodeModel = getTargetOpts().CodeModel;
425 if (CodeModel == "default")
426 CodeModel = "small";
427 for (char &c : CodeModel)
428 c = toupper(c);
429 Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__");
430
431 // ACLE predefines. Many can only have one possible value on v8 AArch64.
432 Builder.defineMacro("__ARM_ACLE_VERSION(year, quarter, patch)",
433 "(100 * (year) + 10 * (quarter) + (patch))");
434#define ARM_ACLE_VERSION(Y, Q, P) (100 * (Y) + 10 * (Q) + (P))
435 Builder.defineMacro("__ARM_ACLE", Twine(ARM_ACLE_VERSION(2024, 2, 0)));
436 Builder.defineMacro("__FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL",
437 Twine(ARM_ACLE_VERSION(2024, 3, 0)));
438#undef ARM_ACLE_VERSION
439 Builder.defineMacro("__ARM_ARCH",
440 std::to_string(ArchInfo->Version.getMajor()));
441 Builder.defineMacro("__ARM_ARCH_PROFILE",
442 std::string("'") + (char)ArchInfo->Profile + "'");
443
444 Builder.defineMacro("__ARM_64BIT_STATE", "1");
445 Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
446 Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
447
448 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
449 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
450 Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
451 Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
452 Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
453 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
454 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
455
456 Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
457
458 // These macros are set when Clang can parse declarations with these
459 // attributes.
460 Builder.defineMacro("__ARM_STATE_ZA", "1");
461 Builder.defineMacro("__ARM_STATE_ZT0", "1");
462
463 // 0xe implies support for half, single and double precision operations.
464 if (FPU & FPUMode)
465 Builder.defineMacro("__ARM_FP", "0xE");
466
467 // PCS specifies this for SysV variants, which is all we support. Other ABIs
468 // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
469 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
470 Builder.defineMacro("__ARM_FP16_ARGS", "1");
471
472 // Clang supports arm_neon_sve_bridge.h
473 Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
474
475 if (Opts.UnsafeFPMath)
476 Builder.defineMacro("__ARM_FP_FAST", "1");
477
478 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
479 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
480
481 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
482
483 // Clang supports range prefetch intrinsics
484 Builder.defineMacro("__ARM_PREFETCH_RANGE", "1");
485
486 if (FPU & NeonMode) {
487 Builder.defineMacro("__ARM_NEON", "1");
488 // 64-bit NEON supports half, single and double precision operations.
489 Builder.defineMacro("__ARM_NEON_FP", "0xE");
490 }
491
492 if (FPU & SveMode)
493 Builder.defineMacro("__ARM_FEATURE_SVE", "1");
494
495 if (HasSVE2)
496 Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
497
498 if (HasSVE2p1)
499 Builder.defineMacro("__ARM_FEATURE_SVE2p1", "1");
500
501 if (HasSVE2 && HasSVEAES)
502 Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1");
503
504 if (HasSVE2 && HasSVEBitPerm)
505 Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1");
506
507 if (HasSVE2 && HasSVE2SHA3)
508 Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1");
509
510 if (HasSVE2 && HasSVE2SM4)
511 Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
512
513 if (HasSVEB16B16)
514 Builder.defineMacro("__ARM_FEATURE_SVE_B16B16", "1");
515
516 if (HasSME) {
517 Builder.defineMacro("__ARM_FEATURE_SME");
518 Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
519 }
520
521 if (HasSME2)
522 Builder.defineMacro("__ARM_FEATURE_SME2", "1");
523
524 if (HasSME2p1)
525 Builder.defineMacro("__ARM_FEATURE_SME2p1", "1");
526
527 if (HasSMEF16F16)
528 Builder.defineMacro("__ARM_FEATURE_SME_F16F16", "1");
529
530 if (HasSMEB16B16)
531 Builder.defineMacro("__ARM_FEATURE_SME_B16B16", "1");
532
533 if (HasFP8)
534 Builder.defineMacro("__ARM_FEATURE_FP8", "1");
535
536 if (HasFP8FMA)
537 Builder.defineMacro("__ARM_FEATURE_FP8FMA", "1");
538
539 if (HasFP8DOT2)
540 Builder.defineMacro("__ARM_FEATURE_FP8DOT2", "1");
541
542 if (HasFP8DOT4)
543 Builder.defineMacro("__ARM_FEATURE_FP8DOT4", "1");
544
545 if (HasSSVE_FP8DOT2)
546 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT2", "1");
547
548 if (HasSSVE_FP8DOT4)
549 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8DOT4", "1");
550
551 if (HasSSVE_FP8FMA)
552 Builder.defineMacro("__ARM_FEATURE_SSVE_FP8FMA", "1");
553
554 if (HasSME_F8F32)
555 Builder.defineMacro("__ARM_FEATURE_SME_F8F32", "1");
556
557 if (HasSME_F8F16)
558 Builder.defineMacro("__ARM_FEATURE_SME_F8F16", "1");
559
560 if (HasCRC)
561 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
562
563 if (HasCSSC)
564 Builder.defineMacro("__ARM_FEATURE_CSSC", "1");
565
566 if (HasRCPC3)
567 Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
568 else if (HasRCPC)
569 Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
570
571 if (HasFPRCVT)
572 Builder.defineMacro("__ARM_FEATURE_FPRCVT", "1");
573
574 if (HasF8F16MM)
575 Builder.defineMacro("__ARM_FEATURE_F8F16MM", "1");
576
577 if (HasF8F32MM)
578 Builder.defineMacro("__ARM_FEATURE_F8F32MM", "1");
579
580 if (HasSVE_F16F32MM)
581 Builder.defineMacro("__ARM_FEATURE_SVE_F16F32MM", "1");
582
583 if (HasSVE_BFSCALE)
584 Builder.defineMacro("__ARM_FEATURE_SVE_BFSCALE", "1");
585
586 if (HasSVE_B16MM)
587 Builder.defineMacro("__ARM_FEATURE_SVE_B16MM", "1");
588
589 if (HasF16MM)
590 Builder.defineMacro("__ARM_FEATURE_F16MM", "1");
591
592 if (HasF16F32DOT)
593 Builder.defineMacro("__ARM_FEATURE_F16F32DOT", "1");
594
595 if (HasF16F32MM)
596 Builder.defineMacro("__ARM_FEATURE_F16F32MM", "1");
597
598 if (HasSVE_AES2)
599 Builder.defineMacro("__ARM_FEATURE_SVE_AES2", "1");
600
601 if (HasSSVE_AES)
602 Builder.defineMacro("__ARM_FEATURE_SSVE_AES", "1");
603
604 if (HasSVE2p2)
605 Builder.defineMacro("__ARM_FEATURE_SVE2p2", "1");
606
607 if (HasSVE2p3)
608 Builder.defineMacro("__ARM_FEATURE_SVE2p3", "1");
609
610 if (HasSME2p2)
611 Builder.defineMacro("__ARM_FEATURE_SME2p2", "1");
612
613 if (HasSME2p3)
614 Builder.defineMacro("__ARM_FEATURE_SME2p3", "1");
615
616 if (HasFMV)
617 Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
618
619 // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
620 // macros for AES, SHA2, SHA3 and SM4
621 if (HasAES && HasSHA2)
622 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
623
624 if (HasAES)
625 Builder.defineMacro("__ARM_FEATURE_AES", "1");
626
627 if (HasSHA2)
628 Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
629
630 if (HasSHA3) {
631 Builder.defineMacro("__ARM_FEATURE_SHA3", "1");
632 Builder.defineMacro("__ARM_FEATURE_SHA512", "1");
633 }
634
635 if (HasSM4) {
636 Builder.defineMacro("__ARM_FEATURE_SM3", "1");
637 Builder.defineMacro("__ARM_FEATURE_SM4", "1");
638 }
639
640 if (HasPAuth)
641 Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
642
643 if (HasPAuthLR)
644 Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");
645
646 if (HasBTI)
647 Builder.defineMacro("__ARM_FEATURE_BTI", "1");
648
650 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
651
652 if ((FPU & NeonMode) && HasFullFP16)
653 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
654 if (HasFullFP16)
655 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
656
657 if (HasDotProd)
658 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
659
660 if (HasMTE)
661 Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
662
663 if (HasMatMul)
664 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
665
666 if (HasLSE)
667 Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
668
669 if (HasBFloat16) {
670 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
671 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
672 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
673 Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
674 }
675
676 if ((FPU & SveMode) && HasBFloat16) {
677 Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
678 }
679
680 if ((FPU & SveMode) && HasMatmulFP64)
681 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1");
682
683 if ((FPU & SveMode) && HasMatmulFP32)
684 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1");
685
686 if ((FPU & SveMode) && HasMatMul)
687 Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1");
688
689 if ((FPU & NeonMode) && HasFP16FML)
690 Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1");
691
692 if (Opts.hasSignReturnAddress()) {
693 // Bitmask:
694 // 0: Protection using the A key
695 // 1: Protection using the B key
696 // 2: Protection including leaf functions
697 // 3: Protection using PC as a diversifier
698 unsigned Value = 0;
699
701 Value |= (1 << 0);
702 else
703 Value |= (1 << 1);
704
706 Value |= (1 << 2);
707
708 if (Opts.BranchProtectionPAuthLR)
709 Value |= (1 << 3);
710
711 Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value));
712 }
713
714 if (Opts.BranchTargetEnforcement)
715 Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
716
717 if (Opts.GuardedControlStack)
718 Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
719
720 if (HasLS64)
721 Builder.defineMacro("__ARM_FEATURE_LS64", "1");
722
723 if (HasRandGen)
724 Builder.defineMacro("__ARM_FEATURE_RNG", "1");
725
726 if (HasMOPS)
727 Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
728
729 if (HasD128)
730 Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
731
732 if (HasGCS)
733 Builder.defineMacro("__ARM_FEATURE_GCS", "1");
734
735 if (*ArchInfo == llvm::AArch64::ARMV8_1A)
736 getTargetDefinesARMV81A(Opts, Builder);
737 else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
738 getTargetDefinesARMV82A(Opts, Builder);
739 else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
740 getTargetDefinesARMV83A(Opts, Builder);
741 else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
742 getTargetDefinesARMV84A(Opts, Builder);
743 else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
744 getTargetDefinesARMV85A(Opts, Builder);
745 else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
746 getTargetDefinesARMV86A(Opts, Builder);
747 else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
748 getTargetDefinesARMV87A(Opts, Builder);
749 else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
750 getTargetDefinesARMV88A(Opts, Builder);
751 else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
752 getTargetDefinesARMV89A(Opts, Builder);
753 else if (*ArchInfo == llvm::AArch64::ARMV9A)
754 getTargetDefinesARMV9A(Opts, Builder);
755 else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
756 getTargetDefinesARMV91A(Opts, Builder);
757 else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
758 getTargetDefinesARMV92A(Opts, Builder);
759 else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
760 getTargetDefinesARMV93A(Opts, Builder);
761 else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
762 getTargetDefinesARMV94A(Opts, Builder);
763 else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
764 getTargetDefinesARMV95A(Opts, Builder);
765 else if (*ArchInfo == llvm::AArch64::ARMV9_6A)
766 getTargetDefinesARMV96A(Opts, Builder);
767 else if (*ArchInfo == llvm::AArch64::ARMV9_7A)
768 getTargetDefinesARMV97A(Opts, Builder);
769
770 // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
771 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
772 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
773 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
774 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
775 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
776
777 // Allow detection of fast FMA support.
778 Builder.defineMacro("__FP_FAST_FMA", "1");
779 Builder.defineMacro("__FP_FAST_FMAF", "1");
780
781 // C/C++ operators work on both VLS and VLA SVE types
782 if (FPU & SveMode)
783 Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
784
785 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
786 Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
787 }
788}
789
792 return {
793 {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"},
794 {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos,
795 "__builtin_neon_"},
796 {&SVE::BuiltinStrings, SVE::BuiltinInfos, "__builtin_sve_"},
798 {&SME::BuiltinStrings, SME::BuiltinInfos, "__builtin_sme_"},
799 {&AArch64::BuiltinStrings, AArch64::BuiltinInfos},
800 {&AArch64::BuiltinStrings, AArch64::PrefixedBuiltinInfos,
801 "__builtin_arm_"},
802 };
803}
804
805std::optional<std::pair<unsigned, unsigned>>
807 ArmStreamingKind Mode,
808 llvm::StringMap<bool> *FeatureMap) const {
809 if (Mode == ArmStreamingKind::NotStreaming &&
810 (LangOpts.VScaleMin || LangOpts.VScaleMax))
811 return std::pair<unsigned, unsigned>(
812 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
813 LangOpts.VScaleMax ? LangOpts.VScaleMax : 16);
814
815 if (Mode == ArmStreamingKind::Streaming &&
816 (LangOpts.VScaleStreamingMin || LangOpts.VScaleStreamingMax))
817 return std::pair<unsigned, unsigned>(
818 LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1,
819 LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
820
822 ((LangOpts.VScaleMin && LangOpts.VScaleStreamingMin) ||
823 (LangOpts.VScaleMax && LangOpts.VScaleStreamingMax))) {
824 unsigned Min =
825 std::min(LangOpts.VScaleMin ? LangOpts.VScaleMin : 1,
826 LangOpts.VScaleStreamingMin ? LangOpts.VScaleStreamingMin : 1);
827 unsigned Max = std::max(
828 LangOpts.VScaleMax ? LangOpts.VScaleMax : 16,
829 LangOpts.VScaleStreamingMax ? LangOpts.VScaleStreamingMax : 16);
830 return std::pair(Min, Max);
831 }
832
833 if (hasFeature("sve") || (FeatureMap && (FeatureMap->lookup("sve"))))
834 return std::pair<unsigned, unsigned>(1, 16);
835
836 if (Mode == ArmStreamingKind::Streaming &&
837 (hasFeature("sme") || (FeatureMap && (FeatureMap->lookup("sme")))))
838 return std::pair<unsigned, unsigned>(1, 16);
839
840 return std::nullopt;
841}
842
843llvm::APInt
845 return llvm::AArch64::getFMVPriority(Features);
846}
847
849 // FMV extensions which imply no backend features do not affect codegen.
850 if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
851 return Ext->ID.has_value();
852 return false;
853}
854
855bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
856 // CPU features might be separated by '+', extract them and check
858 FeatureStr.split(Features, "+");
859 for (auto &Feature : Features)
860 if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())
861 return false;
862 return true;
863}
864
865/// A helper class for "hasFeature" lookups (mimicking a StringSwitch).
867 FeatureLookupBuilder(AArch64FeatureSet &Features) : Features(Features) {
868 Features.clear();
869 }
870
871 FeatureLookupBuilder &Case(StringRef Feat, bool HasFeature) {
872 if (HasFeature)
873 Features.insert(Feat);
874 return *this;
875 }
876
878 if (HasFeature)
879 Features.insert_range(Feats);
880 return *this;
881 }
882
883private:
884 AArch64FeatureSet &Features;
885};
886
887void AArch64TargetInfo::computeFeatureLookup() {
888 FeatureLookupBuilder(HasFeatureLookup)
889 .Cases({"aarch64", "arm64", "arm"}, true)
890 .Case("fmv", HasFMV)
891 .Case("fp", FPU & FPUMode)
892 .Cases({"neon", "simd"}, FPU & NeonMode)
893 .Case("jscvt", HasJSCVT)
894 .Case("fcma", HasFCMA)
895 .Case("rng", HasRandGen)
896 .Case("flagm", HasFlagM)
897 .Case("flagm2", HasAlternativeNZCV)
898 .Case("fp16fml", HasFP16FML)
899 .Case("dotprod", HasDotProd)
900 .Case("sm4", HasSM4)
901 .Case("rdm", HasRDM)
902 .Case("lse", HasLSE)
903 .Case("crc", HasCRC)
904 .Case("cssc", HasCSSC)
905 .Case("sha2", HasSHA2)
906 .Case("sha3", HasSHA3)
907 .Cases({"aes", "pmull"}, HasAES)
908 .Cases({"fp16", "fullfp16"}, HasFullFP16)
909 .Case("dit", HasDIT)
910 .Case("dpb", HasCCPP)
911 .Case("dpb2", HasCCDP)
912 .Case("rcpc", HasRCPC)
913 .Case("frintts", HasFRInt3264)
914 .Case("i8mm", HasMatMul)
915 .Case("bf16", HasBFloat16)
916 .Case("sve", FPU & SveMode)
917 .Case("sve-b16b16", HasSVEB16B16)
918 .Case("f32mm", FPU & SveMode && HasMatmulFP32)
919 .Case("f64mm", FPU & SveMode && HasMatmulFP64)
920 .Case("sve2", FPU & SveMode && HasSVE2)
921 .Case("sve-aes", HasSVEAES)
922 .Case("sve-bitperm", FPU & HasSVEBitPerm)
923 .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
924 .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
925 .Case("sve2p1", FPU & SveMode && HasSVE2p1)
926 .Case("sme", HasSME)
927 .Case("sme2", HasSME2)
928 .Case("sme2p1", HasSME2p1)
929 .Case("sme-f64f64", HasSMEF64F64)
930 .Case("sme-i16i64", HasSMEI16I64)
931 .Case("sme-fa64", HasSMEFA64)
932 .Case("sme-f16f16", HasSMEF16F16)
933 .Case("sme-b16b16", HasSMEB16B16)
934 .Case("memtag", HasMTE)
935 .Case("sb", HasSB)
936 .Case("predres", HasPredRes)
937 .Cases({"ssbs", "ssbs2"}, HasSSBS)
938 .Case("bti", HasBTI)
939 .Cases({"ls64", "ls64_v", "ls64_accdata"}, HasLS64)
940 .Case("wfxt", HasWFxT)
941 .Case("rcpc3", HasRCPC3)
942 .Case("fp8", HasFP8)
943 .Case("fp8fma", HasFP8FMA)
944 .Case("fp8dot2", HasFP8DOT2)
945 .Case("fp8dot4", HasFP8DOT4)
946 .Case("ssve-fp8dot2", HasSSVE_FP8DOT2)
947 .Case("ssve-fp8dot4", HasSSVE_FP8DOT4)
948 .Case("ssve-fp8fma", HasSSVE_FP8FMA)
949 .Case("sme-f8f32", HasSME_F8F32)
950 .Case("sme-f8f16", HasSME_F8F16)
951 .Case("fprcvt", HasFPRCVT)
952 .Case("f8f16mm", HasF8F16MM)
953 .Case("f8f32mm", HasF8F32MM)
954 .Case("sve-f16f32mm", HasSVE_F16F32MM)
955 .Case("sve-bfscale", HasSVE_BFSCALE)
956 .Case("sve-aes2", HasSVE_AES2)
957 .Case("ssve-aes", HasSSVE_AES)
958 .Case("sve2p2", FPU & SveMode && HasSVE2p2)
959 .Case("sme2p2", HasSME2p2)
960 .Case("sve2p3", FPU & SveMode && HasSVE2p3)
961 .Case("sme2p3", HasSME2p3)
962 .Case("sve-b16mm", HasSVE_B16MM)
963 .Case("f16mm", HasF16MM)
964 .Case("f16f32dot", HasF16F32DOT)
965 .Case("f16f32mm", HasF16F32MM);
966}
967
969 return HasFeatureLookup.contains(Feature);
970}
971
972void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
973 StringRef Name, bool Enabled) const {
974 Features[Name] = Enabled;
975 // If the feature is an architecture feature (like v8.2a), add all previous
976 // architecture versions and any dependant target features.
977 const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
978 llvm::AArch64::ArchInfo::findBySubArch(Name);
979
980 if (!ArchInfo)
981 return; // Not an architecture, nothing more to do.
982
983 // Disabling an architecture feature does not affect dependent features
984 if (!Enabled)
985 return;
986
987 for (const auto &OtherArch : llvm::AArch64::ArchInfos)
988 if (ArchInfo->implies(OtherArch))
989 Features[OtherArch.getSubArch()] = true;
990
991 // Set any features implied by the architecture
992 std::vector<StringRef> CPUFeats;
993 if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
994 for (auto F : CPUFeats) {
995 assert(F[0] == '+' && "Expected + in target feature!");
996 Features[F.drop_front(1)] = true;
997 }
998 }
999}
1000
1001bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
1002 DiagnosticsEngine &Diags) {
1003 for (const auto &Feature : Features) {
1004 if (Feature == "-fp-armv8")
1005 HasNoFP = true;
1006 if (Feature == "-neon")
1007 HasNoNeon = true;
1008 if (Feature == "-sve")
1009 HasNoSVE = true;
1010
1011 if (Feature == "+neon" || Feature == "+fp-armv8")
1012 FPU |= NeonMode;
1013 if (Feature == "+jscvt") {
1014 HasJSCVT = true;
1015 FPU |= NeonMode;
1016 }
1017 if (Feature == "+fcma") {
1018 HasFCMA = true;
1019 FPU |= NeonMode;
1020 }
1021
1022 if (Feature == "+sve") {
1023 FPU |= NeonMode;
1024 FPU |= SveMode;
1025 HasFullFP16 = true;
1026 }
1027 if (Feature == "+sve2") {
1028 FPU |= NeonMode;
1029 FPU |= SveMode;
1030 HasFullFP16 = true;
1031 HasSVE2 = true;
1032 }
1033 if (Feature == "+sve2p1") {
1034 FPU |= NeonMode;
1035 FPU |= SveMode;
1036 HasFullFP16 = true;
1037 HasSVE2 = true;
1038 HasSVE2p1 = true;
1039 }
1040 if (Feature == "+sve-aes") {
1041 FPU |= NeonMode;
1042 HasFullFP16 = true;
1043 HasSVEAES = true;
1044 }
1045 if (Feature == "+sve2-sha3") {
1046 FPU |= NeonMode;
1047 FPU |= SveMode;
1048 HasFullFP16 = true;
1049 HasSVE2 = true;
1050 HasSVE2SHA3 = true;
1051 }
1052 if (Feature == "+sve2-sm4") {
1053 FPU |= NeonMode;
1054 FPU |= SveMode;
1055 HasFullFP16 = true;
1056 HasSVE2 = true;
1057 HasSVE2SM4 = true;
1058 }
1059 if (Feature == "+sve-b16b16")
1060 HasSVEB16B16 = true;
1061 if (Feature == "+sve-bitperm") {
1062 FPU |= NeonMode;
1063 HasFullFP16 = true;
1064 HasSVEBitPerm = true;
1065 }
1066 if (Feature == "+f32mm") {
1067 FPU |= NeonMode;
1068 FPU |= SveMode;
1069 HasFullFP16 = true;
1070 HasMatmulFP32 = true;
1071 }
1072 if (Feature == "+f64mm") {
1073 FPU |= NeonMode;
1074 FPU |= SveMode;
1075 HasFullFP16 = true;
1076 HasMatmulFP64 = true;
1077 }
1078 if (Feature == "+sme") {
1079 HasSME = true;
1080 HasBFloat16 = true;
1081 HasFullFP16 = true;
1082 }
1083 if (Feature == "+sme2") {
1084 HasSME = true;
1085 HasSME2 = true;
1086 HasBFloat16 = true;
1087 HasFullFP16 = true;
1088 }
1089 if (Feature == "+sme2p1") {
1090 HasSME = true;
1091 HasSME2 = true;
1092 HasSME2p1 = true;
1093 HasBFloat16 = true;
1094 HasFullFP16 = true;
1095 }
1096 if (Feature == "+sme-f64f64") {
1097 HasSME = true;
1098 HasSMEF64F64 = true;
1099 HasBFloat16 = true;
1100 HasFullFP16 = true;
1101 }
1102 if (Feature == "+sme-i16i64") {
1103 HasSME = true;
1104 HasSMEI16I64 = true;
1105 HasBFloat16 = true;
1106 HasFullFP16 = true;
1107 }
1108 if (Feature == "+sme-fa64") {
1109 FPU |= NeonMode;
1110 FPU |= SveMode;
1111 HasSME = true;
1112 HasSVE2 = true;
1113 HasSMEFA64 = true;
1114 }
1115 if (Feature == "+sme-f16f16") {
1116 HasSME = true;
1117 HasSME2 = true;
1118 HasBFloat16 = true;
1119 HasFullFP16 = true;
1120 HasSMEF16F16 = true;
1121 }
1122 if (Feature == "+sme-b16b16") {
1123 HasSME = true;
1124 HasSME2 = true;
1125 HasBFloat16 = true;
1126 HasFullFP16 = true;
1127 HasSVEB16B16 = true;
1128 HasSMEB16B16 = true;
1129 }
1130
1131 if (Feature == "+fp8")
1132 HasFP8 = true;
1133 if (Feature == "+fp8fma")
1134 HasFP8FMA = true;
1135 if (Feature == "+fp8dot2")
1136 HasFP8DOT2 = true;
1137 if (Feature == "+fp8dot4")
1138 HasFP8DOT4 = true;
1139 if (Feature == "+ssve-fp8dot2")
1140 HasSSVE_FP8DOT2 = true;
1141 if (Feature == "+ssve-fp8dot4")
1142 HasSSVE_FP8DOT4 = true;
1143 if (Feature == "+ssve-fp8fma")
1144 HasSSVE_FP8FMA = true;
1145 if (Feature == "+sme-f8f32")
1146 HasSME_F8F32 = true;
1147 if (Feature == "+sme-f8f16")
1148 HasSME_F8F16 = true;
1149 if (Feature == "+sb")
1150 HasSB = true;
1151 if (Feature == "+predres")
1152 HasPredRes = true;
1153 if (Feature == "+ssbs")
1154 HasSSBS = true;
1155 if (Feature == "+bti")
1156 HasBTI = true;
1157 if (Feature == "+wfxt")
1158 HasWFxT = true;
1159 if (Feature == "-fmv")
1160 HasFMV = false;
1161 if (Feature == "+crc")
1162 HasCRC = true;
1163 if (Feature == "+rcpc")
1164 HasRCPC = true;
1165 if (Feature == "+aes") {
1166 FPU |= NeonMode;
1167 HasAES = true;
1168 }
1169 if (Feature == "+sha2") {
1170 FPU |= NeonMode;
1171 HasSHA2 = true;
1172 }
1173 if (Feature == "+sha3") {
1174 FPU |= NeonMode;
1175 HasSHA2 = true;
1176 HasSHA3 = true;
1177 }
1178 if (Feature == "+rdm") {
1179 FPU |= NeonMode;
1180 HasRDM = true;
1181 }
1182 if (Feature == "+dit")
1183 HasDIT = true;
1184 if (Feature == "+cccp")
1185 HasCCPP = true;
1186 if (Feature == "+ccdp") {
1187 HasCCPP = true;
1188 HasCCDP = true;
1189 }
1190 if (Feature == "+fptoint")
1191 HasFRInt3264 = true;
1192 if (Feature == "+sm4") {
1193 FPU |= NeonMode;
1194 HasSM4 = true;
1195 }
1196 if (Feature == "+strict-align")
1197 HasUnalignedAccess = false;
1198 if (Feature == "+fprcvt")
1199 HasFPRCVT = true;
1200 if (Feature == "+f8f16mm")
1201 HasF8F16MM = true;
1202 if (Feature == "+f8f32mm")
1203 HasF8F32MM = true;
1204 if (Feature == "+sve-f16f32mm")
1205 HasSVE_F16F32MM = true;
1206 if (Feature == "+sve-b16mm")
1207 HasSVE_B16MM = true;
1208 if (Feature == "+f16mm")
1209 HasF16MM = true;
1210 if (Feature == "+f16f32dot")
1211 HasF16F32DOT = true;
1212 if (Feature == "+f16f32mm")
1213 HasF16F32MM = true;
1214 if (Feature == "+sve-bfscale")
1215 HasSVE_BFSCALE = true;
1216 if (Feature == "+sve-aes2")
1217 HasSVE_AES2 = true;
1218 if (Feature == "+ssve-aes")
1219 HasSSVE_AES = true;
1220 if (Feature == "+sve2p2")
1221 HasSVE2p2 = true;
1222 if (Feature == "+sve2p3")
1223 HasSVE2p3 = true;
1224 if (Feature == "+sme2p2")
1225 HasSME2p2 = true;
1226 if (Feature == "+sme2p3")
1227 HasSME2p3 = true;
1228
1229 // All predecessor archs are added but select the latest one for ArchKind.
1230 if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
1231 ArchInfo = &llvm::AArch64::ARMV8A;
1232 if (Feature == "+v8.1a" &&
1233 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
1234 ArchInfo = &llvm::AArch64::ARMV8_1A;
1235 if (Feature == "+v8.2a" &&
1236 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
1237 ArchInfo = &llvm::AArch64::ARMV8_2A;
1238 if (Feature == "+v8.3a" &&
1239 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
1240 ArchInfo = &llvm::AArch64::ARMV8_3A;
1241 if (Feature == "+v8.4a" &&
1242 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
1243 ArchInfo = &llvm::AArch64::ARMV8_4A;
1244 if (Feature == "+v8.5a" &&
1245 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
1246 ArchInfo = &llvm::AArch64::ARMV8_5A;
1247 if (Feature == "+v8.6a" &&
1248 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
1249 ArchInfo = &llvm::AArch64::ARMV8_6A;
1250 if (Feature == "+v8.7a" &&
1251 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
1252 ArchInfo = &llvm::AArch64::ARMV8_7A;
1253 if (Feature == "+v8.8a" &&
1254 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
1255 ArchInfo = &llvm::AArch64::ARMV8_8A;
1256 if (Feature == "+v8.9a" &&
1257 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
1258 ArchInfo = &llvm::AArch64::ARMV8_9A;
1259 if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
1260 ArchInfo = &llvm::AArch64::ARMV9A;
1261 if (Feature == "+v9.1a" &&
1262 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
1263 ArchInfo = &llvm::AArch64::ARMV9_1A;
1264 if (Feature == "+v9.2a" &&
1265 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
1266 ArchInfo = &llvm::AArch64::ARMV9_2A;
1267 if (Feature == "+v9.3a" &&
1268 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
1269 ArchInfo = &llvm::AArch64::ARMV9_3A;
1270 if (Feature == "+v9.4a" &&
1271 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
1272 ArchInfo = &llvm::AArch64::ARMV9_4A;
1273 if (Feature == "+v9.5a" &&
1274 ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
1275 ArchInfo = &llvm::AArch64::ARMV9_5A;
1276 if (Feature == "+v9.6a" &&
1277 ArchInfo->Version < llvm::AArch64::ARMV9_6A.Version)
1278 ArchInfo = &llvm::AArch64::ARMV9_6A;
1279 if (Feature == "+v9.7a" &&
1280 ArchInfo->Version < llvm::AArch64::ARMV9_7A.Version)
1281 ArchInfo = &llvm::AArch64::ARMV9_7A;
1282 if (Feature == "+v8r")
1283 ArchInfo = &llvm::AArch64::ARMV8R;
1284 if (Feature == "+fullfp16") {
1285 FPU |= NeonMode;
1286 HasFullFP16 = true;
1287 }
1288 if (Feature == "+dotprod") {
1289 FPU |= NeonMode;
1290 HasDotProd = true;
1291 }
1292 if (Feature == "+fp16fml") {
1293 FPU |= NeonMode;
1294 HasFullFP16 = true;
1295 HasFP16FML = true;
1296 }
1297 if (Feature == "+mte")
1298 HasMTE = true;
1299 if (Feature == "+pauth")
1300 HasPAuth = true;
1301 if (Feature == "+i8mm")
1302 HasMatMul = true;
1303 if (Feature == "+bf16")
1304 HasBFloat16 = true;
1305 if (Feature == "+lse")
1306 HasLSE = true;
1307 if (Feature == "+ls64")
1308 HasLS64 = true;
1309 if (Feature == "+rand")
1310 HasRandGen = true;
1311 if (Feature == "+flagm")
1312 HasFlagM = true;
1313 if (Feature == "+altnzcv") {
1314 HasFlagM = true;
1315 HasAlternativeNZCV = true;
1316 }
1317 if (Feature == "+mops")
1318 HasMOPS = true;
1319 if (Feature == "+d128")
1320 HasD128 = true;
1321 if (Feature == "+gcs")
1322 HasGCS = true;
1323 if (Feature == "+rcpc3")
1324 HasRCPC3 = true;
1325 if (Feature == "+pauth-lr") {
1326 HasPAuthLR = true;
1327 HasPAuth = true;
1328 }
1329 if (Feature == "+cssc")
1330 HasCSSC = true;
1331 }
1332
1333 // Check features that are manually disabled by command line options.
1334 // This needs to be checked after architecture-related features are handled,
1335 // making sure they are properly disabled when required.
1336 for (const auto &Feature : Features) {
1337 if (Feature == "-d128")
1338 HasD128 = false;
1339 }
1340
1342
1343 if (HasNoFP) {
1344 FPU &= ~FPUMode;
1345 FPU &= ~NeonMode;
1346 FPU &= ~SveMode;
1347 }
1348 if (HasNoNeon) {
1349 FPU &= ~NeonMode;
1350 FPU &= ~SveMode;
1351 }
1352 if (HasNoSVE)
1353 FPU &= ~SveMode;
1354
1355 computeFeatureLookup();
1356 return true;
1357}
1358
1359// Parse AArch64 Target attributes, which are a comma separated list of:
1360// "arch=<arch>" - parsed to features as per -march=..
1361// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
1362// "tune=<cpu>" - TuneCPU set to <cpu>
1363// "feature", "no-feature" - Add (or remove) feature.
1364// "+feature", "+nofeature" - Add (or remove) feature.
1365//
1366// A feature may correspond to an Extension (anything with a corresponding
1367// AEK_), in which case an ExtensionSet is used to parse it and expand its
1368// dependencies. If the feature does not yield a successful parse then it
1369// is passed through.
1371 ParsedTargetAttr Ret;
1372 if (Features == "default")
1373 return Ret;
1374 SmallVector<StringRef, 1> AttrFeatures;
1375 Features.split(AttrFeatures, ",");
1376 bool FoundArch = false;
1377
1378 auto SplitAndAddFeatures = [](StringRef FeatString,
1379 std::vector<std::string> &Features,
1380 llvm::AArch64::ExtensionSet &FeatureBits) {
1381 SmallVector<StringRef, 8> SplitFeatures;
1382 FeatString.split(SplitFeatures, StringRef("+"), -1, false);
1383 for (StringRef Feature : SplitFeatures) {
1384 if (FeatureBits.parseModifier(Feature))
1385 continue;
1386 // Pass through anything that failed to parse so that we can emit
1387 // diagnostics, as well as valid internal feature names.
1388 //
1389 // FIXME: We should consider rejecting internal feature names like
1390 // neon, v8a, etc.
1391 // FIXME: We should consider emitting diagnostics here.
1392 if (Feature.starts_with("no"))
1393 Features.push_back("-" + Feature.drop_front(2).str());
1394 else
1395 Features.push_back("+" + Feature.str());
1396 }
1397 };
1398
1399 llvm::AArch64::ExtensionSet FeatureBits;
1400 // Reconstruct the bitset from the command line option features.
1401 FeatureBits.reconstructFromParsedFeatures(getTargetOpts().FeaturesAsWritten,
1402 Ret.Features);
1403
1404 for (auto &Feature : AttrFeatures) {
1405 Feature = Feature.trim();
1406 if (Feature.starts_with("fpmath="))
1407 continue;
1408
1409 if (Feature.starts_with("branch-protection=")) {
1410 Ret.BranchProtection = Feature.split('=').second.trim();
1411 continue;
1412 }
1413
1414 if (Feature.starts_with("arch=")) {
1415 if (FoundArch)
1416 Ret.Duplicate = "arch=";
1417 FoundArch = true;
1418 std::pair<StringRef, StringRef> Split =
1419 Feature.split("=").second.trim().split("+");
1420 const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1421
1422 // Parse the architecture version, adding the required features to
1423 // Ret.Features.
1424 if (!AI)
1425 continue;
1426 FeatureBits.addArchDefaults(*AI);
1427 // Add any extra features, after the +
1428 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1429 } else if (Feature.starts_with("cpu=")) {
1430 if (!Ret.CPU.empty())
1431 Ret.Duplicate = "cpu=";
1432 else {
1433 // Split the cpu string into "cpu=", "cortex-a710" and any remaining
1434 // "+feat" features.
1435 std::pair<StringRef, StringRef> Split =
1436 Feature.split("=").second.trim().split("+");
1437 Ret.CPU = Split.first;
1438 if (auto CpuInfo = llvm::AArch64::parseCpu(Ret.CPU)) {
1439 FeatureBits.addCPUDefaults(*CpuInfo);
1440 SplitAndAddFeatures(Split.second, Ret.Features, FeatureBits);
1441 }
1442 }
1443 } else if (Feature.starts_with("tune=")) {
1444 if (!Ret.Tune.empty())
1445 Ret.Duplicate = "tune=";
1446 else
1447 Ret.Tune = Feature.split("=").second.trim();
1448 } else if (Feature.starts_with("+")) {
1449 SplitAndAddFeatures(Feature, Ret.Features, FeatureBits);
1450 } else {
1451 if (FeatureBits.parseModifier(Feature, /* AllowNoDashForm = */ true))
1452 continue;
1453 // Pass through anything that failed to parse so that we can emit
1454 // diagnostics, as well as valid internal feature names.
1455 //
1456 // FIXME: We should consider rejecting internal feature names like
1457 // neon, v8a, etc.
1458 // FIXME: We should consider emitting diagnostics here.
1459 if (Feature.starts_with("no-"))
1460 Ret.Features.push_back("-" + Feature.drop_front(3).str());
1461 else
1462 Ret.Features.push_back("+" + Feature.str());
1463 }
1464 }
1465 FeatureBits.toLLVMFeatureList(Ret.Features);
1466 return Ret;
1467}
1468
1470 return true;
1471}
1472
1475 switch (CC) {
1476 case CC_C:
1477 case CC_Swift:
1478 case CC_SwiftAsync:
1479 case CC_PreserveMost:
1480 case CC_PreserveAll:
1481 case CC_PreserveNone:
1482 case CC_DeviceKernel:
1484 case CC_AArch64SVEPCS:
1485 case CC_Win64:
1486 return CCCR_OK;
1487 default:
1488 return CCCR_Warning;
1489 }
1490}
1491
1492bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; }
1493
1497
1498const char *const AArch64TargetInfo::GCCRegNames[] = {
1499 // clang-format off
1500
1501 // 32-bit Integer registers
1502 "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
1503 "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
1504 "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
1505
1506 // 64-bit Integer registers
1507 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
1508 "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22",
1509 "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp",
1510
1511 // 32-bit floating point regsisters
1512 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1513 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1514 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1515
1516 // 64-bit floating point regsisters
1517 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1518 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1519 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1520
1521 // Neon vector registers
1522 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
1523 "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
1524 "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
1525
1526 // SVE vector registers
1527 "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
1528 "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
1529 "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
1530
1531 // SVE predicate registers
1532 "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
1533 "p11", "p12", "p13", "p14", "p15",
1534
1535 // SVE predicate-as-counter registers
1536 "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",
1537 "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
1538
1539 // SME registers
1540 "za", "zt0",
1541
1542 // clang-format on
1543};
1544
1548
1549const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
1550 {{"w31"}, "wsp"},
1551 {{"x31"}, "sp"},
1552 // GCC rN registers are aliases of xN registers.
1553 {{"r0"}, "x0"},
1554 {{"r1"}, "x1"},
1555 {{"r2"}, "x2"},
1556 {{"r3"}, "x3"},
1557 {{"r4"}, "x4"},
1558 {{"r5"}, "x5"},
1559 {{"r6"}, "x6"},
1560 {{"r7"}, "x7"},
1561 {{"r8"}, "x8"},
1562 {{"r9"}, "x9"},
1563 {{"r10"}, "x10"},
1564 {{"r11"}, "x11"},
1565 {{"r12"}, "x12"},
1566 {{"r13"}, "x13"},
1567 {{"r14"}, "x14"},
1568 {{"r15"}, "x15"},
1569 {{"r16"}, "x16"},
1570 {{"r17"}, "x17"},
1571 {{"r18"}, "x18"},
1572 {{"r19"}, "x19"},
1573 {{"r20"}, "x20"},
1574 {{"r21"}, "x21"},
1575 {{"r22"}, "x22"},
1576 {{"r23"}, "x23"},
1577 {{"r24"}, "x24"},
1578 {{"r25"}, "x25"},
1579 {{"r26"}, "x26"},
1580 {{"r27"}, "x27"},
1581 {{"r28"}, "x28"},
1582 {{"r29", "x29"}, "fp"},
1583 {{"r30", "x30"}, "lr"},
1584 // The S/D/Q and W/X registers overlap, but aren't really aliases; we
1585 // don't want to substitute one of these for a different-sized one.
1586};
1587
1591
1592// Returns the length of cc constraint.
1593static unsigned matchAsmCCConstraint(const char *Name) {
1594 constexpr unsigned len = 5;
1595 auto RV = llvm::StringSwitch<unsigned>(Name)
1596 .Case("@cceq", len)
1597 .Case("@ccne", len)
1598 .Case("@cchs", len)
1599 .Case("@cccs", len)
1600 .Case("@cccc", len)
1601 .Case("@cclo", len)
1602 .Case("@ccmi", len)
1603 .Case("@ccpl", len)
1604 .Case("@ccvs", len)
1605 .Case("@ccvc", len)
1606 .Case("@cchi", len)
1607 .Case("@ccls", len)
1608 .Case("@ccge", len)
1609 .Case("@cclt", len)
1610 .Case("@ccgt", len)
1611 .Case("@ccle", len)
1612 .Default(0);
1613 return RV;
1614}
1615
1616std::string
1617AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
1618 std::string R;
1619 switch (*Constraint) {
1620 case 'U': // Three-character constraint; add "@3" hint for later parsing.
1621 R = std::string("@3") + std::string(Constraint, 3);
1622 Constraint += 2;
1623 break;
1624 case '@':
1625 if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
1626 std::string Converted = "{" + std::string(Constraint, Len) + "}";
1627 Constraint += Len - 1;
1628 return Converted;
1629 }
1630 return std::string(1, *Constraint);
1631 default:
1632 R = TargetInfo::convertConstraint(Constraint);
1633 break;
1634 }
1635 return R;
1636}
1637
1639 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1640 switch (*Name) {
1641 default:
1642 return false;
1643 case 'w': // Floating point and SIMD registers (V0-V31)
1644 Info.setAllowsRegister();
1645 return true;
1646 case 'I': // Constant that can be used with an ADD instruction
1647 case 'J': // Constant that can be used with a SUB instruction
1648 case 'K': // Constant that can be used with a 32-bit logical instruction
1649 case 'L': // Constant that can be used with a 64-bit logical instruction
1650 case 'M': // Constant that can be used as a 32-bit MOV immediate
1651 case 'N': // Constant that can be used as a 64-bit MOV immediate
1652 case 'Y': // Floating point constant zero
1653 case 'Z': // Integer constant zero
1654 return true;
1655 case 'Q': // A memory reference with base register and no offset
1656 Info.setAllowsMemory();
1657 return true;
1658 case 'S': // A symbolic address
1659 Info.setAllowsRegister();
1660 return true;
1661 case 'U':
1662 if (Name[1] == 'p' &&
1663 (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
1664 // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
1665 Info.setAllowsRegister();
1666 Name += 2;
1667 return true;
1668 }
1669 if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
1670 // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
1671 Info.setAllowsRegister();
1672 Name += 2;
1673 return true;
1674 }
1675 // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
1676 // Utf: A memory address suitable for ldp/stp in TF mode.
1677 // Usa: An absolute symbolic address.
1678 // Ush: The high part (bits 32:12) of a pc-relative symbolic address.
1679
1680 // Better to return an error saying that it's an unrecognised constraint
1681 // even if this is a valid constraint in gcc.
1682 return false;
1683 case 'z': // Zero register, wzr or xzr
1684 Info.setAllowsRegister();
1685 return true;
1686 case 'x': // Floating point and SIMD registers (V0-V15)
1687 Info.setAllowsRegister();
1688 return true;
1689 case 'y': // SVE registers (V0-V7)
1690 Info.setAllowsRegister();
1691 return true;
1692 case '@':
1693 // CC condition
1694 if (const unsigned Len = matchAsmCCConstraint(Name)) {
1695 Name += Len - 1;
1696 Info.setAllowsRegister();
1697 Info.setOutputOperandBounds(0, 2);
1698 return true;
1699 }
1700 }
1701 return false;
1702}
1703
1705 StringRef Constraint, char Modifier, unsigned Size,
1706 std::string &SuggestedModifier) const {
1707 // Strip off constraint modifiers.
1708 Constraint = Constraint.ltrim("=+&");
1709
1710 switch (Constraint[0]) {
1711 default:
1712 return true;
1713 case 'z':
1714 case 'r': {
1715 switch (Modifier) {
1716 case 'x':
1717 case 'w':
1718 // For now assume that the person knows what they're
1719 // doing with the modifier.
1720 return true;
1721 default:
1722 // By default an 'r' constraint will be in the 'x'
1723 // registers.
1724 if (Size == 64)
1725 return true;
1726
1727 if (Size == 512)
1728 return HasLS64;
1729
1730 SuggestedModifier = "w";
1731 return false;
1732 }
1733 }
1734 }
1735}
1736
1737std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
1738
1740 if (RegNo == 0)
1741 return 0;
1742 if (RegNo == 1)
1743 return 1;
1744 return -1;
1745}
1746
1748 const llvm::APSInt &value) const {
1749 return 0 <= value && value <= 3;
1750}
1751
1752bool AArch64TargetInfo::hasInt128Type() const { return true; }
1753
1755 const TargetOptions &Opts)
1756 : AArch64TargetInfo(Triple, Opts) {}
1757
1759 MacroBuilder &Builder) const {
1760 Builder.defineMacro("__AARCH64EL__");
1762}
1763
1765 const TargetOptions &Opts)
1766 : AArch64TargetInfo(Triple, Opts) {}
1767
1769 MacroBuilder &Builder) const {
1770 Builder.defineMacro("__AARCH64EB__");
1771 Builder.defineMacro("__AARCH_BIG_ENDIAN");
1772 Builder.defineMacro("__ARM_BIG_ENDIAN");
1774}
1775
1777 const TargetOptions &Opts)
1778 : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
1779
1780 // This is an LLP64 platform.
1781 // int:4, long:4, long long:8, long double:8.
1782 IntWidth = IntAlign = 32;
1783 LongWidth = LongAlign = 32;
1786 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1792}
1793
1798
1801 switch (CC) {
1802 case CC_X86VectorCall:
1803 if (getTriple().isWindowsArm64EC())
1804 return CCCR_OK;
1805 return CCCR_Ignore;
1806 case CC_X86StdCall:
1807 case CC_X86ThisCall:
1808 case CC_X86FastCall:
1809 return CCCR_Ignore;
1810 case CC_C:
1811 case CC_DeviceKernel:
1812 case CC_PreserveMost:
1813 case CC_PreserveAll:
1814 case CC_PreserveNone:
1815 case CC_Swift:
1816 case CC_SwiftAsync:
1817 case CC_Win64:
1818 return CCCR_OK;
1819 default:
1820 return CCCR_Warning;
1821 }
1822}
1823
1825 const TargetOptions &Opts)
1826 : WindowsARM64TargetInfo(Triple, Opts) {
1827 TheCXXABI.set(TargetCXXABI::Microsoft);
1828}
1829
1831 MacroBuilder &Builder) const {
1833 if (getTriple().isWindowsArm64EC()) {
1834 Builder.defineMacro("_M_X64", "100");
1835 Builder.defineMacro("_M_AMD64", "100");
1836 Builder.defineMacro("_M_ARM64EC", "1");
1837 } else {
1838 Builder.defineMacro("_M_ARM64", "1");
1839 }
1840}
1841
1844 return CCK_MicrosoftWin64;
1845}
1846
1848 bool HasNonWeakDef) const {
1849 unsigned Align =
1850 WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
1851
1852 return std::max(Align, Microsoft64BitMinGlobalAlign(TypeSize));
1853}
1854
1856 const TargetOptions &Opts)
1857 : WindowsARM64TargetInfo(Triple, Opts) {
1858 TheCXXABI.set(TargetCXXABI::GenericAArch64);
1859}
1860
1862 const llvm::Triple &Triple, const TargetOptions &Opts)
1863 : AppleMachOTargetInfo<AArch64leTargetInfo>(Triple, Opts) {}
1864
1866 const TargetOptions &Opts)
1867 : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) {
1869 if (getTriple().isArch32Bit())
1871
1874
1876 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1877
1879
1880 if (getTriple().isArch32Bit()) {
1884 TheCXXABI.set(TargetCXXABI::WatchOS);
1885 } else
1886 TheCXXABI.set(TargetCXXABI::AppleARM64);
1887}
1888
1890 const LangOptions &Opts,
1891 const llvm::Triple &Triple) {
1892 Builder.defineMacro("__AARCH64_SIMD__");
1893 if (Triple.isArch32Bit())
1894 Builder.defineMacro("__ARM64_ARCH_8_32__");
1895 else
1896 Builder.defineMacro("__ARM64_ARCH_8__");
1897 Builder.defineMacro("__ARM_NEON__");
1898 Builder.defineMacro("__REGISTER_PREFIX__", "");
1899 Builder.defineMacro("__arm64", "1");
1900 Builder.defineMacro("__arm64__", "1");
1901
1902 if (Triple.isArm64e()) {
1903 Builder.defineMacro("__arm64e__", "1");
1904 Builder.defineMacro("__PTRAUTH_INTRINSICS__", "1");
1905 }
1906}
1907
1909 const llvm::Triple &Triple,
1910 MacroBuilder &Builder) const {
1911 getAppleMachOAArch64Defines(Builder, Opts, Triple);
1913 Builder);
1914}
1915
1917 const llvm::Triple &Triple,
1918 MacroBuilder &Builder) const {
1919 getAppleMachOAArch64Defines(Builder, Opts, Triple);
1921}
1922
Defines the Diagnostic-related interfaces.
static unsigned matchAsmCCConstraint(const char *Name)
Definition AArch64.cpp:1593
static constexpr int NumAArch64Builtins
Definition AArch64.cpp:37
#define ARM_ACLE_VERSION(Y, Q, P)
static constexpr int NumSVEBuiltins
Definition AArch64.cpp:32
static constexpr int NumFp16Builtins
Definition AArch64.cpp:30
static constexpr int NumSMEBuiltins
Definition AArch64.cpp:36
static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings
Definition AArch64.cpp:115
static constexpr int NumSVENeonBridgeBuiltins
Definition AArch64.cpp:34
static constexpr int NumNeonBuiltins
Definition AArch64.cpp:28
static constexpr auto BuiltinSVENeonBridgeInfos
Definition AArch64.cpp:124
static constexpr Builtin::Info PrefixedBuiltinInfos[]
Definition Hexagon.cpp:235
static constexpr Builtin::Info BuiltinInfos[]
Definition Builtins.cpp:39
static constexpr unsigned NumBuiltins
Definition Builtins.cpp:33
#define CLANG_BUILTIN_STR_TABLE_START
Definition Builtins.h:166
Defines the clang::LangOptions interface.
static bool HasFeature(const Preprocessor &PP, StringRef Feature)
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:234
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
@ NonLeaf
Sign the return address of functions that spill LR.
@ All
Sign the return address of all functions,.
@ BKey
Return address signing uses APIB key.
@ AKey
Return address signing uses APIA key.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isSignReturnAddressWithAKey() const
Check if return address signing uses AKey.
bool hasSignReturnAddress() const
Check if return address signing is enabled.
bool isSignReturnAddressScopeAll() const
Check if leaf functions are also signed.
LangOptions::SignReturnAddressScopeKind SignReturnAddr
LangOptions::SignReturnAddressKeyKind SignKey
TargetOptions & getTargetOpts() const
Retrieve the target options.
Definition TargetInfo.h:330
TargetInfo(const llvm::Triple &T)
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const LangASMap * AddrSpaceMap
Definition TargetInfo.h:260
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition TargetInfo.h:337
@ AArch64ABIBuiltinVaList
__builtin_va_list as defined by the AArch64 ABI http://infocenter.arm.com/help/topic/com....
Definition TargetInfo.h:346
@ CharPtrBuiltinVaList
typedef char* __builtin_va_list;
Definition TargetInfo.h:339
virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const =0
===-— Other target property query methods -----------------------—===//
unsigned HasUnalignedAccess
Definition TargetInfo.h:288
unsigned char MaxAtomicPromoteWidth
Definition TargetInfo.h:253
void resetDataLayout()
Set the data layout based on current triple and ABI.
virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const
getMinGlobalAlign - Return the minimum alignment of a global variable, unless its alignment is explic...
Definition TargetInfo.h:763
unsigned HasAArch64ACLETypes
Definition TargetInfo.h:279
virtual std::string convertConstraint(const char *&Constraint) const
unsigned char MaxAtomicInlineWidth
Definition TargetInfo.h:253
TargetCXXABI TheCXXABI
Definition TargetInfo.h:258
unsigned HasBuiltinMSVaList
Definition TargetInfo.h:273
Options for controlling the target.
llvm::EABI EABIVersion
The EABI version to use.
llvm::StringMap< bool > FeatureMap
The map of which features have been enabled disabled based on the command line.
void getTargetDefinesARMV95A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:385
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition AArch64.cpp:1737
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition AArch64.cpp:968
std::string convertConstraint(const char *&Constraint) const override
Definition AArch64.cpp:1617
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition AArch64.cpp:1588
bool hasBFloat16Type() const override
Determine whether the _BFloat16 type is supported on this target.
Definition AArch64.cpp:1469
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
Definition AArch64.cpp:1370
void getTargetDefinesARMV96A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:391
void getTargetDefinesARMV97A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:397
AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:133
ArrayRef< const char * > getGCCRegNames() const override
Definition AArch64.cpp:1545
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const override
Validate register name used for global register variables.
Definition AArch64.cpp:231
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
Definition AArch64.cpp:1001
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition AArch64.cpp:403
void setFeatureEnabled(llvm::StringMap< bool > &Features, StringRef Name, bool Enabled) const override
Enable or disable a specific target feature; the feature name must be valid.
Definition AArch64.cpp:972
llvm::SmallVector< Builtin::InfosShard > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition AArch64.cpp:791
bool setCPU(StringRef Name) override
Target the specified CPU.
Definition AArch64.cpp:288
void getTargetDefinesARMV89A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:349
void getTargetDefinesARMV92A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:367
bool validateTarget(DiagnosticsEngine &Diags) const override
Check the target is valid after it is fully initialized.
Definition AArch64.cpp:221
void getTargetDefinesARMV93A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:373
bool setABI(const std::string &Name) override
Use the specified ABI.
Definition AArch64.cpp:213
void getTargetDefinesARMV84A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:314
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
Definition AArch64.cpp:284
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
Definition AArch64.cpp:290
StringRef getABI() const override
Get the ABI currently in use.
Definition AArch64.cpp:211
bool hasInt128Type() const override
Determine whether the __int128 type is supported on this target.
Definition AArch64.cpp:1752
void getTargetDefinesARMV88A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:343
void getTargetDefinesARMV87A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:337
void getTargetDefinesARMV9A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:355
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition AArch64.cpp:1474
void getTargetDefinesARMV91A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:361
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts, ArmStreamingKind Mode, llvm::StringMap< bool > *FeatureMap=nullptr) const override
Returns target-specific min and max values VScale_Range.
Definition AArch64.cpp:806
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition AArch64.cpp:1494
int getEHDataRegisterNumber(unsigned RegNo) const override
Return the register number that __builtin_eh_return_regno would return with the specified argument.
Definition AArch64.cpp:1739
void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:295
bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const override
Determine if this TargetInfo supports the given branch protection specification.
Definition AArch64.cpp:252
void getTargetDefinesARMV86A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:327
void getTargetDefinesARMV94A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:379
llvm::APInt getFMVPriority(ArrayRef< StringRef > Features) const override
Definition AArch64.cpp:844
bool validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const override
Definition AArch64.cpp:1704
bool isCLZForZeroUndef() const override
The __builtin_clz* and __builtin_ctz* built-in functions are specified to have undefined results for ...
Definition AArch64.cpp:1492
void getTargetDefinesARMV82A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:300
void getTargetDefinesARMV83A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:306
bool validateCpuSupports(StringRef FeatureStr) const override
Definition AArch64.cpp:855
bool validatePointerAuthKey(const llvm::APSInt &value) const override
Determine whether the given pointer-authentication key is valid.
Definition AArch64.cpp:1747
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Definition AArch64.cpp:1638
bool doesFeatureAffectCodeGen(StringRef Name) const override
Returns true if feature has an impact on target code generation.
Definition AArch64.cpp:848
void getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const
Definition AArch64.cpp:320
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition AArch64.cpp:1768
AArch64beTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1764
AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1754
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition AArch64.cpp:1758
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
Definition AArch64.cpp:1908
AppleMachOAArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1861
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
Definition OSTargets.h:48
AppleMachOTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition OSTargets.h:54
DarwinAArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1865
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
Definition AArch64.cpp:1916
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition AArch64.cpp:1924
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
Definition OSTargets.h:78
DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition OSTargets.h:85
unsigned getMinGlobalAlign(uint64_t TypeSize, bool HasNonWeakDef) const override
getMinGlobalAlign - Return the minimum alignment of a global variable, unless its alignment is explic...
Definition AArch64.cpp:1847
MicrosoftARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1824
TargetInfo::CallingConvKind getCallingConvKind(bool ClangABICompat4) const override
Definition AArch64.cpp:1843
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition AArch64.cpp:1830
MinGWARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1855
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition AArch64.cpp:1795
WindowsARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition AArch64.cpp:1776
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition AArch64.cpp:1800
WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition OSTargets.h:888
Defines the clang::TargetInfo interface.
static constexpr Builtin::Info PrefixedBuiltinInfos[]
Definition AArch64.cpp:57
static constexpr Builtin::Info BuiltinInfos[]
Definition AArch64.cpp:51
static constexpr std::array< Info, N > MakeInfos(std::array< Info, N > Infos)
A constexpr function to construct an infos array from X-macros.
Definition Builtins.h:115
static constexpr std::array< Builtin::Info, NumFp16Builtins > BuiltinInfos
Definition AArch64.cpp:82
static constexpr std::array< Builtin::Info, NumNeonBuiltins > BuiltinInfos
Definition AArch64.cpp:71
static constexpr std::array< Builtin::Info, NumSMEBuiltins > BuiltinInfos
Definition AArch64.cpp:107
static constexpr std::array< Builtin::Info, NumSVEBuiltins > BuiltinInfos
Definition AArch64.cpp:95
void getAppleMachOAArch64Defines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple)
Definition AArch64.cpp:1889
llvm::SmallDenseSet< StringRef, 32 > AArch64FeatureSet
Definition AArch64.h:59
static const unsigned ARM64AddrSpaceMap[]
Definition AArch64.h:27
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
unsigned Microsoft64BitMinGlobalAlign(uint64_t TypeSize)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition Specifiers.h:279
@ CC_Swift
Definition Specifiers.h:294
@ CC_PreserveMost
Definition Specifiers.h:296
@ CC_Win64
Definition Specifiers.h:286
@ CC_X86ThisCall
Definition Specifiers.h:283
@ CC_AArch64VectorCall
Definition Specifiers.h:298
@ CC_DeviceKernel
Definition Specifiers.h:293
@ CC_PreserveNone
Definition Specifiers.h:301
@ CC_SwiftAsync
Definition Specifiers.h:295
@ CC_X86VectorCall
Definition Specifiers.h:284
@ CC_AArch64SVEPCS
Definition Specifiers.h:299
@ CC_X86StdCall
Definition Specifiers.h:281
@ CC_PreserveAll
Definition Specifiers.h:297
@ CC_X86FastCall
Definition Specifiers.h:282
FeatureLookupBuilder & Case(StringRef Feat, bool HasFeature)
Definition AArch64.cpp:871
FeatureLookupBuilder(AArch64FeatureSet &Features)
Definition AArch64.cpp:867
FeatureLookupBuilder & Cases(ArrayRef< StringRef > Feats, bool HasFeature)
Definition AArch64.cpp:877
The info used to represent each builtin.
Definition Builtins.h:80
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:60
void setOutputOperandBounds(unsigned Min, unsigned Max)
unsigned UseZeroLengthBitfieldAlignment
Whether zero length bitfields (e.g., int : 0;) force alignment of the next bitfield.
Definition TargetInfo.h:188
const llvm::fltSemantics * LongDoubleFormat
Definition TargetInfo.h:144
unsigned ZeroLengthBitfieldBoundary
If non-zero, specifies a fixed alignment value for bitfields that follow zero length bitfield,...
Definition TargetInfo.h:201
std::optional< unsigned > BitIntMaxAlign
Definition TargetInfo.h:106
unsigned LargestOverSizedBitfieldContainer
The largest container size which should be used for an over-sized bitfield, in bits.
Definition TargetInfo.h:205
unsigned UseBitFieldTypeAlignment
Control whether the alignment of bit-field types is respected when laying out structures.
Definition TargetInfo.h:179
unsigned UseSignedCharForObjCBool
Whether Objective-C's built-in boolean type should be signed char.
Definition TargetInfo.h:171
const llvm::fltSemantics * BFloat16Format
Definition TargetInfo.h:143