[clang] [llvm] [clang-tools-extra] [RISCV] Relax march string order constraint (PR #78120)
Craig Topper via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 24 23:47:38 PST 2024
================
@@ -793,153 +887,69 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
Minor = Version->Minor;
}
- ISAInfo->addExtension(StringRef(&Baseline, 1), {Major, Minor});
+ // Postpone AddExtension until end of this function
+ SeenExtMap[StringRef(&Baseline, 1).str()] = {Major, Minor};
}
// Consume the base ISA version number and any '_' between rvxxx and the
// first extension
Exts = Exts.drop_front(ConsumeLength);
Exts.consume_front("_");
- auto StdExtsItr = StdExts.begin();
- auto StdExtsEnd = StdExts.end();
- auto GoToNextExt = [](StringRef::iterator &I, unsigned ConsumeLength,
- StringRef::iterator E) {
- I += 1 + ConsumeLength;
- if (I != E && *I == '_')
- ++I;
- };
- for (auto I = Exts.begin(), E = Exts.end(); I != E;) {
- char C = *I;
-
- // Check ISA extensions are specified in the canonical order.
- while (StdExtsItr != StdExtsEnd && *StdExtsItr != C)
- ++StdExtsItr;
-
- if (StdExtsItr == StdExtsEnd) {
- // Either c contains a valid extension but it was not given in
- // canonical order or it is an invalid extension.
- if (StdExts.contains(C)) {
- return createStringError(
- errc::invalid_argument,
- "standard user-level extension not given in canonical order '%c'",
- C);
- }
-
- return createStringError(errc::invalid_argument,
- "invalid standard user-level extension '%c'", C);
- }
-
- // Move to next char to prevent repeated letter.
- ++StdExtsItr;
-
- StringRef Next;
- unsigned Major, Minor, ConsumeLength;
- if (std::next(I) != E)
- Next = StringRef(std::next(I), E - std::next(I));
- if (auto E = getExtensionVersion(StringRef(&C, 1), Next, Major, Minor,
- ConsumeLength, EnableExperimentalExtension,
- ExperimentalExtensionVersionCheck)) {
- if (IgnoreUnknown) {
- consumeError(std::move(E));
- GoToNextExt(I, ConsumeLength, Exts.end());
- continue;
- }
- return std::move(E);
- }
-
- // The order is OK, then push it into features.
- // Currently LLVM supports only "mafdcvh".
- if (!isSupportedExtension(StringRef(&C, 1))) {
- if (IgnoreUnknown) {
- GoToNextExt(I, ConsumeLength, Exts.end());
- continue;
+ std::vector<std::string> SplitedExts;
+ if (auto E = splitExtsByUnderscore(Exts, SplitedExts))
+ return std::move(E);
+
+ for (auto Ext : SplitedExts) {
+ StringRef CurrExt = Ext;
+ while (!CurrExt.empty()) {
+ if (AllStdExts.contains(CurrExt.front())) {
+ if (auto E = processSingleLetterExtension(
+ CurrExt, SeenExtMap, IgnoreUnknown, EnableExperimentalExtension,
+ ExperimentalExtensionVersionCheck))
+ return E;
+ } else if (CurrExt.front() == 'z' || CurrExt.front() == 's' ||
+ CurrExt.front() == 'x') {
+ // Handle other types of extensions other than the standard
+ // general purpose and standard user-level extensions.
+ // Parse the ISA string containing non-standard user-level
+ // extensions, standard supervisor-level extensions and
+ // non-standard supervisor-level extensions.
+ // These extensions start with 'z', 's', 'x' prefixes, might have a
+ // version number (major, minor) and are separated by a single
+ // underscore '_'. We do not enforce a canonical order for them.
+ if (auto E = processMultiLetterExtension(
+ CurrExt, SeenExtMap, IgnoreUnknown, EnableExperimentalExtension,
+ ExperimentalExtensionVersionCheck))
+ return E;
+ // Multi-letter extension must be seperate following extension with
+ // underscore
+ break;
+ } else {
+ // FIXME: Could it be ignored by IgnoreUnknown?
+ return createStringError(errc::invalid_argument,
+ "invalid standard user-level extension '%c'",
+ CurrExt.front());
}
- return createStringError(errc::invalid_argument,
- "unsupported standard user-level extension '%c'",
- C);
}
- ISAInfo->addExtension(StringRef(&C, 1), {Major, Minor});
-
- // Consume full extension name and version, including any optional '_'
- // between this extension and the next
- GoToNextExt(I, ConsumeLength, Exts.end());
}
- // Handle other types of extensions other than the standard
- // general purpose and standard user-level extensions.
- // Parse the ISA string containing non-standard user-level
- // extensions, standard supervisor-level extensions and
- // non-standard supervisor-level extensions.
- // These extensions start with 'z', 's', 'x' prefixes, might have a version
- // number (major, minor) and are separated by a single underscore '_'. We do
- // not enforce a canonical order for them.
- // Set the hardware features for the extensions that are supported.
-
- // Multi-letter extensions are seperated by a single underscore
- // as described in RISC-V User-Level ISA V2.2.
- SmallVector<StringRef, 8> Split;
- OtherExts.split(Split, '_');
-
- SmallVector<StringRef, 8> AllExts;
- if (Split.size() > 1 || Split[0] != "") {
- for (StringRef Ext : Split) {
- if (Ext.empty())
- return createStringError(errc::invalid_argument,
- "extension name missing after separator '_'");
-
- StringRef Type = getExtensionType(Ext);
- StringRef Desc = getExtensionTypeDesc(Ext);
- auto Pos = findLastNonVersionCharacter(Ext) + 1;
- StringRef Name(Ext.substr(0, Pos));
- StringRef Vers(Ext.substr(Pos));
-
- if (Type.empty()) {
- if (IgnoreUnknown)
- continue;
- return createStringError(errc::invalid_argument,
- "invalid extension prefix '" + Ext + "'");
- }
-
- if (!IgnoreUnknown && Name.size() == Type.size()) {
- return createStringError(errc::invalid_argument,
- "%s name missing after '%s'",
- Desc.str().c_str(), Type.str().c_str());
- }
-
- unsigned Major, Minor, ConsumeLength;
- if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
- EnableExperimentalExtension,
- ExperimentalExtensionVersionCheck)) {
- if (IgnoreUnknown) {
- consumeError(std::move(E));
- continue;
- }
- return std::move(E);
- }
+ // Check all Extensions are supported.
+ for (auto SeenExtAndVers : SeenExtMap) {
----------------
topperc wrote:
`auto &SeenExtAndVers`
https://github.com/llvm/llvm-project/pull/78120
More information about the cfe-commits
mailing list