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 @@ -89,6 +89,7 @@ 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 @@ -300,19 +300,6 @@ return I != ExtInfo.end() && I->Name == Ext; } -bool RISCVISAInfo::isSupportedExtension(StringRef Ext) { - verifyTables(); - - for (auto ExtInfo : {ArrayRef(SupportedExtensions), - ArrayRef(SupportedExperimentalExtensions)}) { - auto I = llvm::lower_bound(ExtInfo, Ext, LessExtName()); - if (I != ExtInfo.end() && I->Name == Ext) - return true; - } - - return false; -} - bool RISCVISAInfo::isSupportedExtension(StringRef Ext, unsigned MajorVersion, unsigned MinorVersion) { for (auto ExtInfo : {ArrayRef(SupportedExtensions), @@ -547,6 +534,37 @@ return createStringError(errc::invalid_argument, Error); } +bool RISCVISAInfo::isSupportedExtension(StringRef Ext) { + verifyTables(); + + if (Ext.empty()) + return false; + + // With version + auto Pos = findLastNonVersionCharacter(Ext) + 1; + StringRef Name = Ext.substr(0, Pos); + StringRef Vers = Ext.substr(Pos); + if (!Vers.empty()) { + unsigned Major, Minor, ConsumeLength; + if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength, + true, true)) { + consumeError(std::move(E)); + return false; + } + return true; + } + + // Without version + for (auto ExtInfo : {ArrayRef(SupportedExtensions), + ArrayRef(SupportedExperimentalExtensions)}) { + auto I = llvm::lower_bound(ExtInfo, Ext, LessExtName()); + if (I != ExtInfo.end() && I->Name == Ext) + return true; + } + + return false; +} + llvm::Expected> RISCVISAInfo::parseFeatures(unsigned XLen, const std::vector &Features) { @@ -1219,3 +1237,14 @@ } llvm_unreachable("Invalid XLEN"); } + +std::string RISCVISAInfo::getTargetFeatureFromOneExt(StringRef Ext) { + if (!isSupportedExtension(Ext)) + return std::string(); + + auto Pos = findLastNonVersionCharacter(Ext) + 1; + StringRef Name = Ext.substr(0, Pos); + + 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 @@ -507,3 +507,24 @@ ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); } + +TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { + EXPECT_TRUE(RISCVISAInfo::isSupportedExtension("zbb1p0")); + EXPECT_TRUE(RISCVISAInfo::isSupportedExtension("zbb")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtension("zfoo1p0")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtension("zfoo")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtension("")); + EXPECT_FALSE(RISCVISAInfo::isSupportedExtension("c2p0zbb1p0")); +} + +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"), ""); +}