aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp b/contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp
index 1b1bff023d2f..7cb1147d4265 100644
--- a/contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/RISCVISAInfo.cpp
@@ -503,6 +503,67 @@ RISCVISAInfo::parseFeatures(unsigned XLen,
}
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
+RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
+ if (llvm::any_of(Arch, isupper)) {
+ return createStringError(errc::invalid_argument,
+ "string must be lowercase");
+ }
+ // Must start with a valid base ISA name.
+ unsigned XLen;
+ if (Arch.startswith("rv32i") || Arch.startswith("rv32e"))
+ XLen = 32;
+ else if (Arch.startswith("rv64i") || Arch.startswith("rv64e"))
+ XLen = 64;
+ else
+ return createStringError(errc::invalid_argument,
+ "arch string must begin with valid base ISA");
+ std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
+ // Discard rv32/rv64 prefix.
+ Arch = Arch.substr(4);
+
+ // Each extension is of the form ${name}${major_version}p${minor_version}
+ // and separated by _. Split by _ and then extract the name and version
+ // information for each extension.
+ SmallVector<StringRef, 8> Split;
+ Arch.split(Split, '_');
+ for (StringRef Ext : Split) {
+ StringRef Prefix, MinorVersionStr;
+ std::tie(Prefix, MinorVersionStr) = Ext.rsplit('p');
+ if (MinorVersionStr.empty())
+ return createStringError(errc::invalid_argument,
+ "extension lacks version in expected format");
+ unsigned MajorVersion, MinorVersion;
+ if (MinorVersionStr.getAsInteger(10, MinorVersion))
+ return createStringError(errc::invalid_argument,
+ "failed to parse minor version number");
+
+ // Split Prefix into the extension name and the major version number
+ // (the trailing digits of Prefix).
+ int TrailingDigits = 0;
+ StringRef ExtName = Prefix;
+ while (!ExtName.empty()) {
+ if (!isDigit(ExtName.back()))
+ break;
+ ExtName = ExtName.drop_back(1);
+ TrailingDigits++;
+ }
+ if (!TrailingDigits)
+ return createStringError(errc::invalid_argument,
+ "extension lacks version in expected format");
+
+ StringRef MajorVersionStr = Prefix.take_back(TrailingDigits);
+ if (MajorVersionStr.getAsInteger(10, MajorVersion))
+ return createStringError(errc::invalid_argument,
+ "failed to parse major version number");
+ ISAInfo->addExtension(ExtName, MajorVersion, MinorVersion);
+ }
+ ISAInfo->updateFLen();
+ ISAInfo->updateMinVLen();
+ ISAInfo->updateMaxELen();
+ return std::move(ISAInfo);
+}
+
+llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
bool ExperimentalExtensionVersionCheck,
bool IgnoreUnknown) {
@@ -999,6 +1060,8 @@ std::vector<std::string> RISCVISAInfo::toFeatureVector() const {
std::string ExtName = Ext.first;
if (ExtName == "i") // i is not recognized in clang -cc1
continue;
+ if (!isSupportedExtension(ExtName))
+ continue;
std::string Feature = isExperimentalExtension(ExtName)
? "+experimental-" + ExtName
: "+" + ExtName;