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