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 getTargetFeatureForExtension(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 @@ -1249,3 +1249,40 @@ } 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::getTargetFeatureForExtension(StringRef Ext) { + if (Ext.empty()) + return std::string(); + + auto Pos = findLastNonVersionCharacter(Ext) + 1; + StringRef Name = Ext.substr(0, Pos); + + if (Pos != Ext.size() && !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 @@ -604,3 +604,25 @@ EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U); EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U); } + +TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { + EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0")); +} + +TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) { + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zicond1p0"), + "experimental-zicond"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zicond"), + "experimental-zicond"); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"), + ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), ""); + EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), ""); +}