================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits