17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSwitch.h"
19#include "llvm/TargetParser/ARMTargetParser.h"
24void ARMTargetInfo::setABIAAPCS() {
33 bool IsNetBSD =
T.isOSNetBSD();
34 bool IsOpenBSD =
T.isOSOpenBSD();
35 if (!
T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
44 if (
T.isOSBinFormatMachO()) {
46 ?
"E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
47 :
"e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
49 }
else if (
T.isOSWindows()) {
50 assert(!
BigEndian &&
"Windows on ARM does not support big endian");
62 ?
"E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
63 :
"e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
69void ARMTargetInfo::setABIAPCS(
bool IsAAPCS16) {
92 if (
T.isOSBinFormatMachO() && IsAAPCS16) {
93 assert(!
BigEndian &&
"AAPCS16 does not support big-endian");
95 }
else if (
T.isOSBinFormatMachO())
98 ?
"E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
99 :
"e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
104 ?
"E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
105 :
"e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
110void ARMTargetInfo::setArchInfo() {
113 ArchISA = llvm::ARM::parseArchISA(
ArchName);
114 CPU = std::string(llvm::ARM::getDefaultCPU(
ArchName));
115 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(
ArchName);
116 if (AK != llvm::ARM::ArchKind::INVALID)
118 setArchInfo(ArchKind);
121void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
126 SubArch = llvm::ARM::getSubArch(ArchKind);
127 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
128 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
131 CPUAttr = getCPUAttr();
132 CPUProfile = getCPUProfile();
135void ARMTargetInfo::setAtomic() {
136 if (ArchProfile == llvm::ARM::ProfileKind::M) {
140 if (ArchVersion >= 7)
153 if (
getTriple().getOS() == llvm::Triple::Linux || ArchVersion >= 6)
158bool ARMTargetInfo::hasMVE()
const {
159 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline &&
MVE != 0;
162bool ARMTargetInfo::hasMVEFloat()
const {
163 return hasMVE() && (
MVE & MVE_FP);
168bool ARMTargetInfo::isThumb()
const {
169 return ArchISA == llvm::ARM::ISAKind::THUMB;
172bool ARMTargetInfo::supportsThumb()
const {
173 return CPUAttr.count(
'T') || ArchVersion >= 6;
176bool ARMTargetInfo::supportsThumb2()
const {
177 return CPUAttr ==
"6T2" || (ArchVersion >= 7 && CPUAttr !=
"8M_BASE");
180StringRef ARMTargetInfo::getCPUAttr()
const {
185 return llvm::ARM::getCPUAttr(ArchKind);
186 case llvm::ARM::ArchKind::ARMV6M:
188 case llvm::ARM::ArchKind::ARMV7S:
190 case llvm::ARM::ArchKind::ARMV7A:
192 case llvm::ARM::ArchKind::ARMV7R:
194 case llvm::ARM::ArchKind::ARMV7M:
196 case llvm::ARM::ArchKind::ARMV7EM:
198 case llvm::ARM::ArchKind::ARMV7VE:
200 case llvm::ARM::ArchKind::ARMV8A:
202 case llvm::ARM::ArchKind::ARMV8_1A:
204 case llvm::ARM::ArchKind::ARMV8_2A:
206 case llvm::ARM::ArchKind::ARMV8_3A:
208 case llvm::ARM::ArchKind::ARMV8_4A:
210 case llvm::ARM::ArchKind::ARMV8_5A:
212 case llvm::ARM::ArchKind::ARMV8_6A:
214 case llvm::ARM::ArchKind::ARMV8_7A:
216 case llvm::ARM::ArchKind::ARMV8_8A:
218 case llvm::ARM::ArchKind::ARMV8_9A:
220 case llvm::ARM::ArchKind::ARMV9A:
222 case llvm::ARM::ArchKind::ARMV9_1A:
224 case llvm::ARM::ArchKind::ARMV9_2A:
226 case llvm::ARM::ArchKind::ARMV9_3A:
228 case llvm::ARM::ArchKind::ARMV9_4A:
230 case llvm::ARM::ArchKind::ARMV9_5A:
232 case llvm::ARM::ArchKind::ARMV9_6A:
234 case llvm::ARM::ArchKind::ARMV8MBaseline:
236 case llvm::ARM::ArchKind::ARMV8MMainline:
238 case llvm::ARM::ArchKind::ARMV8R:
240 case llvm::ARM::ArchKind::ARMV8_1MMainline:
245StringRef ARMTargetInfo::getCPUProfile()
const {
246 switch (ArchProfile) {
247 case llvm::ARM::ProfileKind::A:
249 case llvm::ARM::ProfileKind::R:
251 case llvm::ARM::ProfileKind::M:
260 :
TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(
true), LDREX(0),
262 bool IsFreeBSD = Triple.isOSFreeBSD();
263 bool IsOpenBSD = Triple.isOSOpenBSD();
264 bool IsNetBSD = Triple.isOSNetBSD();
265 bool IsHaiku = Triple.isOSHaiku();
266 bool IsOHOS = Triple.isOHOSFamily();
272 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
277 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
283 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
284 !Triple.isWatchABI())
297 if (Triple.isOSBinFormatMachO()) {
300 if (Triple.getEnvironment() == llvm::Triple::EABI ||
301 Triple.getOS() == llvm::Triple::UnknownOS ||
302 ArchProfile == llvm::ARM::ProfileKind::M) {
304 }
else if (Triple.isWatchABI()) {
309 }
else if (Triple.isOSWindows()) {
314 switch (Triple.getEnvironment()) {
315 case llvm::Triple::Android:
316 case llvm::Triple::GNUEABI:
317 case llvm::Triple::GNUEABIT64:
318 case llvm::Triple::GNUEABIHF:
319 case llvm::Triple::GNUEABIHFT64:
320 case llvm::Triple::MuslEABI:
321 case llvm::Triple::MuslEABIHF:
322 case llvm::Triple::OpenHOS:
325 case llvm::Triple::EABIHF:
326 case llvm::Triple::EABI:
329 case llvm::Triple::GNU:
335 else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS)
351 if (IsAAPCS && !Triple.isAndroid())
360 if (Triple.getOS() == llvm::Triple::Linux ||
361 Triple.getOS() == llvm::Triple::UnknownOS)
363 ?
"llvm.arm.gnu.eabi.mcount"
378 if (Name ==
"apcs-gnu" || Name ==
"aapcs16") {
379 setABIAPCS(Name ==
"aapcs16");
382 if (Name ==
"aapcs" || Name ==
"aapcs-vfp" || Name ==
"aapcs-linux") {
390 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(
Arch);
391 if (CPUArch == llvm::ARM::ArchKind::INVALID)
392 CPUArch = llvm::ARM::parseArch(
getTriple().getArchName());
394 if (CPUArch == llvm::ARM::ArchKind::INVALID)
397 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
399 llvm::Triple(ArchFeature,
getTriple().getVendorName(),
402 StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
403 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
404 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
410 StringRef &Err)
const {
411 llvm::ARM::ParsedBranchProtection PBP;
412 if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
419 llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
425 if (PBP.Key ==
"b_key")
437 const std::vector<std::string> &FeaturesVec)
const {
439 std::string ArchFeature;
440 std::vector<StringRef> TargetFeatures;
441 llvm::ARM::ArchKind
Arch = llvm::ARM::parseArch(
getTriple().getArchName());
445 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
446 if (CPUArch == llvm::ARM::ArchKind::INVALID)
448 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
449 ArchFeature = (
"+" + llvm::ARM::getArchName(CPUArch)).str();
450 TargetFeatures.push_back(ArchFeature);
456 for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
457 I != llvm::ARM::ArchKind::INVALID; --I)
458 Features[llvm::ARM::getSubArch(I)] =
true;
459 if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
460 CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
461 for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
463 Features[llvm::ARM::getSubArch(I)] =
true;
467 llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU,
Arch);
468 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
471 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU,
Arch);
472 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
474 for (
auto Feature : TargetFeatures)
476 Features[
Feature.drop_front(1)] =
true;
481 Features[
"thumb-mode"] =
true;
483 Features[
"thumb-mode"] =
false;
487 std::vector<std::string> UpdatedFeaturesVec;
488 for (
const auto &
Feature : FeaturesVec) {
491 if (
Feature ==
"+soft-float-abi")
494 StringRef FixedFeature;
496 FixedFeature =
"-thumb-mode";
498 FixedFeature =
"+thumb-mode";
501 UpdatedFeaturesVec.push_back(FixedFeature.str());
529 FPRegsDisabled =
false;
533 for (
const auto &
Feature : Features) {
534 if (
Feature ==
"+soft-float") {
550 HW_FP |= HW_FP_SP | HW_FP_HP;
553 }
else if (
Feature ==
"+fp-armv8sp" ||
Feature ==
"+fp-armv8d16sp" ||
556 HW_FP |= HW_FP_SP | HW_FP_HP;
559 }
else if (
Feature ==
"+neon") {
562 }
else if (
Feature ==
"+hwdiv") {
564 }
else if (
Feature ==
"+hwdiv-arm") {
566 }
else if (
Feature ==
"+crc") {
568 }
else if (
Feature ==
"+crypto") {
570 }
else if (
Feature ==
"+sha2") {
572 }
else if (
Feature ==
"+aes") {
574 }
else if (
Feature ==
"+dsp") {
576 }
else if (
Feature ==
"+fp64") {
578 }
else if (
Feature ==
"+8msecext") {
579 if (CPUProfile !=
"M" || ArchVersion != 8) {
580 Diags.
Report(diag::err_target_unsupported_mcmse) << CPU;
583 }
else if (
Feature ==
"+strict-align") {
585 }
else if (
Feature ==
"+fp16") {
587 }
else if (
Feature ==
"+fullfp16") {
589 }
else if (
Feature ==
"+dotprod") {
591 }
else if (
Feature ==
"+mve") {
593 }
else if (
Feature ==
"+mve.fp") {
596 MVE |= MVE_INT | MVE_FP;
597 HW_FP |= HW_FP_SP | HW_FP_HP;
598 }
else if (
Feature ==
"+i8mm") {
600 }
else if (
Feature.size() == strlen(
"+cdecp0") &&
Feature >=
"+cdecp0" &&
602 unsigned Coproc =
Feature.back() -
'0';
604 }
else if (
Feature ==
"+bf16") {
606 }
else if (
Feature ==
"-fpregs") {
607 FPRegsDisabled =
true;
608 }
else if (
Feature ==
"+pacbti") {
611 }
else if (
Feature ==
"+fullbf16") {
613 }
else if (
Feature ==
"+execute-only") {
620 switch (ArchVersion) {
622 if (ArchProfile == llvm::ARM::ProfileKind::M)
624 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K ||
625 ArchKind == llvm::ARM::ArchKind::ARMV6KZ)
632 if (ArchProfile == llvm::ARM::ProfileKind::M)
638 assert(ArchProfile != llvm::ARM::ProfileKind::M &&
639 "No Armv9-M architectures defined");
643 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
644 Diags.
Report(diag::err_target_unsupported_fpmath) <<
"neon";
648 if (FPMath == FP_Neon)
649 Features.push_back(
"+neonfp");
650 else if (FPMath == FP_VFP)
651 Features.push_back(
"-neonfp");
657 return llvm::StringSwitch<bool>(
Feature)
659 .Case(
"aarch32",
true)
660 .Case(
"softfloat", SoftFloat)
661 .Case(
"thumb", isThumb())
662 .Case(
"neon", (FPU & NeonFPU) && !SoftFloat)
663 .Case(
"vfp", FPU && !SoftFloat)
664 .Case(
"hwdiv", HWDiv & HWDivThumb)
665 .Case(
"hwdiv-arm", HWDiv & HWDivARM)
666 .Case(
"mve", hasMVE())
676 return Name ==
"generic" ||
677 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
681 llvm::ARM::fillValidCPUArchList(Values);
685 if (Name !=
"generic")
686 setArchInfo(llvm::ARM::parseCPUArch(Name));
688 if (ArchKind == llvm::ARM::ArchKind::INVALID)
696 if (Name ==
"neon") {
699 }
else if (Name ==
"vfp" || Name ==
"vfp2" || Name ==
"vfp3" ||
709 Builder.defineMacro(
"__ARM_FEATURE_QRDMX",
"1");
721 Builder.defineMacro(
"__ARM_FEATURE_COMPLEX",
"1");
728 Builder.defineMacro(
"__arm");
729 Builder.defineMacro(
"__arm__");
731 if (
getTriple().getOS() == llvm::Triple::UnknownOS &&
732 (
getTriple().getEnvironment() == llvm::Triple::EABI ||
733 getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
735 Builder.defineMacro(
"_GNU_SOURCE");
739 Builder.defineMacro(
"__REGISTER_PREFIX__",
"");
744 Builder.defineMacro(
"__ARM_ARCH_7K__",
"2");
746 if (!CPUAttr.empty())
747 Builder.defineMacro(
"__ARM_ARCH_" + CPUAttr +
"__");
751 Builder.defineMacro(
"__ARM_ARCH", Twine(ArchVersion));
753 if (ArchVersion >= 8) {
758 Builder.defineMacro(
"__ARM_FEATURE_CRYPTO",
"1");
760 Builder.defineMacro(
"__ARM_FEATURE_SHA2",
"1");
762 Builder.defineMacro(
"__ARM_FEATURE_AES",
"1");
765 Builder.defineMacro(
"__ARM_FEATURE_CRC32",
"1");
767 Builder.defineMacro(
"__ARM_FEATURE_NUMERIC_MAXMIN",
"1");
769 Builder.defineMacro(
"__ARM_FEATURE_DIRECTED_ROUNDING",
"1");
775 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
776 Builder.defineMacro(
"__ARM_ARCH_ISA_ARM",
"1");
782 if (supportsThumb2())
783 Builder.defineMacro(
"__ARM_ARCH_ISA_THUMB",
"2");
784 else if (supportsThumb())
785 Builder.defineMacro(
"__ARM_ARCH_ISA_THUMB",
"1");
789 Builder.defineMacro(
"__ARM_32BIT_STATE",
"1");
794 if (!CPUProfile.empty())
795 Builder.defineMacro(
"__ARM_ARCH_PROFILE",
"'" + CPUProfile +
"'");
799 Builder.defineMacro(
"__ARM_FEATURE_UNALIGNED",
"1");
803 Builder.defineMacro(
"__ARM_FEATURE_LDREX",
"0x" + Twine::utohexstr(LDREX));
806 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile !=
"M") ||
808 Builder.defineMacro(
"__ARM_FEATURE_CLZ",
"1");
812 Builder.defineMacro(
"__ARM_FP",
"0x" + Twine::utohexstr(HW_FP));
815 Builder.defineMacro(
"__ARM_ACLE",
"200");
818 Builder.defineMacro(
"__ARM_FP16_FORMAT_IEEE",
"1");
819 Builder.defineMacro(
"__ARM_FP16_ARGS",
"1");
822 if (ArchVersion >= 7 && (FPU & VFP4FPU))
823 Builder.defineMacro(
"__ARM_FEATURE_FMA",
"1");
830 if (5 <= ArchVersion && ArchVersion <= 8 && !
getTriple().isOSWindows())
831 Builder.defineMacro(
"__THUMB_INTERWORK__");
833 if (ABI ==
"aapcs" || ABI ==
"aapcs-linux" || ABI ==
"aapcs-vfp") {
837 Builder.defineMacro(
"__ARM_EABI__");
838 Builder.defineMacro(
"__ARM_PCS",
"1");
841 if ((!SoftFloat && !SoftFloatABI) || ABI ==
"aapcs-vfp" || ABI ==
"aapcs16")
842 Builder.defineMacro(
"__ARM_PCS_VFP",
"1");
844 if (SoftFloat || (SoftFloatABI && !FPU))
845 Builder.defineMacro(
"__SOFTFP__");
849 Builder.defineMacro(
"__ARM_ROPI",
"1");
851 Builder.defineMacro(
"__ARM_RWPI",
"1");
854 uint64_t FeatureCoprocBF = 0;
858 case llvm::ARM::ArchKind::ARMV4:
859 case llvm::ARM::ArchKind::ARMV4T:
861 FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;
863 case llvm::ARM::ArchKind::ARMV5T:
864 FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;
866 case llvm::ARM::ArchKind::ARMV5TE:
867 case llvm::ARM::ArchKind::ARMV5TEJ:
870 FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;
872 case llvm::ARM::ArchKind::ARMV6:
873 case llvm::ARM::ArchKind::ARMV6K:
874 case llvm::ARM::ArchKind::ARMV6KZ:
875 case llvm::ARM::ArchKind::ARMV6T2:
876 if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)
877 FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
878 FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
880 case llvm::ARM::ArchKind::ARMV7A:
881 case llvm::ARM::ArchKind::ARMV7R:
882 case llvm::ARM::ArchKind::ARMV7M:
883 case llvm::ARM::ArchKind::ARMV7S:
884 case llvm::ARM::ArchKind::ARMV7EM:
885 FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
886 FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
888 case llvm::ARM::ArchKind::ARMV8A:
889 case llvm::ARM::ArchKind::ARMV8R:
890 case llvm::ARM::ArchKind::ARMV8_1A:
891 case llvm::ARM::ArchKind::ARMV8_2A:
892 case llvm::ARM::ArchKind::ARMV8_3A:
893 case llvm::ARM::ArchKind::ARMV8_4A:
894 case llvm::ARM::ArchKind::ARMV8_5A:
895 case llvm::ARM::ArchKind::ARMV8_6A:
896 case llvm::ARM::ArchKind::ARMV8_7A:
897 case llvm::ARM::ArchKind::ARMV8_8A:
898 case llvm::ARM::ArchKind::ARMV8_9A:
899 case llvm::ARM::ArchKind::ARMV9A:
900 case llvm::ARM::ArchKind::ARMV9_1A:
901 case llvm::ARM::ArchKind::ARMV9_2A:
902 case llvm::ARM::ArchKind::ARMV9_3A:
903 case llvm::ARM::ArchKind::ARMV9_4A:
904 case llvm::ARM::ArchKind::ARMV9_5A:
905 case llvm::ARM::ArchKind::ARMV9_6A:
907 FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
909 case llvm::ARM::ArchKind::ARMV8MMainline:
910 case llvm::ARM::ArchKind::ARMV8_1MMainline:
911 FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
912 FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
915 Builder.defineMacro(
"__ARM_FEATURE_COPROC",
916 "0x" + Twine::utohexstr(FeatureCoprocBF));
918 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
919 Builder.defineMacro(
"__XSCALE__");
922 Builder.defineMacro(
"__THUMBEL__");
923 Builder.defineMacro(
"__thumb__");
924 if (supportsThumb2())
925 Builder.defineMacro(
"__thumb2__");
929 if ((CPUProfile !=
"M" && ArchVersion >= 6) || (CPUProfile ==
"M" && DSP))
930 Builder.defineMacro(
"__ARM_FEATURE_SIMD32",
"1");
933 if (((HWDiv & HWDivThumb) && isThumb()) ||
934 ((HWDiv & HWDivARM) && !isThumb())) {
935 Builder.defineMacro(
"__ARM_FEATURE_IDIV",
"1");
936 Builder.defineMacro(
"__ARM_ARCH_EXT_IDIV__",
"1");
940 Builder.defineMacro(
"__APCS_32__");
945 Builder.defineMacro(
"__VFP_FP__");
947 if (FPUModeIsVFP((FPUMode)FPU)) {
949 Builder.defineMacro(
"__ARM_VFPV2__");
951 Builder.defineMacro(
"__ARM_VFPV3__");
953 Builder.defineMacro(
"__ARM_VFPV4__");
955 Builder.defineMacro(
"__ARM_FPV5__");
962 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
963 Builder.defineMacro(
"__ARM_NEON",
"1");
964 Builder.defineMacro(
"__ARM_NEON__");
967 Builder.defineMacro(
"__ARM_NEON_FP",
968 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
972 Builder.defineMacro(
"__ARM_FEATURE_MVE", hasMVEFloat() ?
"3" :
"1");
976 Builder.defineMacro(
"__ARM_FEATURE_CDE",
"1");
977 Builder.defineMacro(
"__ARM_FEATURE_CDE_COPROC",
981 Builder.defineMacro(
"__ARM_SIZEOF_WCHAR_T",
982 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
984 Builder.defineMacro(
"__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ?
"1" :
"4");
987 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
988 Builder.defineMacro(
"__ARM_FEATURE_CMSE", Opts.Cmse ?
"3" :
"1");
990 if (ArchVersion >= 6 && CPUAttr !=
"6M" && CPUAttr !=
"8M_BASE") {
991 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
992 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
993 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
994 Builder.defineMacro(
"__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
999 Builder.defineMacro(
"__ARM_FEATURE_DSP",
"1");
1004 if ((ArchVersion == 6 && CPUProfile !=
"M") || ArchVersion > 6) {
1005 Builder.defineMacro(
"__ARM_FEATURE_SAT",
"1");
1011 Builder.defineMacro(
"__ARM_FEATURE_QBIT",
"1");
1013 if (Opts.UnsafeFPMath)
1014 Builder.defineMacro(
"__ARM_FP_FAST",
"1");
1018 Builder.defineMacro(
"__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
"1");
1022 Builder.defineMacro(
"__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
"1");
1026 Builder.defineMacro(
"__ARM_FEATURE_DOTPROD",
"1");
1029 Builder.defineMacro(
"__ARM_FEATURE_MATMUL_INT8",
"1");
1032 Builder.defineMacro(
"__ARM_FEATURE_PAUTH",
"1");
1035 Builder.defineMacro(
"__ARM_FEATURE_BTI",
"1");
1038 Builder.defineMacro(
"__ARM_FEATURE_BF16",
"1");
1039 Builder.defineMacro(
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC",
"1");
1040 Builder.defineMacro(
"__ARM_BF16_FORMAT_ALTERNATIVE",
"1");
1043 if (Opts.BranchTargetEnforcement)
1044 Builder.defineMacro(
"__ARM_FEATURE_BTI_DEFAULT",
"1");
1050 Builder.defineMacro(
"__ARM_FEATURE_PAC_DEFAULT", Twine(
Value));
1056 case llvm::ARM::ArchKind::ARMV8_1A:
1059 case llvm::ARM::ArchKind::ARMV8_2A:
1062 case llvm::ARM::ArchKind::ARMV8_3A:
1063 case llvm::ARM::ArchKind::ARMV8_4A:
1064 case llvm::ARM::ArchKind::ARMV8_5A:
1065 case llvm::ARM::ArchKind::ARMV8_6A:
1066 case llvm::ARM::ArchKind::ARMV8_7A:
1067 case llvm::ARM::ArchKind::ARMV8_8A:
1068 case llvm::ARM::ArchKind::ARMV8_9A:
1069 case llvm::ARM::ArchKind::ARMV9A:
1070 case llvm::ARM::ArchKind::ARMV9_1A:
1071 case llvm::ARM::ArchKind::ARMV9_2A:
1072 case llvm::ARM::ArchKind::ARMV9_3A:
1073 case llvm::ARM::ArchKind::ARMV9_4A:
1074 case llvm::ARM::ArchKind::ARMV9_5A:
1075 case llvm::ARM::ArchKind::ARMV9_6A:
1097#define GET_NEON_BUILTIN_STR_TABLE
1098#include "clang/Basic/arm_neon.inc"
1099#undef GET_NEON_BUILTIN_STR_TABLE
1101static constexpr std::array<Builtin::Info, NumNeonBuiltins>
BuiltinInfos = {
1102#define GET_NEON_BUILTIN_INFOS
1103#include "clang/Basic/arm_neon.inc"
1104#undef GET_NEON_BUILTIN_INFOS
1108#define GET_NEON_BUILTIN_STR_TABLE
1109#include "clang/Basic/arm_fp16.inc"
1110#undef GET_NEON_BUILTIN_STR_TABLE
1112static constexpr std::array<Builtin::Info, NumFp16Builtins>
BuiltinInfos = {
1113#define GET_NEON_BUILTIN_INFOS
1114#include "clang/Basic/arm_fp16.inc"
1115#undef GET_NEON_BUILTIN_INFOS
1123#define GET_MVE_BUILTIN_STR_TABLE
1124#include "clang/Basic/arm_mve_builtins.inc"
1125#undef GET_MVE_BUILTIN_STR_TABLE
1127static constexpr std::array<Builtin::Info, NumMVEBuiltins>
BuiltinInfos = {
1128#define GET_MVE_BUILTIN_INFOS
1129#include "clang/Basic/arm_mve_builtins.inc"
1130#undef GET_MVE_BUILTIN_INFOS
1135#define GET_CDE_BUILTIN_STR_TABLE
1136#include "clang/Basic/arm_cde_builtins.inc"
1137#undef GET_CDE_BUILTIN_STR_TABLE
1139static constexpr std::array<Builtin::Info, NumCDEBuiltins>
BuiltinInfos = {
1140#define GET_CDE_BUILTIN_INFOS
1141#include "clang/Basic/arm_cde_builtins.inc"
1142#undef GET_CDE_BUILTIN_INFOS
1149#define BUILTIN CLANG_BUILTIN_STR_TABLE
1150#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE
1151#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE
1152#include "clang/Basic/BuiltinsARM.def"
1156#define BUILTIN CLANG_BUILTIN_ENTRY
1157#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
1158#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
1159#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY
1160#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY
1161#include "clang/Basic/BuiltinsARM.def"
1170 {&MVE::BuiltinStrings, MVE::BuiltinInfos,
"__builtin_arm_mve_"},
1171 {&CDE::BuiltinStrings, CDE::BuiltinInfos,
"__builtin_arm_cde_"},
1184const char *
const ARMTargetInfo::GCCRegNames[] = {
1186 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
1187 "r12",
"sp",
"lr",
"pc",
1190 "s0",
"s1",
"s2",
"s3",
"s4",
"s5",
"s6",
"s7",
"s8",
"s9",
"s10",
"s11",
1191 "s12",
"s13",
"s14",
"s15",
"s16",
"s17",
"s18",
"s19",
"s20",
"s21",
"s22",
1192 "s23",
"s24",
"s25",
"s26",
"s27",
"s28",
"s29",
"s30",
"s31",
1195 "d0",
"d1",
"d2",
"d3",
"d4",
"d5",
"d6",
"d7",
"d8",
"d9",
"d10",
"d11",
1196 "d12",
"d13",
"d14",
"d15",
"d16",
"d17",
"d18",
"d19",
"d20",
"d21",
"d22",
1197 "d23",
"d24",
"d25",
"d26",
"d27",
"d28",
"d29",
"d30",
"d31",
1200 "q0",
"q1",
"q2",
"q3",
"q4",
"q5",
"q6",
"q7",
"q8",
"q9",
"q10",
"q11",
1201 "q12",
"q13",
"q14",
"q15"};
1208 {{
"a1"},
"r0"}, {{
"a2"},
"r1"}, {{
"a3"},
"r2"}, {{
"a4"},
"r3"},
1209 {{
"v1"},
"r4"}, {{
"v2"},
"r5"}, {{
"v3"},
"r6"}, {{
"v4"},
"r7"},
1210 {{
"v5"},
"r8"}, {{
"v6",
"rfp"},
"r9"}, {{
"sl"},
"r10"}, {{
"fp"},
"r11"},
1211 {{
"ip"},
"r12"}, {{
"r13"},
"sp"}, {{
"r14"},
"lr"}, {{
"r15"},
"pc"},
1245 if (CPUAttr ==
"6T2" || ArchVersion >= 7) {
1252 if (!supportsThumb2())
1264 if (isThumb() && !supportsThumb2())
1271 if (!supportsThumb2())
1286 if (!supportsThumb2())
1298 if (isThumb() && !supportsThumb2())
1309 if (isThumb() && !supportsThumb2()) {
1316 if (isThumb() && !supportsThumb2()) {
1359 switch (*Constraint) {
1362 R = std::string(
"^") + std::string(Constraint, 2);
1366 R = std::string(
"r");
1369 return std::string(1, *Constraint);
1375 StringRef Constraint,
char Modifier,
unsigned Size,
1376 std::string &SuggestedModifier)
const {
1377 bool isOutput = (Constraint[0] ==
'=');
1378 bool isInOut = (Constraint[0] ==
'+');
1381 Constraint = Constraint.ltrim(
"=+&");
1383 switch (Constraint[0]) {
1389 return (isInOut || isOutput || Size <= 64);
1434 Builder.defineMacro(
"__ARMEL__");
1444 Builder.defineMacro(
"__ARMEB__");
1445 Builder.defineMacro(
"__ARM_BIG_ENDIAN");
1457 Builder.defineMacro(
"_M_ARM_NT",
"1");
1458 Builder.defineMacro(
"_M_ARMT",
"_M_ARM");
1459 Builder.defineMacro(
"_M_THUMB",
"_M_ARM");
1461 assert((Triple.getArch() == llvm::Triple::arm ||
1462 Triple.getArch() == llvm::Triple::thumb) &&
1463 "invalid architecture for Windows ARM target info");
1464 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1465 Builder.defineMacro(
"_M_ARM", Triple.getArchName().substr(Offset));
1469 Builder.defineMacro(
"_M_ARM_FP",
"31");
1493 return CCCR_Warning;
1501 TheCXXABI.set(TargetCXXABI::GenericARM);
1508 if (Opts.MSVCCompat)
1516 TheCXXABI.set(TargetCXXABI::Microsoft);
1528 TheCXXABI.set(TargetCXXABI::GenericARM);
1534 Builder.defineMacro(
"_ARM_");
1543 resetDataLayout(
"e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1549 Builder.defineMacro(
"_ARM_");
1550 Builder.defineMacro(
"__CYGWIN__");
1551 Builder.defineMacro(
"__CYGWIN32__");
1554 Builder.defineMacro(
"_GNU_SOURCE");
1562 const llvm::Triple &Triple,
1570 HasAlignMac68kSupport =
true;
1571 if (Triple.isWatchABI()) {
1573 TheCXXABI.set(TargetCXXABI::WatchOS);
1576 UseSignedCharForObjCBool =
false;
1578 TheCXXABI.set(TargetCXXABI::iOS);
1582 const llvm::Triple &Triple,
Defines the Diagnostic-related interfaces.
static constexpr int NumFp16Builtins
static constexpr int NumNeonBuiltins
static constexpr llvm::StringTable BuiltinStrings
static constexpr int NumARMBuiltins
static constexpr int NumMVEBuiltins
static constexpr int NumCDEBuiltins
static constexpr Builtin::Info BuiltinInfos[]
Defines enum values for all the target-independent builtin functions.
#define CLANG_BUILTIN_STR_TABLE_START
Enumerates target-specific builtins in their own namespaces within namespace clang.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
@ None
No signing for any function.
@ NonLeaf
Sign the return address of functions that spill LR.
@ All
Sign the return address of all functions,.
@ 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 hasSignReturnAddress() const
Check if return address signing is enabled.
bool isSignReturnAddressScopeAll() const
Check if leaf functions are also signed.
LangOptions::SignReturnAddressScopeKind SignReturnAddr
LangOptions::SignReturnAddressKeyKind SignKey
bool BranchProtectionPAuthLR
bool BranchTargetEnforcement
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
@ AAPCSABIBuiltinVaList
__builtin_va_list as defined by ARM AAPCS ABI http://infocenter.arm.com
@ CharPtrBuiltinVaList
typedef char* __builtin_va_list;
@ VoidPtrBuiltinVaList
typedef void* __builtin_va_list;
@ ARM_LDREX_W
half (16-bit)
@ ARM_LDREX_H
byte (8-bit)
@ ARM_LDREX_D
word (32-bit)
unsigned HasUnalignedAccess
unsigned char MaxAtomicPromoteWidth
uint32_t getARMCDECoprocMask() const
For ARM targets returns a mask defining which coprocessors are configured as Custom Datapath.
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 ...
unsigned char MaxAtomicInlineWidth
unsigned ARMCDECoprocMask
Options for controlling the target.
llvm::EABI EABIVersion
The EABI version to use.
std::vector< std::string > FeaturesAsWritten
The list of target specific features to enable or disable, as written on the command line.
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
llvm::SmallVector< Builtin::InfosShard > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
void getTargetDefinesARMV83A(const LangOptions &Opts, MacroBuilder &Builder) const
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
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 ...
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
bool setABI(const std::string &Name) override
Use the specified ABI.
StringRef getABI() const override
Get the ABI currently in use.
bool setCPU(const std::string &Name) override
Target the specified CPU.
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const override
Determine if this TargetInfo supports the given branch protection specification.
void getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const
bool validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size, std::string &SuggestedModifier) const override
ArrayRef< const char * > getGCCRegNames() const override
bool setFPMath(StringRef Name) override
Use the specified unit for FP math.
std::string convertConstraint(const char *&Constraint) const override
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
void getTargetDefinesARMV82A(const LangOptions &Opts, MacroBuilder &Builder) const
ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
bool hasSjLjLowering() const override
Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....
void fillValidCPUList(SmallVectorImpl< StringRef > &Values) const override
Fill a SmallVectorImpl with the valid values to setCPU.
int getEHDataRegisterNumber(unsigned RegNo) const override
Return the register number that __builtin_eh_return_regno would return with the specified argument.
bool hasBFloat16Type() const override
Determine whether the _BFloat16 type is supported on this target.
bool isCLZForZeroUndef() const override
The __builtin_clz* and __builtin_ctz* built-in functions are specified to have undefined results for ...
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
bool isBranchProtectionSupportedArch(StringRef Arch) const override
Determine if the Architecture in this TargetInfo supports branch protection.
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
AppleMachOARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
MicrosoftARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
BuiltinVaListKind getBuiltinVaListKind() const override
void getVisualStudioDefines(const LangOptions &Opts, MacroBuilder &Builder) const
WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
static constexpr std::array< Builtin::Info, NumFp16Builtins > BuiltinInfos
static constexpr std::array< Builtin::Info, NumNeonBuiltins > BuiltinInfos
static constexpr int NumBuiltins
void getAppleMachODefines(MacroBuilder &Builder, const LangOptions &Opts, const llvm::Triple &Triple)
LLVM_LIBRARY_VISIBILITY void DefineStd(clang::MacroBuilder &Builder, llvm::StringRef MacroName, const clang::LangOptions &Opts)
Define a macro name and standard variants.
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.
const FunctionProtoType * T
CallingConv
CallingConv - Specifies the calling convention that a function uses.
void setRequiresImmediate(int Min, int Max)
unsigned UseZeroLengthBitfieldAlignment
Whether zero length bitfields (e.g., int : 0;) force alignment of the next bitfield.
unsigned short SuitableAlign
unsigned ZeroLengthBitfieldBoundary
If non-zero, specifies a fixed alignment value for bitfields that follow zero length bitfield,...
unsigned char LongLongAlign
unsigned UseBitFieldTypeAlignment
Control whether the alignment of bit-field types is respected when laying out structures.
unsigned char BFloat16Width
unsigned char LongDoubleAlign
unsigned char BFloat16Align
unsigned char DoubleAlign
const llvm::fltSemantics * BFloat16Format
unsigned char DefaultAlignForAttributeAligned