//===-- RISCVISAInfo.cpp - RISC-V Arch String Parser ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/TargetParser/RISCVISAInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"

#include <array>
#include <atomic>
#include <optional>
#include <string>
#include <vector>

using namespace llvm;

namespace {

struct RISCVSupportedExtension {
  const char *Name;
  /// Supported version.
  RISCVISAUtils::ExtensionVersion Version;

  bool operator<(const RISCVSupportedExtension &RHS) const {
    return StringRef(Name) < StringRef(RHS.Name);
  }
};

struct RISCVProfile {
  StringLiteral Name;
  StringLiteral MArch;

  bool operator<(const RISCVProfile &RHS) const {
    return StringRef(Name) < StringRef(RHS.Name);
  }
};

} // end anonymous namespace

static const char *RISCVGImplications[] = {"i", "m", "a", "f", "d"};
static const char *RISCVGImplicationsZi[] = {"zicsr", "zifencei"};

#define GET_SUPPORTED_EXTENSIONS
#include "llvm/TargetParser/RISCVTargetParserDef.inc"

#define GET_SUPPORTED_PROFILES
#include "llvm/TargetParser/RISCVTargetParserDef.inc"

static void verifyTables() {
#ifndef NDEBUG
  static std::atomic<bool> TableChecked(false);
  if (!TableChecked.load(std::memory_order_relaxed)) {
    assert(llvm::is_sorted(SupportedExtensions) &&
           "Extensions are not sorted by name");
    assert(llvm::is_sorted(SupportedExperimentalExtensions) &&
           "Experimental extensions are not sorted by name");
    assert(llvm::is_sorted(SupportedProfiles) &&
           "Profiles are not sorted by name");
    assert(llvm::is_sorted(SupportedExperimentalProfiles) &&
           "Experimental profiles are not sorted by name");
    TableChecked.store(true, std::memory_order_relaxed);
  }
#endif
}

static void PrintExtension(StringRef Name, StringRef Version,
                           StringRef Description) {
  outs().indent(4);
  unsigned VersionWidth = Description.empty() ? 0 : 10;
  outs() << left_justify(Name, 21) << left_justify(Version, VersionWidth)
         << Description << "\n";
}

void RISCVISAInfo::printSupportedExtensions(StringMap<StringRef> &DescMap) {
  outs() << "All available -march extensions for RISC-V\n\n";
  PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));

  RISCVISAUtils::OrderedExtensionMap ExtMap;
  for (const auto &E : SupportedExtensions)
    ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
  for (const auto &E : ExtMap) {
    std::string Version =
        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
    PrintExtension(E.first, Version, DescMap[E.first]);
  }

  outs() << "\nExperimental extensions\n";
  ExtMap.clear();
  for (const auto &E : SupportedExperimentalExtensions)
    ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
  for (const auto &E : ExtMap) {
    std::string Version =
        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
    PrintExtension(E.first, Version, DescMap["experimental-" + E.first]);
  }

  outs() << "\nSupported Profiles\n";
  for (const auto &P : SupportedProfiles)
    outs().indent(4) << P.Name << "\n";

  outs() << "\nExperimental Profiles\n";
  for (const auto &P : SupportedExperimentalProfiles)
    outs().indent(4) << P.Name << "\n";

  outs() << "\nUse -march to specify the target's extension.\n"
            "For example, clang -march=rv32i_v1p0\n";
}

void RISCVISAInfo::printEnabledExtensions(
    bool IsRV64, std::set<StringRef> &EnabledFeatureNames,
    StringMap<StringRef> &DescMap) {
  outs() << "Extensions enabled for the given RISC-V target\n\n";
  PrintExtension("Name", "Version", (DescMap.empty() ? "" : "Description"));

  RISCVISAUtils::OrderedExtensionMap FullExtMap;
  RISCVISAUtils::OrderedExtensionMap ExtMap;
  for (const auto &E : SupportedExtensions)
    if (EnabledFeatureNames.count(E.Name) != 0) {
      FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
      ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
    }
  for (const auto &E : ExtMap) {
    std::string Version =
        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
    PrintExtension(E.first, Version, DescMap[E.first]);
  }

  outs() << "\nExperimental extensions\n";
  ExtMap.clear();
  for (const auto &E : SupportedExperimentalExtensions) {
    StringRef Name(E.Name);
    if (EnabledFeatureNames.count("experimental-" + Name.str()) != 0) {
      FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
      ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
    }
  }
  for (const auto &E : ExtMap) {
    std::string Version =
        std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor);
    PrintExtension(E.first, Version, DescMap["experimental-" + E.first]);
  }

  unsigned XLen = IsRV64 ? 64 : 32;
  if (auto ISAString = RISCVISAInfo::createFromExtMap(XLen, FullExtMap))
    outs() << "\nISA String: " << ISAString.get()->toString() << "\n";
}

