diff --git a/llvm/include/llvm/Support/RISCVISAInfo.h b/llvm/include/llvm/Support/RISCVISAInfo.h --- a/llvm/include/llvm/Support/RISCVISAInfo.h +++ b/llvm/include/llvm/Support/RISCVISAInfo.h @@ -85,10 +85,12 @@ static bool isSupportedExtensionFeature(StringRef Ext); static bool isSupportedExtension(StringRef Ext); + static bool isSupportedExtensionWithVersion(StringRef Ext); static bool isSupportedExtension(StringRef Ext, unsigned MajorVersion, unsigned MinorVersion); static llvm::Expected> postProcessAndChecking(std::unique_ptr &&ISAInfo); + static std::string getTargetFeatureFromOneExt(StringRef Ext); private: RISCVISAInfo(unsigned XLen) diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -1192,3 +1192,41 @@ } llvm_unreachable("Invalid XLEN"); } + +bool RISCVISAInfo::isSupportedExtensionWithVersion(StringRef Ext) { + if (Ext.empty()) + return false; + + auto Pos = findLastNonVersionCharacter(Ext) + 1; + StringRef Name = Ext.substr(0, Pos); + StringRef Vers = Ext.substr(Pos); + if (Vers.empty()) + return false; + + unsigned Major, Minor, ConsumeLength; + if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength, + true, true)) { + consumeError(std::move(E)); + return false; + } + + return true; +} + +std::string RISCVISAInfo::getTargetFeatureFromOneExt(StringRef Ext) { + if (Ext.empty()) + return std::string(); + + auto Pos = findLastNonVersionCharacter(Ext) + 1; + StringRef Name = Ext.substr(0, Pos); + StringRef Vers = Ext.substr(Pos); + + if (!Vers.empty() && !isSupportedExtensionWithVersion(Ext)) + return std::string(); + + if (!isSupportedExtension(Name)) + return std::string(); + + return isExperimentalExtension(Name) ? "experimental-" + Name.str() + : Name.str(); +} diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -485,3 +485,24 @@ ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); } + +TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0"), true); + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion("zbb"), false); + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0"), false); + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo"), false); + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion(""), false); + EXPECT_EQ(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0"), false); +} + +TEST(getTargetFeatureFromOneExt, RetrieveTargetFeatureFromOneExt) { + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zbb"), "zbb"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zihintntl0p2"), + "experimental-zihintntl"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zihintntl"), + "experimental-zihintntl"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zihintntl1234p4321"), ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zfoo"), ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt(""), ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureFromOneExt("zbbzihintntl"), ""); +}