diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp | 247 |
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); |