static bool stripExperimentalPrefix(StringRef &Ext) {
  return Ext.consume_front("experimental-");
}

// This function finds the last character that doesn't belong to a version
// (e.g. zba1p0 is extension 'zba' of version '1p0'). So the function will
// consume [0-9]*p[0-9]* starting from the backward. An extension name will not
// end with a digit or the letter 'p', so this function will parse correctly.
// NOTE: This function is NOT able to take empty strings or strings that only
// have version numbers and no extension name. It assumes the extension name
// will be at least more than one character.
static size_t findLastNonVersionCharacter(StringRef Ext) {
  assert(!Ext.empty() &&
         "Already guarded by if-statement in ::parseArchString");

  int Pos = Ext.size() - 1;
  while (Pos > 0 && isDigit(Ext[Pos]))
    Pos--;
  if (Pos > 0 && Ext[Pos] == 'p' && isDigit(Ext[Pos - 1])) {
    Pos--;
    while (Pos > 0 && isDigit(Ext[Pos]))
      Pos--;
  }
  return Pos;
}

namespace {
struct LessExtName {
  bool operator()(const RISCVSupportedExtension &LHS, StringRef RHS) {
    return StringRef(LHS.Name) < RHS;
  }
  bool operator()(StringRef LHS, const RISCVSupportedExtension &RHS) {
    return LHS < StringRef(RHS.Name);
  }
};
} // namespace

static std::optional<RISCVISAUtils::ExtensionVersion>
findDefaultVersion(StringRef ExtName) {
  // Find default version of an extension.
  // TODO: We might set default version based on profile or ISA spec.
  for (auto &ExtInfo : {ArrayRef(SupportedExtensions),
                        ArrayRef(SupportedExperimentalExtensions)}) {
    auto I = llvm::lower_bound(ExtInfo, ExtName, LessExtName());

    if (I == ExtInfo.end() || I->Name != ExtName)
      continue;

    return I->Version;
  }
  return std::nullopt;
}

static StringRef getExtensionTypeDesc(StringRef Ext) {
  if (Ext.starts_with('s'))
    return "standard supervisor-level extension";
  if (Ext.starts_with('x'))
    return "non-standard user-level extension";
  if (Ext.starts_with('z'))
    return "standard user-level extension";
  return StringRef();
}

static StringRef getExtensionType(StringRef Ext) {
  if (Ext.starts_with('s'))
    return "s";
  if (Ext.starts_with('x'))
    return "x";
  if (Ext.starts_with('z'))
    return "z";
  return StringRef();
}

static std::optional<RISCVISAUtils::ExtensionVersion>
isExperimentalExtension(StringRef Ext) {
  auto I =
      llvm::lower_bound(SupportedExperimentalExtensions, Ext, LessExtName());
  if (I == std::end(SupportedExperimentalExtensions) || I->Name != Ext)
    return std::nullopt;

  return I->Version;
}

bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) {
  bool IsExperimental = stripExperimentalPrefix(Ext);

  ArrayRef<RISCVSupportedExtension> ExtInfo =
      IsExperimental ? ArrayRef(SupportedExperimentalExtensions)
                     : ArrayRef(SupportedExtensions);

  auto I = llvm::lower_bound(ExtInfo, Ext, LessExtName());
  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),
                       ArrayRef(SupportedExperimentalExtensions)}) {
    auto Range =
        std::equal_range(ExtInfo.begin(), ExtInfo.end(), Ext, LessExtName());
    for (auto I = Range.first, E = Range.second; I != E; ++I)
      if (I->Version.Major == MajorVersion && I->Version.Minor == MinorVersion)
        return true;
  }

  return false;
}

bool RISCVISAInfo::hasExtension(StringRef Ext) const {
  stripExperimentalPrefix(Ext);

  if (!isSupportedExtension(Ext))
    return false;

  return Exts.count(Ext.str()) != 0;
}

