aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp247
1 files changed, 216 insertions, 31 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
index 0e4048f8d5ff..e55feedbd5c6 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/TargetParser/ARMTargetParser.h"
using namespace clang;
using namespace clang::targets;
@@ -172,8 +173,7 @@ bool ARMTargetInfo::supportsThumb() const {
}
bool ARMTargetInfo::supportsThumb2() const {
- return CPUAttr.equals("6T2") ||
- (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
+ return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE");
}
StringRef ARMTargetInfo::getCPUAttr() const {
@@ -212,6 +212,22 @@ StringRef ARMTargetInfo::getCPUAttr() const {
return "8_6A";
case llvm::ARM::ArchKind::ARMV8_7A:
return "8_7A";
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ return "8_8A";
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ return "8_9A";
+ case llvm::ARM::ArchKind::ARMV9A:
+ return "9A";
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ return "9_1A";
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ return "9_2A";
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ return "9_3A";
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ return "9_4A";
+ case llvm::ARM::ArchKind::ARMV9_5A:
+ return "9_5A";
case llvm::ARM::ArchKind::ARMV8MBaseline:
return "8M_BASE";
case llvm::ARM::ArchKind::ARMV8MMainline:
@@ -240,8 +256,11 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
HW_FP(0) {
+ bool IsFreeBSD = Triple.isOSFreeBSD();
bool IsOpenBSD = Triple.isOSOpenBSD();
bool IsNetBSD = Triple.isOSNetBSD();
+ bool IsHaiku = Triple.isOSHaiku();
+ bool IsOHOS = Triple.isOHOSFamily();
// FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
// environment where size_t is `unsigned long` rather than `unsigned int`
@@ -292,9 +311,12 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
switch (Triple.getEnvironment()) {
case llvm::Triple::Android:
case llvm::Triple::GNUEABI:
+ case llvm::Triple::GNUEABIT64:
case llvm::Triple::GNUEABIHF:
+ case llvm::Triple::GNUEABIHFT64:
case llvm::Triple::MuslEABI:
case llvm::Triple::MuslEABIHF:
+ case llvm::Triple::OpenHOS:
setABI("aapcs-linux");
break;
case llvm::Triple::EABIHF:
@@ -307,7 +329,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
default:
if (IsNetBSD)
setABI("apcs-gnu");
- else if (IsOpenBSD)
+ else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS)
setABI("aapcs-linux");
else
setABI("aapcs");
@@ -361,6 +383,50 @@ bool ARMTargetInfo::setABI(const std::string &Name) {
return false;
}
+bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
+ llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
+
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ return false;
+
+ StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
+ auto a =
+ llvm::Triple(ArchFeature, getTriple().getVendorName(),
+ getTriple().getOSName(), getTriple().getEnvironmentName());
+
+ StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
+ llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
+ return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
+}
+
+bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const {
+ llvm::ARM::ParsedBranchProtection PBP;
+ if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
+ return false;
+
+ if (!isBranchProtectionSupportedArch(Arch))
+ return false;
+
+ BPI.SignReturnAddr =
+ llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
+ .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
+ .Case("all", LangOptions::SignReturnAddressScopeKind::All)
+ .Default(LangOptions::SignReturnAddressScopeKind::None);
+
+ // Don't care for the sign key, beyond issuing a warning.
+ if (PBP.Key == "b_key")
+ Err = "b-key";
+ BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
+
+ BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
+ BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
+ return true;
+}
+
// FIXME: This should be based on Arch attributes, not CPU names.
bool ARMTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
@@ -378,10 +444,23 @@ bool ARMTargetInfo::initFeatureMap(
if (CPUArch != llvm::ARM::ArchKind::INVALID) {
ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
TargetFeatures.push_back(ArchFeature);
+
+ // These features are added to allow arm_neon.h target(..) attributes to
+ // match with both arm and aarch64. We need to add all previous architecture
+ // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
+ // v8.x counterparts are added too. We only need these for anything > 8.0-A.
+ for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
+ I != llvm::ARM::ArchKind::INVALID; --I)
+ Features[llvm::ARM::getSubArch(I)] = true;
+ if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
+ CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
+ for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
+ --I)
+ Features[llvm::ARM::getSubArch(I)] = true;
}
// get default FPU features
- unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
+ llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
// get default Extension features
@@ -431,15 +510,19 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
SHA2 = 0;
AES = 0;
DSP = 0;
- Unaligned = 1;
+ HasUnalignedAccess = true;
SoftFloat = false;
// Note that SoftFloatABI is initialized in our constructor.
HWDiv = 0;
DotProd = 0;
HasMatMul = 0;
+ HasPAC = 0;
+ HasBTI = 0;
HasFloat16 = true;
ARMCDECoprocMask = 0;
HasBFloat16 = false;
+ HasFullBFloat16 = false;
+ FPRegsDisabled = false;
// This does not diagnose illegal cases like having both
// "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
@@ -494,7 +577,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return false;
}
} else if (Feature == "+strict-align") {
- Unaligned = 0;
+ HasUnalignedAccess = false;
} else if (Feature == "+fp16") {
HW_FP |= HW_FP_HP;
} else if (Feature == "+fullfp16") {
@@ -516,9 +599,18 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
ARMCDECoprocMask |= (1U << Coproc);
} else if (Feature == "+bf16") {
HasBFloat16 = true;
+ } else if (Feature == "-fpregs") {
+ FPRegsDisabled = true;
+ } else if (Feature == "+pacbti") {
+ HasPAC = 1;
+ HasBTI = 1;
+ } else if (Feature == "+fullbf16") {
+ HasFullBFloat16 = true;
}
}
+ HalfArgsAndReturns = true;
+
switch (ArchVersion) {
case 6:
if (ArchProfile == llvm::ARM::ProfileKind::M)
@@ -535,6 +627,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
break;
case 8:
+ case 9:
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
}
@@ -566,7 +659,8 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const {
}
bool ARMTargetInfo::hasBFloat16Type() const {
- return HasBFloat16 && !SoftFloat;
+ // The __bf16 type is generally available so long as we have any fp registers.
+ return HasBFloat16 || (FPU && !SoftFloat);
}
bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
@@ -627,8 +721,10 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
// For bare-metal none-eabi.
if (getTriple().getOS() == llvm::Triple::UnknownOS &&
(getTriple().getEnvironment() == llvm::Triple::EABI ||
- getTriple().getEnvironment() == llvm::Triple::EABIHF))
- Builder.defineMacro("__ELF__");
+ getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
+ Opts.CPlusPlus) {
+ Builder.defineMacro("_GNU_SOURCE");
+ }
// Target properties.
Builder.defineMacro("__REGISTER_PREFIX__", "");
@@ -690,7 +786,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
// ACLE 6.4.3 Unaligned access supported in hardware
- if (Unaligned)
+ if (HasUnalignedAccess)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
// ACLE 6.4.4 LDREX/STREX
@@ -736,7 +832,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
Builder.defineMacro("__ARM_PCS_VFP", "1");
- if (SoftFloat)
+ if (SoftFloat || (SoftFloatABI && !FPU))
Builder.defineMacro("__SOFTFP__");
// ACLE position independent code macros.
@@ -745,6 +841,70 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.RWPI)
Builder.defineMacro("__ARM_RWPI", "1");
+ // Macros for enabling co-proc intrinsics
+ uint64_t FeatureCoprocBF = 0;
+ switch (ArchKind) {
+ default:
+ break;
+ case llvm::ARM::ArchKind::ARMV4:
+ case llvm::ARM::ArchKind::ARMV4T:
+ // Filter __arm_ldcl and __arm_stcl in acle.h
+ FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;
+ break;
+ case llvm::ARM::ArchKind::ARMV5T:
+ FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;
+ break;
+ case llvm::ARM::ArchKind::ARMV5TE:
+ case llvm::ARM::ArchKind::ARMV5TEJ:
+ if (!isThumb())
+ FeatureCoprocBF =
+ FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;
+ break;
+ case llvm::ARM::ArchKind::ARMV6:
+ case llvm::ARM::ArchKind::ARMV6K:
+ case llvm::ARM::ArchKind::ARMV6KZ:
+ case llvm::ARM::ArchKind::ARMV6T2:
+ if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ case llvm::ARM::ArchKind::ARMV7A:
+ case llvm::ARM::ArchKind::ARMV7R:
+ case llvm::ARM::ArchKind::ARMV7M:
+ case llvm::ARM::ArchKind::ARMV7S:
+ case llvm::ARM::ArchKind::ARMV7EM:
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ case llvm::ARM::ArchKind::ARMV8A:
+ case llvm::ARM::ArchKind::ARMV8R:
+ case llvm::ARM::ArchKind::ARMV8_1A:
+ case llvm::ARM::ArchKind::ARMV8_2A:
+ case llvm::ARM::ArchKind::ARMV8_3A:
+ case llvm::ARM::ArchKind::ARMV8_4A:
+ case llvm::ARM::ArchKind::ARMV8_5A:
+ case llvm::ARM::ArchKind::ARMV8_6A:
+ case llvm::ARM::ArchKind::ARMV8_7A:
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ case llvm::ARM::ArchKind::ARMV9A:
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
+ // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
+ break;
+ case llvm::ARM::ArchKind::ARMV8MMainline:
+ case llvm::ARM::ArchKind::ARMV8_1MMainline:
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ }
+ Builder.defineMacro("__ARM_FEATURE_COPROC",
+ "0x" + Twine::utohexstr(FeatureCoprocBF));
+
if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Builder.defineMacro("__XSCALE__");
@@ -858,12 +1018,28 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasMatMul)
Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
+ if (HasPAC)
+ Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
+
+ if (HasBTI)
+ Builder.defineMacro("__ARM_FEATURE_BTI", "1");
+
if (HasBFloat16) {
Builder.defineMacro("__ARM_FEATURE_BF16", "1");
Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
}
+ if (Opts.BranchTargetEnforcement)
+ Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
+
+ if (Opts.hasSignReturnAddress()) {
+ unsigned Value = 1;
+ if (Opts.isSignReturnAddressScopeAll())
+ Value |= 1 << 2;
+ Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
+ }
+
switch (ArchKind) {
default:
break;
@@ -877,32 +1053,45 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
case llvm::ARM::ArchKind::ARMV8_4A:
case llvm::ARM::ArchKind::ARMV8_5A:
case llvm::ARM::ArchKind::ARMV8_6A:
+ case llvm::ARM::ArchKind::ARMV8_7A:
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ case llvm::ARM::ArchKind::ARMV9A:
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
getTargetDefinesARMV83A(Opts, Builder);
break;
}
}
-const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsNEON.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
- {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/BuiltinsARM.def"
};
ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
@@ -933,7 +1122,7 @@ const char *const ARMTargetInfo::GCCRegNames[] = {
"q12", "q13", "q14", "q15"};
ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
@@ -946,7 +1135,7 @@ const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool ARMTargetInfo::validateAsmConstraint(
@@ -968,11 +1157,13 @@ bool ARMTargetInfo::validateAsmConstraint(
case 't': // s0-s31, d0-d31, or q0-q15
case 'w': // s0-s15, d0-d7, or q0-q3
case 'x': // s0-s31, d0-d15, or q0-q7
+ if (FPRegsDisabled)
+ return false;
Info.setAllowsRegister();
return true;
case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
// only available in ARMv6T2 and above
- if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
+ if (CPUAttr == "6T2" || ArchVersion >= 7) {
Info.setRequiresImmediate(0, 65535);
return true;
}
@@ -1108,8 +1299,7 @@ bool ARMTargetInfo::validateConstraintModifier(
bool isInOut = (Constraint[0] == '+');
// Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
+ Constraint = Constraint.ltrim("=+&");
switch (Constraint[0]) {
default:
@@ -1127,7 +1317,7 @@ bool ARMTargetInfo::validateConstraintModifier(
return true;
}
-const char *ARMTargetInfo::getClobbers() const {
+std::string_view ARMTargetInfo::getClobbers() const {
// FIXME: Is this really right?
return "";
}
@@ -1289,11 +1479,6 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
HasAlignMac68kSupport = true;
- // iOS always has 64-bit atomic instructions.
- // FIXME: This should be based off of the target features in
- // ARMleTargetInfo.
- MaxAtomicInlineWidth = 64;
-
if (Triple.isWatchABI()) {
// Darwin on iOS uses a variant of the ARM C++ ABI.
TheCXXABI.set(TargetCXXABI::WatchOS);