17#include "llvm/ADT/APSInt.h"
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/TargetParser/AArch64TargetParser.h"
22#include "llvm/TargetParser/ARMTargetParserCommon.h"
29#define BUILTIN(ID, TYPE, ATTRS) \
30 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
31#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
32 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
33#include "clang/Basic/BuiltinsNEON.def"
35#define BUILTIN(ID, TYPE, ATTRS) \
36 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
37#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
38 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
39#include "clang/Basic/BuiltinsSVE.def"
41#define BUILTIN(ID, TYPE, ATTRS) \
42 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
43#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
44 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
45#include "clang/Basic/BuiltinsSME.def"
47#define BUILTIN(ID, TYPE, ATTRS) \
48 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
49#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
50 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
51#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
52 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
53#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
54 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
55#include "clang/Basic/BuiltinsAArch64.def"
59 if (*ArchInfo == llvm::AArch64::ARMV8R) {
69 }
else if (ArchInfo->Version.getMajor() == 8) {
70 if (ArchInfo->Version.getMinor() >= 7u) {
73 if (ArchInfo->Version.getMinor() >= 6u) {
77 if (ArchInfo->Version.getMinor() >= 5u) {
78 HasAlternativeNZCV =
true;
85 if (ArchInfo->Version.getMinor() >= 4u) {
90 if (ArchInfo->Version.getMinor() >= 3u) {
94 if (ArchInfo->Version.getMinor() >= 2u) {
97 if (ArchInfo->Version.getMinor() >= 1u) {
102 }
else if (ArchInfo->Version.getMajor() == 9) {
103 if (ArchInfo->Version.getMinor() >= 2u) {
106 if (ArchInfo->Version.getMinor() >= 1u) {
113 HasAlternativeNZCV =
true;
151 if (Triple.isArch64Bit())
193 if (Triple.getOS() == llvm::Triple::Linux)
195 else if (Triple.getOS() == llvm::Triple::UnknownOS)
197 Opts.
EABIVersion == llvm::EABI::GNU ?
"\01_mcount" :
"mcount";
203 if (Name !=
"aapcs" && Name !=
"darwinpcs")
212 StringRef &Err)
const {
213 llvm::ARM::ParsedBranchProtection PBP;
214 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
218 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
223 if (PBP.Key ==
"a_key")
235 return Name ==
"generic" || llvm::AArch64::parseCpu(Name);
244 llvm::AArch64::fillValidCPUArchList(Values);
249 Builder.defineMacro(
"__ARM_FEATURE_QRDMX",
"1");
260 Builder.defineMacro(
"__ARM_FEATURE_COMPLEX",
"1");
261 Builder.defineMacro(
"__ARM_FEATURE_JCVT",
"1");
274 Builder.defineMacro(
"__ARM_FEATURE_FRINT",
"1");
275 Builder.defineMacro(
"__ARM_FEATURE_BTI",
"1");
350 Builder.defineMacro(
"__amd64__");
351 Builder.defineMacro(
"__amd64");
352 Builder.defineMacro(
"__x86_64");
353 Builder.defineMacro(
"__x86_64__");
354 Builder.defineMacro(
"__arm64ec__");
356 Builder.defineMacro(
"__aarch64__");
360 Builder.defineMacro(
"__GCC_ASM_FLAG_OUTPUTS__");
363 if (CodeModel ==
"default")
365 for (
char &
c : CodeModel)
367 Builder.defineMacro(
"__AARCH64_CMODEL_" + CodeModel +
"__");
370 Builder.defineMacro(
"__ARM_ACLE",
"200");
371 Builder.defineMacro(
"__ARM_ARCH",
372 std::to_string(ArchInfo->Version.getMajor()));
373 Builder.defineMacro(
"__ARM_ARCH_PROFILE",
374 std::string(
"'") + (
char)ArchInfo->Profile +
"'");
376 Builder.defineMacro(
"__ARM_64BIT_STATE",
"1");
377 Builder.defineMacro(
"__ARM_PCS_AAPCS64",
"1");
378 Builder.defineMacro(
"__ARM_ARCH_ISA_A64",
"1");
380 Builder.defineMacro(
"__ARM_FEATURE_CLZ",
"1");
381 Builder.defineMacro(
"__ARM_FEATURE_FMA",
"1");
382 Builder.defineMacro(
"__ARM_FEATURE_LDREX",
"0xF");
383 Builder.defineMacro(
"__ARM_FEATURE_IDIV",
"1");
384 Builder.defineMacro(
"__ARM_FEATURE_DIV");
385 Builder.defineMacro(
"__ARM_FEATURE_NUMERIC_MAXMIN",
"1");
386 Builder.defineMacro(
"__ARM_FEATURE_DIRECTED_ROUNDING",
"1");
388 Builder.defineMacro(
"__ARM_ALIGN_MAX_STACK_PWR",
"4");
392 Builder.defineMacro(
"__ARM_STATE_ZA",
"1");
393 Builder.defineMacro(
"__ARM_STATE_ZT0",
"1");
397 Builder.defineMacro(
"__ARM_FP",
"0xE");
401 Builder.defineMacro(
"__ARM_FP16_FORMAT_IEEE",
"1");
402 Builder.defineMacro(
"__ARM_FP16_ARGS",
"1");
404 if (Opts.UnsafeFPMath)
405 Builder.defineMacro(
"__ARM_FP_FAST",
"1");
407 Builder.defineMacro(
"__ARM_SIZEOF_WCHAR_T",
408 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
410 Builder.defineMacro(
"__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ?
"1" :
"4");
412 if (FPU & NeonMode) {
413 Builder.defineMacro(
"__ARM_NEON",
"1");
415 Builder.defineMacro(
"__ARM_NEON_FP",
"0xE");
419 Builder.defineMacro(
"__ARM_FEATURE_SVE",
"1");
421 if ((FPU & NeonMode) && (FPU & SveMode))
422 Builder.defineMacro(
"__ARM_NEON_SVE_BRIDGE",
"1");
425 Builder.defineMacro(
"__ARM_FEATURE_SVE2",
"1");
427 if (HasSVE2 && HasSVE2AES)
428 Builder.defineMacro(
"__ARM_FEATURE_SVE2_AES",
"1");
430 if (HasSVE2 && HasSVE2BitPerm)
431 Builder.defineMacro(
"__ARM_FEATURE_SVE2_BITPERM",
"1");
433 if (HasSVE2 && HasSVE2SHA3)
434 Builder.defineMacro(
"__ARM_FEATURE_SVE2_SHA3",
"1");
436 if (HasSVE2 && HasSVE2SM4)
437 Builder.defineMacro(
"__ARM_FEATURE_SVE2_SM4",
"1");
440 Builder.defineMacro(
"__ARM_FEATURE_SME");
441 Builder.defineMacro(
"__ARM_FEATURE_LOCALLY_STREAMING",
"1");
445 Builder.defineMacro(
"__ARM_FEATURE_SME");
446 Builder.defineMacro(
"__ARM_FEATURE_SME2");
447 Builder.defineMacro(
"__ARM_FEATURE_LOCALLY_STREAMING",
"1");
451 Builder.defineMacro(
"__ARM_FEATURE_CRC32",
"1");
454 Builder.defineMacro(
"__ARM_FEATURE_RCPC",
"3");
456 Builder.defineMacro(
"__ARM_FEATURE_RCPC",
"1");
459 Builder.defineMacro(
"__HAVE_FUNCTION_MULTI_VERSIONING",
"1");
463 if (HasAES && HasSHA2)
464 Builder.defineMacro(
"__ARM_FEATURE_CRYPTO",
"1");
467 Builder.defineMacro(
"__ARM_FEATURE_AES",
"1");
470 Builder.defineMacro(
"__ARM_FEATURE_SHA2",
"1");
473 Builder.defineMacro(
"__ARM_FEATURE_SHA3",
"1");
474 Builder.defineMacro(
"__ARM_FEATURE_SHA512",
"1");
478 Builder.defineMacro(
"__ARM_FEATURE_SM3",
"1");
479 Builder.defineMacro(
"__ARM_FEATURE_SM4",
"1");
483 Builder.defineMacro(
"__ARM_FEATURE_PAUTH",
"1");
486 Builder.defineMacro(
"__ARM_FEATURE_PAUTH_LR",
"1");
489 Builder.defineMacro(
"__ARM_FEATURE_UNALIGNED",
"1");
491 if ((FPU & NeonMode) && HasFullFP16)
492 Builder.defineMacro(
"__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
"1");
494 Builder.defineMacro(
"__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
"1");
497 Builder.defineMacro(
"__ARM_FEATURE_DOTPROD",
"1");
500 Builder.defineMacro(
"__ARM_FEATURE_MEMORY_TAGGING",
"1");
503 Builder.defineMacro(
"__ARM_FEATURE_TME",
"1");
506 Builder.defineMacro(
"__ARM_FEATURE_MATMUL_INT8",
"1");
509 Builder.defineMacro(
"__ARM_FEATURE_ATOMICS",
"1");
512 Builder.defineMacro(
"__ARM_FEATURE_BF16",
"1");
513 Builder.defineMacro(
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC",
"1");
514 Builder.defineMacro(
"__ARM_BF16_FORMAT_ALTERNATIVE",
"1");
515 Builder.defineMacro(
"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC",
"1");
518 if ((FPU & SveMode) && HasBFloat16) {
519 Builder.defineMacro(
"__ARM_FEATURE_SVE_BF16",
"1");
522 if ((FPU & SveMode) && HasMatmulFP64)
523 Builder.defineMacro(
"__ARM_FEATURE_SVE_MATMUL_FP64",
"1");
525 if ((FPU & SveMode) && HasMatmulFP32)
526 Builder.defineMacro(
"__ARM_FEATURE_SVE_MATMUL_FP32",
"1");
528 if ((FPU & SveMode) && HasMatMul)
529 Builder.defineMacro(
"__ARM_FEATURE_SVE_MATMUL_INT8",
"1");
531 if ((FPU & NeonMode) && HasFP16FML)
532 Builder.defineMacro(
"__ARM_FEATURE_FP16_FML",
"1");
550 if (Opts.BranchProtectionPAuthLR)
553 Builder.defineMacro(
"__ARM_FEATURE_PAC_DEFAULT", std::to_string(
Value));
556 if (Opts.BranchTargetEnforcement)
557 Builder.defineMacro(
"__ARM_FEATURE_BTI_DEFAULT",
"1");
559 if (Opts.GuardedControlStack)
560 Builder.defineMacro(
"__ARM_FEATURE_GCS_DEFAULT",
"1");
563 Builder.defineMacro(
"__ARM_FEATURE_LS64",
"1");
566 Builder.defineMacro(
"__ARM_FEATURE_RNG",
"1");
569 Builder.defineMacro(
"__ARM_FEATURE_MOPS",
"1");
572 Builder.defineMacro(
"__ARM_FEATURE_SYSREG128",
"1");
575 Builder.defineMacro(
"__ARM_FEATURE_GCS",
"1");
577 if (*ArchInfo == llvm::AArch64::ARMV8_1A)
579 else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
581 else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
583 else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
585 else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
587 else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
589 else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
591 else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
593 else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
595 else if (*ArchInfo == llvm::AArch64::ARMV9A)
597 else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
599 else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
601 else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
603 else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
605 else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
609 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
610 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
611 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
612 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
613 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
616 Builder.defineMacro(
"__FP_FAST_FMA",
"1");
617 Builder.defineMacro(
"__FP_FAST_FMAF",
"1");
621 Builder.defineMacro(
"__ARM_FEATURE_SVE_VECTOR_OPERATORS",
"2");
623 if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
624 Builder.defineMacro(
"__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
633std::optional<std::pair<unsigned, unsigned>>
635 if (LangOpts.VScaleMin || LangOpts.VScaleMax)
636 return std::pair<unsigned, unsigned>(
637 LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
640 return std::pair<unsigned, unsigned>(1, 16);
646 if (Name ==
"default")
648 if (
auto Ext = llvm::AArch64::parseArchExtension(Name))
649 return Ext->FmvPriority;
655 return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
659 if (
auto Ext = llvm::AArch64::parseArchExtension(Name))
660 return !Ext->DependentFeatures.empty();
665 if (
auto Ext = llvm::AArch64::parseArchExtension(Name))
666 return Ext->DependentFeatures;
673 FeatureStr.split(Features,
"+");
674 for (
auto &Feature : Features)
675 if (!llvm::AArch64::parseArchExtension(Feature.trim()).has_value())
681 return llvm::StringSwitch<bool>(Feature)
682 .Cases(
"aarch64",
"arm64",
"arm",
true)
684 .Cases(
"neon",
"fp",
"simd", FPU & NeonMode)
685 .Case(
"jscvt", HasJSCVT)
686 .Case(
"fcma", HasFCMA)
687 .Case(
"rng", HasRandGen)
688 .Case(
"flagm", HasFlagM)
689 .Case(
"flagm2", HasAlternativeNZCV)
690 .Case(
"fp16fml", HasFP16FML)
691 .Case(
"dotprod", HasDotProd)
696 .Case(
"sha2", HasSHA2)
697 .Case(
"sha3", HasSHA3)
698 .Cases(
"aes",
"pmull", HasAES)
699 .Cases(
"fp16",
"fullfp16", HasFullFP16)
701 .Case(
"dpb", HasCCPP)
702 .Case(
"dpb2", HasCCDP)
703 .Case(
"rcpc", HasRCPC)
704 .Case(
"frintts", HasFRInt3264)
705 .Case(
"i8mm", HasMatMul)
706 .Case(
"bf16", HasBFloat16)
707 .Case(
"sve", FPU & SveMode)
708 .Case(
"sve-bf16", FPU & SveMode && HasBFloat16)
709 .Case(
"sve-i8mm", FPU & SveMode && HasMatMul)
710 .Case(
"f32mm", FPU & SveMode && HasMatmulFP32)
711 .Case(
"f64mm", FPU & SveMode && HasMatmulFP64)
712 .Case(
"sve2", FPU & SveMode && HasSVE2)
713 .Case(
"sve2-pmull128", FPU & SveMode && HasSVE2AES)
714 .Case(
"sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
715 .Case(
"sve2-sha3", FPU & SveMode && HasSVE2SHA3)
716 .Case(
"sve2-sm4", FPU & SveMode && HasSVE2SM4)
718 .Case(
"sme2", HasSME2)
719 .Case(
"sme-f64f64", HasSMEF64F64)
720 .Case(
"sme-i16i64", HasSMEI16I64)
721 .Case(
"sme-fa64", HasSMEFA64)
722 .Cases(
"memtag",
"memtag2", HasMTE)
724 .Case(
"predres", HasPredRes)
725 .Cases(
"ssbs",
"ssbs2", HasSSBS)
727 .Cases(
"ls64",
"ls64_v",
"ls64_accdata", HasLS64)
728 .Case(
"wfxt", HasWFxT)
729 .Case(
"rcpc3", HasRCPC3)
734 StringRef Name,
bool Enabled)
const {
735 Features[Name] = Enabled;
738 const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
739 llvm::AArch64::ArchInfo::findBySubArch(Name);
748 for (
const auto *OtherArch : llvm::AArch64::ArchInfos)
749 if (ArchInfo->implies(*OtherArch))
750 Features[OtherArch->getSubArch()] =
true;
753 std::vector<StringRef> CPUFeats;
754 if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
755 for (
auto F : CPUFeats) {
756 assert(F[0] ==
'+' &&
"Expected + in target feature!");
757 Features[F.drop_front(1)] =
true;
764 for (
const auto &Feature : Features) {
765 if (Feature ==
"-fp-armv8")
767 if (Feature ==
"-neon")
769 if (Feature ==
"-sve")
772 if (Feature ==
"+neon" || Feature ==
"+fp-armv8")
774 if (Feature ==
"+jscvt") {
778 if (Feature ==
"+fcma") {
783 if (Feature ==
"+sve") {
788 if (Feature ==
"+sve2") {
794 if (Feature ==
"+sve2-aes") {
801 if (Feature ==
"+sve2-sha3") {
808 if (Feature ==
"+sve2-sm4") {
815 if (Feature ==
"+sve2-bitperm") {
820 HasSVE2BitPerm =
true;
822 if (Feature ==
"+f32mm") {
826 HasMatmulFP32 =
true;
828 if (Feature ==
"+f64mm") {
832 HasMatmulFP64 =
true;
834 if (Feature ==
"+sme") {
839 if (Feature ==
"+sme2") {
845 if (Feature ==
"+sme-f64f64") {
851 if (Feature ==
"+sme-i16i64") {
857 if (Feature ==
"+sme-fa64") {
864 if (Feature ==
"+sb")
866 if (Feature ==
"+predres")
868 if (Feature ==
"+ssbs")
870 if (Feature ==
"+bti")
872 if (Feature ==
"+wfxt")
874 if (Feature ==
"-fmv")
876 if (Feature ==
"+crc")
878 if (Feature ==
"+rcpc")
880 if (Feature ==
"+aes") {
884 if (Feature ==
"+sha2") {
888 if (Feature ==
"+sha3") {
893 if (Feature ==
"+rdm") {
897 if (Feature ==
"+dit")
899 if (Feature ==
"+cccp")
901 if (Feature ==
"+ccdp") {
905 if (Feature ==
"+fptoint")
907 if (Feature ==
"+sm4") {
911 if (Feature ==
"+strict-align")
912 HasUnaligned =
false;
914 if (Feature ==
"+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
915 ArchInfo = &llvm::AArch64::ARMV8A;
916 if (Feature ==
"+v8.1a" &&
917 ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
918 ArchInfo = &llvm::AArch64::ARMV8_1A;
919 if (Feature ==
"+v8.2a" &&
920 ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
921 ArchInfo = &llvm::AArch64::ARMV8_2A;
922 if (Feature ==
"+v8.3a" &&
923 ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
924 ArchInfo = &llvm::AArch64::ARMV8_3A;
925 if (Feature ==
"+v8.4a" &&
926 ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
927 ArchInfo = &llvm::AArch64::ARMV8_4A;
928 if (Feature ==
"+v8.5a" &&
929 ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
930 ArchInfo = &llvm::AArch64::ARMV8_5A;
931 if (Feature ==
"+v8.6a" &&
932 ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
933 ArchInfo = &llvm::AArch64::ARMV8_6A;
934 if (Feature ==
"+v8.7a" &&
935 ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
936 ArchInfo = &llvm::AArch64::ARMV8_7A;
937 if (Feature ==
"+v8.8a" &&
938 ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
939 ArchInfo = &llvm::AArch64::ARMV8_8A;
940 if (Feature ==
"+v8.9a" &&
941 ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
942 ArchInfo = &llvm::AArch64::ARMV8_9A;
943 if (Feature ==
"+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
944 ArchInfo = &llvm::AArch64::ARMV9A;
945 if (Feature ==
"+v9.1a" &&
946 ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
947 ArchInfo = &llvm::AArch64::ARMV9_1A;
948 if (Feature ==
"+v9.2a" &&
949 ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
950 ArchInfo = &llvm::AArch64::ARMV9_2A;
951 if (Feature ==
"+v9.3a" &&
952 ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
953 ArchInfo = &llvm::AArch64::ARMV9_3A;
954 if (Feature ==
"+v9.4a" &&
955 ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
956 ArchInfo = &llvm::AArch64::ARMV9_4A;
957 if (Feature ==
"+v9.5a" &&
958 ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
959 ArchInfo = &llvm::AArch64::ARMV9_5A;
960 if (Feature ==
"+v8r")
961 ArchInfo = &llvm::AArch64::ARMV8R;
962 if (Feature ==
"+fullfp16") {
966 if (Feature ==
"+dotprod") {
970 if (Feature ==
"+fp16fml") {
975 if (Feature ==
"+mte")
977 if (Feature ==
"+tme")
979 if (Feature ==
"+pauth")
981 if (Feature ==
"+i8mm")
983 if (Feature ==
"+bf16")
985 if (Feature ==
"+lse")
987 if (Feature ==
"+ls64")
989 if (Feature ==
"+rand")
991 if (Feature ==
"+flagm")
993 if (Feature ==
"+altnzcv") {
995 HasAlternativeNZCV =
true;
997 if (Feature ==
"+mops")
999 if (Feature ==
"+d128")
1001 if (Feature ==
"+gcs")
1003 if (Feature ==
"+rcpc3")
1005 if (Feature ==
"+pauth-lr") {
1014 for (
const auto &Feature : Features) {
1015 if (Feature ==
"-d128")
1039 const std::vector<std::string> &FeaturesVec)
const {
1040 std::vector<std::string> UpdatedFeaturesVec;
1042 std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
1044 auto Exts = CpuInfo->getImpliedExtensions();
1045 std::vector<StringRef> CPUFeats;
1046 llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
1047 for (
auto F : CPUFeats) {
1048 assert((F[0] ==
'+' || F[0] ==
'-') &&
"Expected +/- in target feature!");
1049 UpdatedFeaturesVec.push_back(F.str());
1057 for (
const auto &Feature : FeaturesVec)
1058 if (((Feature[0] ==
'?' || Feature[0] ==
'+')) &&
1060 StringRef DepFeatures =
1063 DepFeatures.split(AttrFeatures,
",");
1064 for (
auto F : AttrFeatures)
1065 UpdatedFeaturesVec.push_back(F.str());
1067 for (
const auto &Feature : FeaturesVec)
1068 if (Feature[0] !=
'?') {
1069 std::string UpdatedFeature = Feature;
1070 if (Feature[0] ==
'+') {
1071 std::optional<llvm::AArch64::ExtensionInfo> Extension =
1072 llvm::AArch64::parseArchExtension(Feature.substr(1));
1074 UpdatedFeature = Extension->Feature.str();
1076 UpdatedFeaturesVec.push_back(UpdatedFeature);
1090 if (Features ==
"default")
1093 Features.split(AttrFeatures,
",");
1094 bool FoundArch =
false;
1096 auto SplitAndAddFeatures = [](StringRef FeatString,
1097 std::vector<std::string> &Features) {
1099 FeatString.split(SplitFeatures, StringRef(
"+"), -1,
false);
1100 for (StringRef Feature : SplitFeatures) {
1101 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1102 if (!FeatureName.empty())
1103 Features.push_back(FeatureName.str());
1107 if (Feature.starts_with(
"no"))
1108 Features.push_back(
"-" + Feature.drop_front(2).str());
1110 Features.push_back(
"+" + Feature.str());
1114 for (
auto &Feature : AttrFeatures) {
1115 Feature = Feature.trim();
1116 if (Feature.starts_with(
"fpmath="))
1119 if (Feature.starts_with(
"branch-protection=")) {
1120 Ret.BranchProtection = Feature.split(
'=').second.trim();
1124 if (Feature.starts_with(
"arch=")) {
1126 Ret.Duplicate =
"arch=";
1128 std::pair<StringRef, StringRef> Split =
1129 Feature.split(
"=").second.trim().split(
"+");
1130 const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
1136 Ret.Features.push_back(AI->ArchFeature.str());
1138 SplitAndAddFeatures(Split.second, Ret.Features);
1139 }
else if (Feature.starts_with(
"cpu=")) {
1140 if (!Ret.CPU.empty())
1141 Ret.Duplicate =
"cpu=";
1145 std::pair<StringRef, StringRef> Split =
1146 Feature.split(
"=").second.trim().split(
"+");
1147 Ret.CPU = Split.first;
1148 SplitAndAddFeatures(Split.second, Ret.Features);
1150 }
else if (Feature.starts_with(
"tune=")) {
1151 if (!Ret.Tune.empty())
1152 Ret.Duplicate =
"tune=";
1154 Ret.Tune = Feature.split(
"=").second.trim();
1155 }
else if (Feature.starts_with(
"+")) {
1156 SplitAndAddFeatures(Feature, Ret.Features);
1157 }
else if (Feature.starts_with(
"no-")) {
1158 StringRef FeatureName =
1159 llvm::AArch64::getArchExtFeature(Feature.split(
"-").second);
1160 if (!FeatureName.empty())
1161 Ret.Features.push_back(
"-" + FeatureName.drop_front(1).str());
1163 Ret.Features.push_back(
"-" + Feature.split(
"-").second.str());
1168 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
1169 if (!FeatureName.empty())
1170 Ret.Features.push_back(FeatureName.str());
1172 Ret.Features.push_back(
"+" + Feature.str());
1206const char *
const AArch64TargetInfo::GCCRegNames[] = {
1210 "w0",
"w1",
"w2",
"w3",
"w4",
"w5",
"w6",
"w7",
"w8",
"w9",
"w10",
"w11",
1211 "w12",
"w13",
"w14",
"w15",
"w16",
"w17",
"w18",
"w19",
"w20",
"w21",
"w22",
1212 "w23",
"w24",
"w25",
"w26",
"w27",
"w28",
"w29",
"w30",
"wsp",
1215 "x0",
"x1",
"x2",
"x3",
"x4",
"x5",
"x6",
"x7",
"x8",
"x9",
"x10",
"x11",
1216 "x12",
"x13",
"x14",
"x15",
"x16",
"x17",
"x18",
"x19",
"x20",
"x21",
"x22",
1217 "x23",
"x24",
"x25",
"x26",
"x27",
"x28",
"fp",
"lr",
"sp",
1220 "s0",
"s1",
"s2",
"s3",
"s4",
"s5",
"s6",
"s7",
"s8",
"s9",
"s10",
"s11",
1221 "s12",
"s13",
"s14",
"s15",
"s16",
"s17",
"s18",
"s19",
"s20",
"s21",
"s22",
1222 "s23",
"s24",
"s25",
"s26",
"s27",
"s28",
"s29",
"s30",
"s31",
1225 "d0",
"d1",
"d2",
"d3",
"d4",
"d5",
"d6",
"d7",
"d8",
"d9",
"d10",
"d11",
1226 "d12",
"d13",
"d14",
"d15",
"d16",
"d17",
"d18",
"d19",
"d20",
"d21",
"d22",
1227 "d23",
"d24",
"d25",
"d26",
"d27",
"d28",
"d29",
"d30",
"d31",
1230 "v0",
"v1",
"v2",
"v3",
"v4",
"v5",
"v6",
"v7",
"v8",
"v9",
"v10",
"v11",
1231 "v12",
"v13",
"v14",
"v15",
"v16",
"v17",
"v18",
"v19",
"v20",
"v21",
"v22",
1232 "v23",
"v24",
"v25",
"v26",
"v27",
"v28",
"v29",
"v30",
"v31",
1235 "z0",
"z1",
"z2",
"z3",
"z4",
"z5",
"z6",
"z7",
"z8",
"z9",
"z10",
1236 "z11",
"z12",
"z13",
"z14",
"z15",
"z16",
"z17",
"z18",
"z19",
"z20",
"z21",
1237 "z22",
"z23",
"z24",
"z25",
"z26",
"z27",
"z28",
"z29",
"z30",
"z31",
1240 "p0",
"p1",
"p2",
"p3",
"p4",
"p5",
"p6",
"p7",
"p8",
"p9",
"p10",
1241 "p11",
"p12",
"p13",
"p14",
"p15",
1244 "pn0",
"pn1",
"pn2",
"pn3",
"pn4",
"pn5",
"pn6",
"pn7",
"pn8",
1245 "pn9",
"pn10",
"pn11",
"pn12",
"pn13",
"pn14",
"pn15",
1290 {{
"r29",
"x29"},
"fp"},
1291 {{
"r30",
"x30"},
"lr"},
1302 constexpr unsigned len = 5;
1303 auto RV = llvm::StringSwitch<unsigned>(Name)
1327 switch (*Constraint) {
1329 R = std::string(
"@3") + std::string(Constraint, 3);
1334 std::string Converted =
"{" + std::string(Constraint, Len) +
"}";
1335 Constraint += Len - 1;
1338 return std::string(1, *Constraint);
1370 if (Name[1] ==
'p' &&
1371 (Name[2] ==
'l' || Name[2] ==
'a' || Name[2] ==
'h')) {
1377 if (Name[1] ==
'c' && (Name[2] ==
'i' || Name[2] ==
'j')) {
1412 StringRef Constraint,
char Modifier,
unsigned Size,
1413 std::string &SuggestedModifier)
const {
1415 Constraint = Constraint.ltrim(
"=+&");
1417 switch (Constraint[0]) {
1437 SuggestedModifier =
"w";
1455 const llvm::APSInt &value)
const {
1456 return 0 <= value && value <= 3;
1465void AArch64leTargetInfo::setDataLayout() {
1472 resetDataLayout(
"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1477 Builder.defineMacro(
"__AARCH64EL__");
1487 Builder.defineMacro(
"__AARCH64EB__");
1488 Builder.defineMacro(
"__AARCH_BIG_ENDIAN");
1489 Builder.defineMacro(
"__ARM_BIG_ENDIAN");
1493void AArch64beTargetInfo::setDataLayout() {
1494 assert(!
getTriple().isOSBinFormatMachO());
1495 resetDataLayout(
"E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128");
1504 IntWidth = IntAlign = 32;
1505 LongWidth = LongAlign = 32;
1506 DoubleAlign = LongLongAlign = 64;
1507 LongDoubleWidth = LongDoubleAlign = 64;
1508 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1509 IntMaxType = SignedLongLong;
1510 Int64Type = SignedLongLong;
1511 SizeType = UnsignedLongLong;
1512 PtrDiffType = SignedLongLong;
1513 IntPtrType = SignedLongLong;
1517 resetDataLayout(Triple.isOSBinFormatMachO()
1518 ?
"e-m:o-i64:64-i128:128-n32:64-S128"
1519 :
"e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128",
1520 Triple.isOSBinFormatMachO() ?
"_" :
"");
1545 return CCCR_Warning;
1552 TheCXXABI.set(TargetCXXABI::Microsoft);
1558 if (getTriple().isWindowsArm64EC()) {
1559 Builder.defineMacro(
"_M_X64",
"100");
1560 Builder.defineMacro(
"_M_AMD64",
"100");
1561 Builder.defineMacro(
"_M_ARM64EC",
"1");
1563 Builder.defineMacro(
"_M_ARM64",
"1");
1569 return CCK_MicrosoftWin64;
1573 bool HasNonWeakDef)
const {
1575 WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize, HasNonWeakDef);
1581 if (TypeSize >= 512) {
1582 Align = std::max(Align, 128u);
1583 }
else if (TypeSize >= 64) {
1584 Align = std::max(Align, 64u);
1585 }
else if (TypeSize >= 16) {
1586 Align = std::max(Align, 32u);
1594 TheCXXABI.set(TargetCXXABI::GenericAArch64);
1600 Int64Type = SignedLongLong;
1601 if (getTriple().isArch32Bit())
1602 IntMaxType = SignedLongLong;
1604 WCharType = SignedInt;
1605 UseSignedCharForObjCBool =
false;
1607 LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
1608 LongDoubleFormat = &llvm::APFloat::IEEEdouble();
1610 UseZeroLengthBitfieldAlignment =
false;
1612 if (getTriple().isArch32Bit()) {
1613 UseBitFieldTypeAlignment =
false;
1614 ZeroLengthBitfieldBoundary = 32;
1615 UseZeroLengthBitfieldAlignment =
true;
1616 TheCXXABI.set(TargetCXXABI::WatchOS);
1618 TheCXXABI.set(TargetCXXABI::AppleARM64);
1622 const llvm::Triple &Triple,
1624 Builder.defineMacro(
"__AARCH64_SIMD__");
1625 if (Triple.isArch32Bit())
1626 Builder.defineMacro(
"__ARM64_ARCH_8_32__");
1628 Builder.defineMacro(
"__ARM64_ARCH_8__");
1629 Builder.defineMacro(
"__ARM_NEON__");
1630 Builder.defineMacro(
"__REGISTER_PREFIX__",
"");
1631 Builder.defineMacro(
"__arm64",
"1");
1632 Builder.defineMacro(
"__arm64__",
"1");
1634 if (Triple.isArm64e())
1635 Builder.defineMacro(
"__arm64e__",
"1");
1650 Triple.getEnvironmentName()),
1657 Builder.defineMacro(
"__RENDERSCRIPT__");
static unsigned matchAsmCCConstraint(const char *Name)
static constexpr Builtin::Info BuiltinInfo[]
static constexpr Builtin::Info BuiltinInfo[]
Defines the clang::LangOptions interface.
Enumerates target-specific builtins in their own namespaces within namespace clang.
__device__ __2f16 float c
Concrete class used by the front-end to report problems and issues.
@ None
No signing for any function.
@ 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.
Exposes information about the current target.
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned HasAArch64SVETypes
void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
@ AArch64ABIBuiltinVaList
__builtin_va_list as defined by the AArch64 ABI http://infocenter.arm.com/help/topic/com....
@ CharPtrBuiltinVaList
typedef char* __builtin_va_list;
unsigned IsRenderScriptTarget
unsigned char MaxAtomicPromoteWidth
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
virtual std::string convertConstraint(const char *&Constraint) const
unsigned char MaxAtomicInlineWidth
unsigned HasBuiltinMSVaList
Options for controlling the target.
llvm::EABI EABIVersion
The EABI version to use.
void getTargetDefinesARMV95A(const LangOptions &Opts, MacroBuilder &Builder) const
unsigned multiVersionSortPriority(StringRef Name) const override
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
std::string convertConstraint(const char *&Constraint) const override
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
bool hasBFloat16Type() const override
Determine whether the _BFloat16 type is supported on this target.
ParsedTargetAttr parseTargetAttr(StringRef Str) const override
AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeaturesVec) const override
Initialize the map with the default set of target features for the CPU this should include all legal ...
unsigned multiVersionFeatureCost() const override
ArrayRef< const char * > getGCCRegNames() const override
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
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.
void getTargetDefinesARMV89A(const LangOptions &Opts, MacroBuilder &Builder) const
void getTargetDefinesARMV92A(const LangOptions &Opts, MacroBuilder &Builder) const
StringRef getFeatureDependencies(StringRef Name) const override
For given feature return dependent ones.
void getTargetDefinesARMV93A(const LangOptions &Opts, MacroBuilder &Builder) const
bool setABI(const std::string &Name) override
Use the specified ABI.
void getTargetDefinesARMV84A(const LangOptions &Opts, MacroBuilder &Builder) const
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
StringRef getABI() const override
Get the ABI currently in use.
bool hasInt128Type() const override
Determine whether the __int128 type is supported on this target.
void getTargetDefinesARMV88A(const LangOptions &Opts, MacroBuilder &Builder) const
bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, StringRef &Err) const override
Determine if this TargetInfo supports the given branch protection specification.
void getTargetDefinesARMV87A(const LangOptions &Opts, MacroBuilder &Builder) const
void getTargetDefinesARMV9A(const LangOptions &Opts, MacroBuilder &Builder) const
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
void getTargetDefinesARMV91A(const LangOptions &Opts, MacroBuilder &Builder) const
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
int getEHDataRegisterNumber(unsigned RegNo) const override
Return the register number that __builtin_eh_return_regno would return with the specified argument.
void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
void getTargetDefinesARMV86A(const LangOptions &Opts, MacroBuilder &Builder) const
bool setCPU(const std::string &Name) override
Target the specified CPU.
std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const override
Returns target-specific min and max values VScale_Range.
void getTargetDefinesARMV94A(const LangOptions &Opts, MacroBuilder &Builder) const
bool validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const override
bool isCLZForZeroUndef() const override
The __builtin_clz* and __builtin_ctz* built-in functions are specified to have undefined results for ...
void getTargetDefinesARMV82A(const LangOptions &Opts, MacroBuilder &Builder) const
void getTargetDefinesARMV83A(const LangOptions &Opts, MacroBuilder &Builder) const
bool validateCpuSupports(StringRef FeatureStr) const override
bool validatePointerAuthKey(const llvm::APSInt &value) const override
Determine whether the given pointer-authentication key is valid.
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
bool doesFeatureAffectCodeGen(StringRef Name) const override
Returns true if feature has an impact on target code generation.
void getTargetDefinesARMV85A(const LangOptions &Opts, MacroBuilder &Builder) const
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
AArch64beTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
DarwinAArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
BuiltinVaListKind getBuiltinVaListKind() const override
unsigned getMinGlobalAlign(uint64_t TypeSize, bool HasNonWeakDef) const override
MicrosoftARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
TargetInfo::CallingConvKind getCallingConvKind(bool ClangABICompat4) const override
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
MinGWARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
RenderScript64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
BuiltinVaListKind getBuiltinVaListKind() const override
WindowsARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void setDataLayout() override
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Defines the clang::TargetInfo interface.
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple, StringRef &PlatformName, VersionTuple &PlatformMinVersion)
The JSON file list parser is used to communicate input to InstallAPI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
YAML serialization mapping.
Contains information gathered from parsing the contents of TargetAttr.
LangOptions::SignReturnAddressScopeKind SignReturnAddr
LangOptions::SignReturnAddressKeyKind SignKey
bool BranchProtectionPAuthLR
bool BranchTargetEnforcement
unsigned UseZeroLengthBitfieldAlignment
Whether zero length bitfields (e.g., int : 0;) force alignment of the next bitfield.
unsigned short SuitableAlign
unsigned char PointerWidth
const llvm::fltSemantics * LongDoubleFormat
unsigned UseBitFieldTypeAlignment
Control whether the alignment of bit-field types is respected when laying out structures.
unsigned char PointerAlign
unsigned char BFloat16Width
unsigned char LongDoubleAlign
unsigned char LongDoubleWidth
unsigned char BFloat16Align
const llvm::fltSemantics * BFloat16Format