std::vector<std::string> RISCVISAInfo::toFeatures(bool AddAllExtensions,
                                                  bool IgnoreUnknown) const {
  std::vector<std::string> Features;
  for (const auto &[ExtName, _] : Exts) {
    // i is a base instruction set, not an extension (see
    // https://github.com/riscv/riscv-isa-manual/blob/main/src/naming.adoc#base-integer-isa)
    // and is not recognized in clang -cc1
    if (ExtName == "i")
      continue;
    if (IgnoreUnknown && !isSupportedExtension(ExtName))
      continue;

    if (isExperimentalExtension(ExtName)) {
      Features.push_back((llvm::Twine("+experimental-") + ExtName).str());
    } else {
      Features.push_back((llvm::Twine("+") + ExtName).str());
    }
  }
  if (AddAllExtensions) {
    for (const RISCVSupportedExtension &Ext : SupportedExtensions) {
      if (Exts.count(Ext.Name))
        continue;
      Features.push_back((llvm::Twine("-") + Ext.Name).str());
    }

    for (const RISCVSupportedExtension &Ext : SupportedExperimentalExtensions) {
      if (Exts.count(Ext.Name))
        continue;
      Features.push_back((llvm::Twine("-experimental-") + Ext.Name).str());
    }
  }
  return Features;
}

static Error getError(const Twine &Message) {
  return createStringError(errc::invalid_argument, Message);
}

static Error getErrorForInvalidExt(StringRef ExtName) {
  if (ExtName.size() == 1) {
    return getError("unsupported standard user-level extension '" + ExtName +
                    "'");
  }
  return getError("unsupported " + getExtensionTypeDesc(ExtName) + " '" +
                  ExtName + "'");
}

// Extensions may have a version number, and may be separated by
// an underscore '_' e.g.: rv32i2_m2.
// Version number is divided into major and minor version numbers,
// separated by a 'p'. If the minor version is 0 then 'p0' can be
// omitted from the version string. E.g., rv32i2p0, rv32i2, rv32i2p1.
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major,
                                 unsigned &Minor, unsigned &ConsumeLength,
                                 bool EnableExperimentalExtension,
                                 bool ExperimentalExtensionVersionCheck) {
  StringRef MajorStr, MinorStr;
  Major = 0;
  Minor = 0;
  ConsumeLength = 0;
  MajorStr = In.take_while(isDigit);
  In = In.substr(MajorStr.size());

  if (!MajorStr.empty() && In.consume_front("p")) {
    MinorStr = In.take_while(isDigit);
    In = In.substr(MajorStr.size() + MinorStr.size() - 1);

    // Expected 'p' to be followed by minor version number.
    if (MinorStr.empty()) {
      return getError("minor version number missing after 'p' for extension '" +
                      Ext + "'");
    }
  }

  if (!MajorStr.empty() && MajorStr.getAsInteger(10, Major))
    return getError("Failed to parse major version number for extension '" +
                    Ext + "'");

  if (!MinorStr.empty() && MinorStr.getAsInteger(10, Minor))
    return getError("Failed to parse minor version number for extension '" +
                    Ext + "'");

  ConsumeLength = MajorStr.size();

  if (!MinorStr.empty())
    ConsumeLength += MinorStr.size() + 1 /*'p'*/;

  // Expected multi-character extension with version number to have no
  // subsequent characters (i.e. must either end string or be followed by
  // an underscore).
  if (Ext.size() > 1 && In.size())
    return getError(
        "multi-character extensions must be separated by underscores");

  // If experimental extension, require use of current version number
  if (auto ExperimentalExtension = isExperimentalExtension(Ext)) {
    if (!EnableExperimentalExtension)
      return getError("requires '-menable-experimental-extensions' "
                      "for experimental extension '" +
                      Ext + "'");

    if (ExperimentalExtensionVersionCheck &&
        (MajorStr.empty() && MinorStr.empty()))
      return getError(
          "experimental extension requires explicit version number `" + Ext +
          "`");

    auto SupportedVers = *ExperimentalExtension;
    if (ExperimentalExtensionVersionCheck &&
        (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
      std::string Error = "unsupported version number " + MajorStr.str();
      if (!MinorStr.empty())
        Error += "." + MinorStr.str();
      Error += " for experimental extension '" + Ext.str() +
               "' (this compiler supports " + utostr(SupportedVers.Major) +
               "." + utostr(SupportedVers.Minor) + ")";
      return getError(Error);
    }
    return Error::success();
  }

  // Exception rule for `g`, we don't have clear version scheme for that on
  // ISA spec.
  if (Ext == "g")
    return Error::success();

  if (MajorStr.empty() && MinorStr.empty()) {
    if (auto DefaultVersion = findDefaultVersion(Ext)) {
      Major = DefaultVersion->Major;
      Minor = DefaultVersion->Minor;
    }
    // No matter found or not, return success, assume other place will
    // verify.
    return Error::success();
  }

  if (RISCVISAInfo::isSupportedExtension(Ext, Major, Minor))
    return Error::success();

  if (!RISCVISAInfo::isSupportedExtension(Ext))
    return getErrorForInvalidExt(Ext);

  std::string Error = "unsupported version number " + MajorStr.str();
  if (!MinorStr.empty())
    Error += "." + MinorStr.str();
  Error += " for extension '" + Ext.str() + "'";
  return getError(Error);
}

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::createFromExtMap(unsigned XLen,
                               const RISCVISAUtils::OrderedExtensionMap &Exts) {
  assert(XLen == 32 || XLen == 64);
  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));

  ISAInfo->Exts = Exts;

  return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
}

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseFeatures(unsigned XLen,
                            const std::vector<std::string> &Features) {
  assert(XLen == 32 || XLen == 64);
  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));

  for (StringRef ExtName : Features) {
    assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
    bool Add = ExtName[0] == '+';
    ExtName = ExtName.drop_front(1); // Drop '+' or '-'
    bool Experimental = stripExperimentalPrefix(ExtName);
    auto ExtensionInfos = Experimental
                              ? ArrayRef(SupportedExperimentalExtensions)
                              : ArrayRef(SupportedExtensions);
    auto ExtensionInfoIterator =
        llvm::lower_bound(ExtensionInfos, ExtName, LessExtName());

    // Not all features is related to ISA extension, like `relax` or
    // `save-restore`, skip those feature.
    if (ExtensionInfoIterator == ExtensionInfos.end() ||
        ExtensionInfoIterator->Name != ExtName)
      continue;

    if (Add)
      ISAInfo->Exts[ExtName.str()] = ExtensionInfoIterator->Version;
    else
      ISAInfo->Exts.erase(ExtName.str());
  }

  return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
}

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
  // RISC-V ISA strings must be [a-z0-9_]
  if (!llvm::all_of(
          Arch, [](char C) { return isDigit(C) || isLower(C) || C == '_'; }))
    return getError("string may only contain [a-z0-9_]");

  // Must start with a valid base ISA name.
  unsigned XLen = 0;
  if (Arch.consume_front("rv32"))
    XLen = 32;
  else if (Arch.consume_front("rv64"))
    XLen = 64;

  if (XLen == 0 || Arch.empty() || (Arch[0] != 'i' && Arch[0] != 'e'))
    return getError("arch string must begin with valid base ISA");

  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));

  // 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.
  while (!Arch.empty()) {
    if (Arch[0] == '_') {
      if (Arch.size() == 1 || Arch[1] == '_')
        return getError("extension name missing after separator '_'");
      Arch = Arch.drop_front();
    }

    size_t Idx = Arch.find('_');
    StringRef Ext = Arch.slice(0, Idx);
    Arch = Arch.substr(Idx);

    StringRef Prefix, MinorVersionStr;
    std::tie(Prefix, MinorVersionStr) = Ext.rsplit('p');
    if (MinorVersionStr.empty())
      return getError("extension lacks version in expected format");
    unsigned MajorVersion, MinorVersion;
    if (MinorVersionStr.getAsInteger(10, MinorVersion))
      return getError("failed to parse minor version number");

    // Split Prefix into the extension name and the major version number
    // (the trailing digits of Prefix).
    size_t VersionStart = Prefix.size();
    while (VersionStart != 0) {
      if (!isDigit(Prefix[VersionStart - 1]))
        break;
      --VersionStart;
    }
    if (VersionStart == Prefix.size())
      return getError("extension lacks version in expected format");

    if (VersionStart == 0)
      return getError("missing extension name");

    StringRef ExtName = Prefix.slice(0, VersionStart);
    StringRef MajorVersionStr = Prefix.substr(VersionStart);
    if (MajorVersionStr.getAsInteger(10, MajorVersion))
      return getError("failed to parse major version number");

    if ((ExtName[0] == 'z' || ExtName[0] == 's' || ExtName[0] == 'x') &&
        (ExtName.size() == 1 || isDigit(ExtName[1])))
      return getError("'" + Twine(ExtName[0]) +
                      "' must be followed by a letter");

    if (!ISAInfo->Exts
             .emplace(
                 ExtName.str(),
                 RISCVISAUtils::ExtensionVersion{MajorVersion, MinorVersion})
             .second)
      return getError("duplicate extension '" + ExtName + "'");
  }
  ISAInfo->updateImpliedLengths();
  return std::move(ISAInfo);
}

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
                              bool ExperimentalExtensionVersionCheck) {
  // RISC-V ISA strings must be [a-z0-9_]
  if (!llvm::all_of(
          Arch, [](char C) { return isDigit(C) || isLower(C) || C == '_'; }))
    return getError("string may only contain [a-z0-9_]");

  // ISA string must begin with rv32, rv64, or a profile.
  unsigned XLen = 0;
  if (Arch.consume_front("rv32")) {
    XLen = 32;
  } else if (Arch.consume_front("rv64")) {
    XLen = 64;
  } else {
    // Try parsing as a profile.
    auto ProfileCmp = [](StringRef Arch, const RISCVProfile &Profile) {
      return Arch < Profile.Name;
    };
    auto I = llvm::upper_bound(SupportedProfiles, Arch, ProfileCmp);
    bool FoundProfile = I != std::begin(SupportedProfiles) &&
                        Arch.starts_with(std::prev(I)->Name);
    if (!FoundProfile) {
      I = llvm::upper_bound(SupportedExperimentalProfiles, Arch, ProfileCmp);
      FoundProfile = (I != std::begin(SupportedExperimentalProfiles) &&
                      Arch.starts_with(std::prev(I)->Name));
      if (FoundProfile && !EnableExperimentalExtension) {
        return getError("requires '-menable-experimental-extensions' "
                        "for profile '" +
                        std::prev(I)->Name + "'");
      }
    }
    if (FoundProfile) {
      --I;
      std::string NewArch = I->MArch.str();
      StringRef ArchWithoutProfile = Arch.drop_front(I->Name.size());
      if (!ArchWithoutProfile.empty()) {
        if (ArchWithoutProfile.front() != '_')
          return getError("additional extensions must be after separator '_'");
        NewArch += ArchWithoutProfile.str();
      }
      return parseArchString(NewArch, EnableExperimentalExtension,
                             ExperimentalExtensionVersionCheck);
    }
  }

  if (XLen == 0 || Arch.empty())
    return getError(
        "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported "
        "profile name");

  std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));

  // The canonical order specified in ISA manual.
  // Ref: Table 22.1 in RISC-V User-Level ISA V2.2
  char Baseline = Arch.front();
  // Skip the baseline.
  Arch = Arch.drop_front();

  unsigned Major, Minor, ConsumeLength;

  // First letter should be 'e', 'i' or 'g'.
  switch (Baseline) {
  default:
    return getError("first letter after \'rv" + Twine(XLen) +
                    "\' should be 'e', 'i' or 'g'");
  case 'e':
  case 'i':
    // Baseline is `i` or `e`
    if (auto E = getExtensionVersion(
            StringRef(&Baseline, 1), Arch, Major, Minor, ConsumeLength,
            EnableExperimentalExtension, ExperimentalExtensionVersionCheck))
      return std::move(E);

    ISAInfo->Exts[std::string(1, Baseline)] = {Major, Minor};
    break;
  case 'g':
    // g expands to extensions in RISCVGImplications.
    if (!Arch.empty() && isDigit(Arch.front()))
      return getError("version not supported for 'g'");

    // Versions for g are disallowed, and this was checked for previously.
    ConsumeLength = 0;

    // No matter which version is given to `g`, we always set imafd to default
    // version since the we don't have clear version scheme for that on
    // ISA spec.
    for (const char *Ext : RISCVGImplications) {
      auto Version = findDefaultVersion(Ext);
      assert(Version && "Default extension version not found?");
      ISAInfo->Exts[std::string(Ext)] = {Version->Major, Version->Minor};
    }
    break;
  }

  // Consume the base ISA version number and any '_' between rvxxx and the
  // first extension
  Arch = Arch.drop_front(ConsumeLength);

  while (!Arch.empty()) {
    if (Arch.front() == '_') {
      if (Arch.size() == 1 || Arch[1] == '_')
        return getError("extension name missing after separator '_'");
      Arch = Arch.drop_front();
    }

    size_t Idx = Arch.find('_');
    StringRef Ext = Arch.slice(0, Idx);
    Arch = Arch.substr(Idx);

    do {
      StringRef Name, Vers, Desc;
      if (RISCVISAUtils::AllStdExts.contains(Ext.front())) {
        Name = Ext.take_front(1);
        Ext = Ext.drop_front();
        Vers = Ext;
        Desc = "standard user-level extension";
      } else if (Ext.front() == 'z' || Ext.front() == 's' ||
                 Ext.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.
        StringRef Type = getExtensionType(Ext);
        Desc = getExtensionTypeDesc(Ext);
        auto Pos = findLastNonVersionCharacter(Ext) + 1;
        Name = Ext.substr(0, Pos);
        Vers = Ext.substr(Pos);
        Ext = StringRef();

        assert(!Type.empty() && "Empty type?");
        if (Name.size() == Type.size())
          return getError(Desc + " name missing after '" + Type + "'");
      } else {
        return getError("invalid standard user-level extension '" +
                        Twine(Ext.front()) + "'");
      }

      unsigned Major, Minor, ConsumeLength;
      if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength,
                                       EnableExperimentalExtension,
                                       ExperimentalExtensionVersionCheck))
        return E;

      if (Name.size() == 1)
        Ext = Ext.substr(ConsumeLength);

      if (!RISCVISAInfo::isSupportedExtension(Name))
        return getErrorForInvalidExt(Name);

      // Insert and error for duplicates.
      if (!ISAInfo->Exts
               .emplace(Name.str(),
                        RISCVISAUtils::ExtensionVersion{Major, Minor})
               .second)
        return getError("duplicated " + Desc + " '" + Name + "'");

    } while (!Ext.empty());
  }

  // We add Zicsr/Zifenci as final to allow duplicated "zicsr"/"zifencei" like
  // "rv64g_zicsr_zifencei".
  if (Baseline == 'g') {
    for (const char *Ext : RISCVGImplicationsZi) {
      if (ISAInfo->Exts.count(Ext))
        continue;

      auto Version = findDefaultVersion(Ext);
      assert(Version && "Default extension version not found?");
      ISAInfo->Exts[std::string(Ext)] = {Version->Major, Version->Minor};
    }
  }

  return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
}

static Error getIncompatibleError(StringRef Ext1, StringRef Ext2) {
  return getError("'" + Ext1 + "' and '" + Ext2 +
                  "' extensions are incompatible");
}

static Error getExtensionRequiresError(StringRef Ext, StringRef ReqExt) {
  return getError("'" + Ext + "' requires '" + ReqExt +
                  "' extension to also be specified");
}

Error RISCVISAInfo::checkDependency() {
  bool HasE = Exts.count("e") != 0;
  bool HasI = Exts.count("i") != 0;
  bool HasC = Exts.count("c") != 0;
  bool HasF = Exts.count("f") != 0;
  bool HasD = Exts.count("d") != 0;
  bool HasZfinx = Exts.count("zfinx") != 0;
  bool HasVector = Exts.count("zve32x") != 0;
  bool HasZvl = MinVLen != 0;
  bool HasZcmp = Exts.count("zcmp") != 0;
  bool HasXqccmp = Exts.count("xqccmp") != 0;

  static constexpr StringLiteral XqciExts[] = {
      {"xqcia"},   {"xqciac"},  {"xqcibi"},  {"xqcibm"},  {"xqcicli"},
      {"xqcicm"},  {"xqcics"},  {"xqcicsr"}, {"xqciint"}, {"xqciio"},
      {"xqcilb"},  {"xqcili"},  {"xqcilia"}, {"xqcilo"},  {"xqcilsm"},
      {"xqcisim"}, {"xqcisls"}, {"xqcisync"}};
  static constexpr StringLiteral ZcdOverlaps[] = {
      {"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};

  if (HasI && HasE)
    return getIncompatibleError("i", "e");

  if (HasF && HasZfinx)
    return getIncompatibleError("f", "zfinx");

  if (HasZvl && !HasVector)
    return getExtensionRequiresError("zvl*b", "v' or 'zve*");

  if (HasD && (HasC || Exts.count("zcd")))
    for (auto Ext : ZcdOverlaps)
      if (Exts.count(Ext.str()))
        return getError(
            Twine("'") + Ext + "' extension is incompatible with '" +
            (HasC ? "c" : "zcd") + "' extension when 'd' extension is enabled");

  if (XLen != 32 && Exts.count("zcf"))
    return getError("'zcf' is only supported for 'rv32'");

  if (Exts.count("xwchc") != 0) {
    if (XLen != 32)
      return getError("'xwchc' is only supported for 'rv32'");

    if (HasD)
      return getIncompatibleError("d", "xwchc");

    if (Exts.count("zcb") != 0)
      return getIncompatibleError("xwchc", "zcb");
  }

  if (Exts.count("zclsd") != 0) {
    if (XLen != 32)
      return getError("'zclsd' is only supported for 'rv32'");

    if (Exts.count("zcf") != 0)
      return getIncompatibleError("zclsd", "zcf");
  }

  if (XLen != 32 && Exts.count("zilsd") != 0)
    return getError("'zilsd' is only supported for 'rv32'");

  for (auto Ext : XqciExts)
    if (Exts.count(Ext.str()) && (XLen != 32))
      return getError("'" + Twine(Ext) + "'" + " is only supported for 'rv32'");

  if (HasZcmp && HasXqccmp)
    return getIncompatibleError("zcmp", "xqccmp");

  return Error::success();
}

struct ImpliedExtsEntry {
  StringLiteral Name;
  const char *ImpliedExt;

  bool operator<(const ImpliedExtsEntry &Other) const {
    return Name < Other.Name;
  }
};

static bool operator<(const ImpliedExtsEntry &LHS, StringRef RHS) {
  return LHS.Name < RHS;
}

static bool operator<(StringRef LHS, const ImpliedExtsEntry &RHS) {
  return LHS < RHS.Name;
}

#define GET_IMPLIED_EXTENSIONS
#include "llvm/TargetParser/RISCVTargetParserDef.inc"

void RISCVISAInfo::updateImplication() {
  bool HasE = Exts.count("e") != 0;
  bool HasI = Exts.count("i") != 0;

  // If not in e extension and i extension does not exist, i extension is
  // implied
  if (!HasE && !HasI) {
    auto Version = findDefaultVersion("i");
    Exts["i"] = *Version;
  }

  if (HasE && HasI)
    Exts.erase("i");

  assert(llvm::is_sorted(ImpliedExts) && "Table not sorted by Name");

  // This loop may execute over 1 iteration since implication can be layered
  // Exits loop if no more implication is applied
  SmallVector<StringRef, 16> WorkList;
  for (auto const &Ext : Exts)
    WorkList.push_back(Ext.first);

  while (!WorkList.empty()) {
    StringRef ExtName = WorkList.pop_back_val();
    auto Range = std::equal_range(std::begin(ImpliedExts),
                                  std::end(ImpliedExts), ExtName);
    for (const ImpliedExtsEntry &Implied : llvm::make_range(Range)) {
      const char *ImpliedExt = Implied.ImpliedExt;
      auto [It, Inserted] = Exts.try_emplace(ImpliedExt);
      if (!Inserted)
        continue;
      auto Version = findDefaultVersion(ImpliedExt);
      It->second = *Version;
      WorkList.push_back(ImpliedExt);
    }
  }

  // Add Zcd if C and D are enabled.
  if (Exts.count("c") && Exts.count("d") && !Exts.count("zcd")) {
    auto Version = findDefaultVersion("zcd");
    Exts["zcd"] = *Version;
  }

  // Add Zcf if C and F are enabled on RV32.
  if (XLen == 32 && Exts.count("c") && Exts.count("f") && !Exts.count("zcf")) {
    auto Version = findDefaultVersion("zcf");
    Exts["zcf"] = *Version;
  }

  // Add Zcf if Zce and F are enabled on RV32.
  if (XLen == 32 && Exts.count("zce") && Exts.count("f") &&
      !Exts.count("zcf")) {
    auto Version = findDefaultVersion("zcf");
    Exts["zcf"] = *Version;
  }
}

static constexpr StringLiteral CombineIntoExts[] = {
    {"b"},     {"zk"},    {"zkn"},  {"zks"},   {"zvkn"},
    {"zvknc"}, {"zvkng"}, {"zvks"}, {"zvksc"}, {"zvksg"},
};

void RISCVISAInfo::updateCombination() {
  bool MadeChange = false;
  do {
    MadeChange = false;
    for (StringRef CombineExt : CombineIntoExts) {
      if (Exts.count(CombineExt.str()))
        continue;

      // Look up the extension in the ImpliesExt table to find everything it
      // depends on.
      auto Range = std::equal_range(std::begin(ImpliedExts),
                                    std::end(ImpliedExts), CombineExt);
      bool HasAllRequiredFeatures = std::all_of(
          Range.first, Range.second, [&](const ImpliedExtsEntry &Implied) {
            return Exts.count(Implied.ImpliedExt);
          });
      if (HasAllRequiredFeatures) {
        auto Version = findDefaultVersion(CombineExt);
        Exts[CombineExt.str()] = *Version;
        MadeChange = true;
      }
    }
  } while (MadeChange);
}

void RISCVISAInfo::updateImpliedLengths() {
  assert(FLen == 0 && MaxELenFp == 0 && MaxELen == 0 && MinVLen == 0 &&
         "Expected lengths to be initialied to zero");

  if (Exts.count("q"))
    FLen = 128;
  else if (Exts.count("d"))
    FLen = 64;
  else if (Exts.count("f"))
    FLen = 32;

  if (Exts.count("v")) {
    MaxELenFp = std::max(MaxELenFp, 64u);
    MaxELen = std::max(MaxELen, 64u);
  }

  for (auto const &Ext : Exts) {
    StringRef ExtName = Ext.first;
    // Infer MaxELen and MaxELenFp from Zve(32/64)(x/f/d)
    if (ExtName.consume_front("zve")) {
      unsigned ZveELen;
      if (ExtName.consumeInteger(10, ZveELen))
        continue;

      if (ExtName == "f")
        MaxELenFp = std::max(MaxELenFp, 32u);
      else if (ExtName == "d")
        MaxELenFp = std::max(MaxELenFp, 64u);
      else if (ExtName != "x")
        continue;

      MaxELen = std::max(MaxELen, ZveELen);
      continue;
    }

    // Infer MinVLen from zvl*b.
    if (ExtName.consume_front("zvl")) {
      unsigned ZvlLen;
      if (ExtName.consumeInteger(10, ZvlLen))
        continue;

      if (ExtName != "b")
        continue;

      MinVLen = std::max(MinVLen, ZvlLen);
      continue;
    }
  }
}

std::string RISCVISAInfo::toString() const {
  std::string Buffer;
  raw_string_ostream Arch(Buffer);

  Arch << "rv" << XLen;

  ListSeparator LS("_");
  for (auto const &Ext : Exts) {
    StringRef ExtName = Ext.first;
    auto ExtInfo = Ext.second;
    Arch << LS << ExtName;
    Arch << ExtInfo.Major << "p" << ExtInfo.Minor;
  }

  return Arch.str();
}

llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
  ISAInfo->updateImplication();
  ISAInfo->updateCombination();
  ISAInfo->updateImpliedLengths();

  if (Error Result = ISAInfo->checkDependency())
    return std::move(Result);
  return std::move(ISAInfo);
}

StringRef RISCVISAInfo::computeDefaultABI() const {
  if (XLen == 32) {
    if (Exts.count("e"))
      return "ilp32e";
    if (Exts.count("d"))
      return "ilp32d";
    if (Exts.count("f"))
      return "ilp32f";
    return "ilp32";
  } else if (XLen == 64) {
    if (Exts.count("e"))
      return "lp64e";
    if (Exts.count("d"))
      return "lp64d";
    if (Exts.count("f"))
      return "lp64f";
    return "lp64";
  }
  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();
}

struct RISCVExtBit {
  const StringLiteral ext;
  uint8_t groupid;
  uint8_t bitpos;
};

struct RISCVExtensionBitmask {
  const char *Name;
  unsigned GroupID;
  unsigned BitPosition;
};

#define GET_RISCVExtensionBitmaskTable_IMPL
#include "llvm/TargetParser/RISCVTargetParserDef.inc"

std::pair<int, int> RISCVISAInfo::getRISCVFeaturesBitsInfo(StringRef Ext) {
  // Note that this code currently accepts mixed case extension names, but
  // does not handle extension versions at all.  That's probably fine because
  // there's only one extension version in the __riscv_feature_bits vector.
  for (auto E : ExtensionBitmask)
    if (Ext.equals_insensitive(E.Name))
      return std::make_pair(E.GroupID, E.BitPosition);
  return std::make_pair(-1, -1);
}
