27struct RISCVSupportedExtension {
30 RISCVISAUtils::ExtensionVersion Version;
32 bool operator<(
const RISCVSupportedExtension &
RHS)
const {
33 return StringRef(Name) < StringRef(
RHS.Name);
42 return StringRef(Name) < StringRef(
RHS.Name);
51#define GET_SUPPORTED_EXTENSIONS
52#include "llvm/TargetParser/RISCVTargetParserDef.inc"
54#define GET_SUPPORTED_PROFILES
55#include "llvm/TargetParser/RISCVTargetParserDef.inc"
59 static std::atomic<bool> TableChecked(
false);
60 if (!TableChecked.load(std::memory_order_relaxed)) {
62 "Extensions are not sorted by name");
64 "Experimental extensions are not sorted by name");
66 "Profiles are not sorted by name");
68 "Experimental profiles are not sorted by name");
69 TableChecked.store(
true, std::memory_order_relaxed);
77 unsigned VersionWidth = Description.
empty() ? 0 : 10;
79 << Description <<
"\n";
83 outs() <<
"All available -march extensions for RISC-V\n\n";
87 for (
const auto &E : SupportedExtensions)
88 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
89 for (
const auto &E : ExtMap) {
91 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
95 outs() <<
"\nExperimental extensions\n";
97 for (
const auto &E : SupportedExperimentalExtensions)
98 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
99 for (
const auto &E : ExtMap) {
101 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
105 outs() <<
"\nSupported Profiles\n";
106 for (
const auto &
P : SupportedProfiles)
109 outs() <<
"\nExperimental Profiles\n";
110 for (
const auto &
P : SupportedExperimentalProfiles)
113 outs() <<
"\nUse -march to specify the target's extension.\n"
114 "For example, clang -march=rv32i_v1p0\n";
118 bool IsRV64, std::set<StringRef> &EnabledFeatureNames,
120 outs() <<
"Extensions enabled for the given RISC-V target\n\n";
125 for (
const auto &E : SupportedExtensions)
126 if (EnabledFeatureNames.count(E.Name) != 0) {
127 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
128 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
130 for (
const auto &E : ExtMap) {
132 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
136 outs() <<
"\nExperimental extensions\n";
138 for (
const auto &E : SupportedExperimentalExtensions) {
140 if (EnabledFeatureNames.count(
"experimental-" + Name.str()) != 0) {
141 FullExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
142 ExtMap[E.Name] = {E.Version.Major, E.Version.Minor};
145 for (
const auto &E : ExtMap) {
147 std::to_string(E.second.Major) +
"." + std::to_string(E.second.Minor);
151 unsigned XLen = IsRV64 ? 64 : 32;
153 outs() <<
"\nISA String: " << ISAString.get()->toString() <<
"\n";
169 "Already guarded by if-statement in ::parseArchString");
171 int Pos = Ext.
size() - 1;
172 while (Pos > 0 &&
isDigit(Ext[Pos]))
174 if (Pos > 0 && Ext[Pos] ==
'p' &&
isDigit(Ext[Pos - 1])) {
176 while (Pos > 0 &&
isDigit(Ext[Pos]))
184 bool operator()(
const RISCVSupportedExtension &
LHS, StringRef
RHS) {
185 return StringRef(
LHS.Name) <
RHS;
187 bool operator()(StringRef
LHS,
const RISCVSupportedExtension &
RHS) {
188 return LHS < StringRef(
RHS.Name);
193static std::optional<RISCVISAUtils::ExtensionVersion>
197 for (
auto &ExtInfo : {
ArrayRef(SupportedExtensions),
198 ArrayRef(SupportedExperimentalExtensions)}) {
201 if (
I == ExtInfo.end() ||
I->Name != ExtName)
211 return "standard supervisor-level extension";
213 return "non-standard user-level extension";
215 return "standard user-level extension";
229static std::optional<RISCVISAUtils::ExtensionVersion>
233 if (
I == std::end(SupportedExperimentalExtensions) ||
I->Name != Ext)
243 IsExperimental ?
ArrayRef(SupportedExperimentalExtensions)
247 return I != ExtInfo.
end() &&
I->Name == Ext;
253 for (
auto ExtInfo : {
ArrayRef(SupportedExtensions),
254 ArrayRef(SupportedExperimentalExtensions)}) {
256 if (
I != ExtInfo.end() &&
I->Name == Ext)
264 unsigned MinorVersion) {
265 for (
auto ExtInfo : {
ArrayRef(SupportedExtensions),
266 ArrayRef(SupportedExperimentalExtensions)}) {
268 std::equal_range(ExtInfo.begin(), ExtInfo.end(), Ext, LessExtName());
270 if (
I->Version.Major == MajorVersion &&
I->Version.Minor == MinorVersion)
283 return Exts.count(Ext.
str()) != 0;
287 bool IgnoreUnknown)
const {
288 std::vector<std::string> Features;
289 for (
const auto &[ExtName,
_] : Exts) {
294 Features.push_back((
llvm::Twine(
"+experimental-") + ExtName).str());
296 Features.push_back((
llvm::Twine(
"+") + ExtName).str());
299 if (AddAllExtensions) {
300 for (
const RISCVSupportedExtension &Ext : SupportedExtensions) {
301 if (Exts.count(Ext.Name))
303 Features.push_back((
llvm::Twine(
"-") + Ext.Name).str());
306 for (
const RISCVSupportedExtension &Ext : SupportedExperimentalExtensions) {
307 if (Exts.count(Ext.Name))
309 Features.push_back((
llvm::Twine(
"-experimental-") + Ext.Name).str());
320 if (ExtName.
size() == 1) {
321 return getError(
"unsupported standard user-level extension '" + ExtName +
334 unsigned &Minor,
unsigned &ConsumeLength,
335 bool EnableExperimentalExtension,
336 bool ExperimentalExtensionVersionCheck) {
341 MajorStr = In.take_while(
isDigit);
342 In = In.substr(MajorStr.
size());
344 if (!MajorStr.
empty() && In.consume_front(
"p")) {
345 MinorStr = In.take_while(
isDigit);
346 In = In.substr(MajorStr.
size() + MinorStr.
size() - 1);
349 if (MinorStr.
empty()) {
350 return getError(
"minor version number missing after 'p' for extension '" +
356 return getError(
"Failed to parse major version number for extension '" +
360 return getError(
"Failed to parse minor version number for extension '" +
363 ConsumeLength = MajorStr.
size();
365 if (!MinorStr.
empty())
366 ConsumeLength += MinorStr.
size() + 1 ;
371 if (Ext.
size() > 1 && In.size())
373 "multi-character extensions must be separated by underscores");
377 if (!EnableExperimentalExtension)
378 return getError(
"requires '-menable-experimental-extensions' "
379 "for experimental extension '" +
382 if (ExperimentalExtensionVersionCheck &&
385 "experimental extension requires explicit version number `" + Ext +
388 auto SupportedVers = *ExperimentalExtension;
389 if (ExperimentalExtensionVersionCheck &&
390 (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
391 std::string
Error =
"unsupported version number " + MajorStr.
str();
392 if (!MinorStr.
empty())
394 Error +=
" for experimental extension '" + Ext.
str() +
395 "' (this compiler supports " +
utostr(SupportedVers.Major) +
396 "." +
utostr(SupportedVers.Minor) +
")";
423 std::string
Error =
"unsupported version number " + MajorStr.
str();
424 if (!MinorStr.
empty())
426 Error +=
" for extension '" + Ext.
str() +
"'";
433 assert(XLen == 32 || XLen == 64);
434 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
436 ISAInfo->Exts = Exts;
438 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
443 const std::vector<std::string> &Features) {
444 assert(XLen == 32 || XLen == 64);
445 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
448 assert(ExtName.size() > 1 && (ExtName[0] ==
'+' || ExtName[0] ==
'-'));
449 bool Add = ExtName[0] ==
'+';
450 ExtName = ExtName.drop_front(1);
452 auto ExtensionInfos = Experimental
453 ?
ArrayRef(SupportedExperimentalExtensions)
455 auto ExtensionInfoIterator =
460 if (ExtensionInfoIterator == ExtensionInfos.end() ||
461 ExtensionInfoIterator->Name != ExtName)
465 ISAInfo->Exts[ExtName.str()] = ExtensionInfoIterator->Version;
467 ISAInfo->Exts.erase(ExtName.str());
470 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
478 return getError(
"string may only contain [a-z0-9_]");
487 auto IsBaseISA = [](
char C) {
return C ==
'i' ||
C ==
'e' ||
C ==
'y'; };
488 if (XLen == 0 || Arch.
empty() || !IsBaseISA(Arch[0]))
489 return getError(
"arch string must begin with valid base ISA");
490 char BaseISA = Arch[0];
492 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
497 while (!Arch.
empty()) {
498 if (Arch[0] ==
'_') {
499 if (Arch.
size() == 1 || Arch[1] ==
'_')
500 return getError(
"extension name missing after separator '_'");
504 size_t Idx = Arch.
find(
'_');
509 std::tie(Prefix, MinorVersionStr) = Ext.
rsplit(
'p');
510 if (MinorVersionStr.
empty())
511 return getError(
"extension lacks version in expected format");
512 unsigned MajorVersion, MinorVersion;
514 return getError(
"failed to parse minor version number");
518 size_t VersionStart = Prefix.size();
519 while (VersionStart != 0) {
520 if (!
isDigit(Prefix[VersionStart - 1]))
524 if (VersionStart == Prefix.size())
525 return getError(
"extension lacks version in expected format");
527 if (VersionStart == 0)
528 return getError(
"missing extension name");
530 StringRef ExtName = Prefix.slice(0, VersionStart);
531 StringRef MajorVersionStr = Prefix.substr(VersionStart);
533 return getError(
"failed to parse major version number");
535 if (IsBaseISA(ExtName[0])) {
536 if (ExtName.
size() > 1)
538 "' is missing version number");
539 if (ExtName[0] != BaseISA)
540 return getError(
"conflicting base ISAs '" +
Twine(BaseISA) +
"' and '" +
543 ExtName.
size() > 1) {
545 "' is missing version number");
548 if ((ExtName[0] ==
'z' || ExtName[0] ==
's' || ExtName[0] ==
'x') &&
551 "' must be followed by a letter");
558 return getError(
"duplicate extension '" + ExtName +
"'");
564 ISAInfo->updateImpliedLengths();
565 return std::move(ISAInfo);
570 bool ExperimentalExtensionVersionCheck) {
574 return getError(
"string may only contain [a-z0-9_]");
588 bool FoundProfile =
I != std::begin(SupportedProfiles) &&
592 FoundProfile = (
I != std::begin(SupportedExperimentalProfiles) &&
594 if (FoundProfile && !EnableExperimentalExtension) {
595 return getError(
"requires '-menable-experimental-extensions' "
597 std::prev(
I)->Name +
"'");
602 std::string NewArch =
I->MArch.str();
604 if (!ArchWithoutProfile.
empty()) {
605 if (ArchWithoutProfile.
front() !=
'_')
606 return getError(
"additional extensions must be after separator '_'");
607 NewArch += ArchWithoutProfile.
str();
610 ExperimentalExtensionVersionCheck);
614 if (XLen == 0 || Arch.
empty())
616 "string must begin with rv32{i,e,g,y}, rv64{i,e,g,y}, or a supported "
619 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
623 char Baseline = Arch.
front();
627 unsigned Major, Minor, ConsumeLength;
633 "\' should be 'e', 'i', 'g' or 'y'");
642 StringRef(&Baseline, 1), Arch, Major, Minor, ConsumeLength,
643 EnableExperimentalExtension, ExperimentalExtensionVersionCheck))
646 ISAInfo->Exts[std::string(1, Baseline)] = {Major, Minor};
651 return getError(
"version not supported for 'g'");
662 ISAInfo->Exts[std::string(Ext)] = {
Version->Major,
Version->Minor};
671 while (!Arch.
empty()) {
672 if (Arch.
front() ==
'_') {
673 if (Arch.
size() == 1 || Arch[1] ==
'_')
674 return getError(
"extension name missing after separator '_'");
678 size_t Idx = Arch.
find(
'_');
688 Desc =
"standard user-level extension";
689 }
else if (Ext.
front() ==
'z' || Ext.
front() ==
's' ||
690 Ext.
front() ==
'x') {
702 Name = Ext.
substr(0, Pos);
707 if (Name.size() ==
Type.size())
710 return getError(
"invalid standard user-level extension '" +
714 unsigned Major, Minor, ConsumeLength;
716 EnableExperimentalExtension,
717 ExperimentalExtensionVersionCheck))
720 if (Name.size() == 1)
721 Ext = Ext.
substr(ConsumeLength);
731 return getError(
"duplicated " +
Desc +
" '" + Name +
"'");
733 }
while (!Ext.
empty());
738 if (Baseline ==
'g') {
740 if (ISAInfo->Exts.count(Ext))
745 ISAInfo->Exts[std::string(Ext)] = {
Version->Major,
Version->Minor};
749 return RISCVISAInfo::postProcessAndChecking(std::move(ISAInfo));
753 return getError(
"'" + Ext1 +
"' and '" + Ext2 +
754 "' extensions are incompatible");
758 return getError(
"'" + Ext +
"' is incompatible with " +
Base +
" base");
762 return getError(
"'" + Ext +
"' requires '" + ReqExt +
763 "' extension to also be specified");
766Error RISCVISAInfo::checkDependency() {
767 bool HasE = Exts.count(
"e") != 0;
768 bool HasI = Exts.count(
"i") != 0;
769 bool HasF = Exts.count(
"f") != 0;
770 bool HasD = Exts.count(
"d") != 0;
771 bool HasZfinx = Exts.count(
"zfinx") != 0;
772 bool HasVector = Exts.count(
"zve32x") != 0;
773 bool HasZvl = MinVLen != 0;
774 bool HasZcmp = Exts.count(
"zcmp") != 0;
775 bool HasXqccmp = Exts.count(
"xqccmp") != 0;
776 bool HasZcmt = Exts.count(
"zcmt") != 0;
777 bool HasXqccmt = Exts.count(
"xqccmt") != 0;
779 static constexpr StringLiteral ZcdOverlaps[] = {
780 {
"zcmt"}, {
"zcmp"}, {
"xqccmi"}, {
"xqccmp"},
781 {
"xqccmt"}, {
"xqciac"}, {
"xqcicm"},
783 static constexpr StringLiteral RV32Only[] = {
784 {
"zcf"}, {
"zclsd"}, {
"zilsd"}, {
"xwchc"}, {
"xqccmi"},
785 {
"xqci"}, {
"xqcia"}, {
"xqciac"}, {
"xqcibi"}, {
"xqcibm"},
786 {
"xqcicli"}, {
"xqcicm"}, {
"xqcics"}, {
"xqcicsr"}, {
"xqciint"},
787 {
"xqciio"}, {
"xqcilb"}, {
"xqcili"}, {
"xqcilia"}, {
"xqcilo"},
788 {
"xqcilsm"}, {
"xqcisim"}, {
"xqcisls"}, {
"xqcisync"},
794 if (HasF && HasZfinx)
797 if (HasZvl && !HasVector)
800 if (Exts.count(
"xsfvfbfexp16e") &&
801 !(Exts.count(
"zvfbfmin") || Exts.count(
"zvfbfa")))
803 "'xsfvfbfexp16e' requires 'zvfbfmin' or "
804 "'zvfbfa' extension to also be specified");
806 if (Exts.count(
"zcd"))
807 for (
auto Ext : ZcdOverlaps)
808 if (Exts.count(Ext.str()))
812 for (
auto Ext : RV32Only)
813 if (Exts.count(Ext.str()))
814 return getError(Twine(
"'") + Ext +
"' is only supported for 'rv32'");
816 if (Exts.count(
"xwchc") != 0) {
820 if (Exts.count(
"zcb") != 0)
824 if (Exts.count(
"zclsd") != 0 && Exts.count(
"zcf") != 0)
827 if (Exts.count(
"y") != 0) {
830 if (Exts.count(
"zclsd") != 0)
832 if (Exts.count(
"zcf") != 0)
836 if (Exts.count(
"zcd") != 0)
838 for (
auto Ext : ZcdOverlaps)
839 if (Exts.count(Ext.str()))
844 if (HasZcmp && HasXqccmp)
847 if (HasZcmt && HasXqccmt)
870#define GET_IMPLIED_EXTENSIONS
871#include "llvm/TargetParser/RISCVTargetParserDef.inc"
873void RISCVISAInfo::updateImplication() {
879 for (
auto const &Ext : Exts)
882 while (!WorkList.
empty()) {
884 auto Range = std::equal_range(std::begin(ImpliedExts),
885 std::end(ImpliedExts), ExtName);
887 const char *ImpliedExt = Implied.ImpliedExt;
888 auto [It, Inserted] = Exts.try_emplace(ImpliedExt);
892 It->second = *Version;
898 if (Exts.count(
"c") && Exts.count(
"d") && !Exts.count(
"zcd") &&
899 (XLen == 32 || !Exts.count(
"y"))) {
901 Exts[
"zcd"] = *Version;
905 if (XLen == 32 && Exts.count(
"c") && Exts.count(
"f") && !Exts.count(
"zcf") &&
908 Exts[
"zcf"] = *Version;
912 if (XLen == 32 && Exts.count(
"zce") && Exts.count(
"f") &&
913 !Exts.count(
"zcf") && !Exts.count(
"y")) {
915 Exts[
"zcf"] = *Version;
933 if (Exts.count(
"zca") && !Exts.count(
"c")) {
934 bool ShouldAddC =
false;
938 Exts.count(
"zcd") && (Exts.count(
"y") || Exts.count(
"zcf"));
939 else if (Exts.count(
"f"))
940 ShouldAddC = Exts.count(
"y") || Exts.count(
"zcf");
943 }
else if (XLen == 64) {
945 ShouldAddC = Exts.count(
"y") || Exts.count(
"zcd");
951 Exts[
"c"] = *Version;
955 if (!Exts.count(
"zce") && Exts.count(
"zca") && Exts.count(
"zcb") &&
956 Exts.count(
"zcmp") && Exts.count(
"zcmt")) {
957 bool ShouldAddZce =
false;
959 ShouldAddZce = !Exts.count(
"f") || Exts.count(
"zcf") || Exts.count(
"y");
960 }
else if (XLen == 64) {
962 ShouldAddZce = !Exts.count(
"y");
970 bool HasE = Exts.count(
"e") != 0;
971 bool HasI = Exts.count(
"i") != 0;
975 if (!HasE && !HasI) {
977 Exts[
"i"] = *Version;
985 {
"a"}, {
"b"}, {
"zk"}, {
"zkn"}, {
"zks"},
986 {
"zvkn"}, {
"zvknc"}, {
"zvkng"}, {
"zvks"}, {
"zvksc"},
987 {
"zvksg"}, {
"xqci"}, {
"xsfmm32a"},
990void RISCVISAInfo::updateCombination() {
991 bool MadeChange =
false;
995 if (Exts.count(CombineExt.str()))
1000 auto Range = std::equal_range(std::begin(ImpliedExts),
1001 std::end(ImpliedExts), CombineExt);
1002 bool HasAllRequiredFeatures = std::all_of(
1003 Range.first,
Range.second, [&](
const ImpliedExtsEntry &Implied) {
1004 return Exts.count(Implied.ImpliedExt);
1006 if (HasAllRequiredFeatures) {
1008 Exts[CombineExt.str()] = *
Version;
1012 }
while (MadeChange);
1015void RISCVISAInfo::updateImpliedLengths() {
1016 assert(FLen == 0 && MaxELenFp == 0 && MaxELen == 0 && MinVLen == 0 &&
1017 "Expected lengths to be initialied to zero");
1019 if (Exts.count(
"q"))
1021 else if (Exts.count(
"d"))
1023 else if (Exts.count(
"f"))
1026 if (Exts.count(
"v")) {
1027 MaxELenFp = std::max(MaxELenFp, 64u);
1028 MaxELen = std::max(MaxELen, 64u);
1031 for (
auto const &Ext : Exts) {
1032 StringRef ExtName = Ext.first;
1040 MaxELenFp = std::max(MaxELenFp, 32u);
1041 else if (ExtName ==
"d")
1042 MaxELenFp = std::max(MaxELenFp, 64u);
1043 else if (ExtName !=
"x")
1046 MaxELen = std::max(MaxELen, ZveELen);
1059 MinVLen = std::max(MinVLen, ZvlLen);
1069 Arch <<
"rv" << XLen;
1071 bool HasY = Exts.count(
"y") != 0;
1073 for (
auto const &Ext : Exts) {
1083 auto ExtInfo = Ext.second;
1084 Arch << LS << ExtName;
1085 Arch << ExtInfo.Major <<
"p" << ExtInfo.Minor;
1092RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
1093 ISAInfo->updateImplication();
1094 ISAInfo->updateCombination();
1095 ISAInfo->updateImpliedLengths();
1097 if (
Error Result = ISAInfo->checkDependency())
1098 return std::move(Result);
1099 return std::move(ISAInfo);
1103 bool HasY = Exts.
count(
"y") != 0;
1105 if (Exts.count(
"xcheriot"))
1107 if (Exts.count(
"e"))
1108 return HasY ?
"il32pc64e" :
"ilp32e";
1109 if (Exts.count(
"d"))
1110 return HasY ?
"il32pc64d" :
"ilp32d";
1111 if (Exts.count(
"f"))
1112 return HasY ?
"il32pc64f" :
"ilp32f";
1113 return HasY ?
"il32pc64" :
"ilp32";
1114 }
else if (XLen == 64) {
1116 if (Exts.count(
"e"))
1118 if (Exts.count(
"d"))
1119 return HasY ?
"l64pc128d" :
"lp64d";
1120 if (Exts.count(
"f"))
1121 return HasY ?
"l64pc128f" :
"lp64f";
1122 return HasY ?
"l64pc128" :
"lp64";
1137 unsigned Major, Minor, ConsumeLength;
1149 return std::string();
1155 return std::string();
1158 return std::string();
1170#define GET_RISCVExtensionBitmaskTable_IMPL
1171#include "llvm/TargetParser/RISCVTargetParserDef.inc"
1177 for (
auto E : ExtensionBitmask)
1179 return std::make_pair(E.GroupID, E.BitPosition);
1180 return std::make_pair(-1, -1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static void verifyTables()
static StringRef getExtensionTypeDesc(StringRef Ext)
static const char * RISCVGImplicationsZi[]
static std::optional< RISCVISAUtils::ExtensionVersion > findDefaultVersion(StringRef ExtName)
static size_t findLastNonVersionCharacter(StringRef Ext)
static Error getExtensionRequiresError(StringRef Ext, StringRef ReqExt)
static StringRef getExtensionType(StringRef Ext)
static Error getErrorForInvalidExt(StringRef ExtName)
static constexpr StringLiteral CombineIntoExts[]
static bool stripExperimentalPrefix(StringRef &Ext)
static std::optional< RISCVISAUtils::ExtensionVersion > isExperimentalExtension(StringRef Ext)
static void PrintExtension(StringRef Name, StringRef Version, StringRef Description)
static Error getBaseIncompatibleError(StringRef Ext, StringRef Base)
static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, unsigned &Minor, unsigned &ConsumeLength, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck)
static Error getIncompatibleError(StringRef Ext1, StringRef Ext2)
static Error getError(const Twine &Message)
static const char * RISCVGImplications[]
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static void verifyTables()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
A helper class to return the specified delimiter string after the first invocation of operator String...
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseNormalizedArchString(StringRef Arch)
Parse RISC-V ISA info from an arch string that is already in normalized form (as defined in the psABI...
LLVM_ABI bool hasExtension(StringRef Ext) const
RISCVISAInfo(const RISCVISAInfo &)=delete
LLVM_ABI std::string toString() const
LLVM_ABI StringRef computeDefaultABI() const
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static LLVM_ABI bool isSupportedExtension(StringRef Ext)
static LLVM_ABI void printEnabledExtensions(bool IsRV64, std::set< StringRef > &EnabledFeatureNames, StringMap< StringRef > &DescMap)
static LLVM_ABI void printSupportedExtensions(StringMap< StringRef > &DescMap)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatures(unsigned XLen, const std::vector< std::string > &Features)
Parse RISC-V ISA info from feature vector.
static LLVM_ABI std::pair< int, int > getRISCVFeaturesBitsInfo(StringRef Ext)
Return the group id and bit position of __riscv_feature_bits.
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > createFromExtMap(unsigned XLen, const RISCVISAUtils::OrderedExtensionMap &Exts)
LLVM_ABI std::vector< std::string > toFeatures(bool AddAllExtensions=false, bool IgnoreUnknown=true) const
Convert RISC-V ISA info to a feature vector.
static LLVM_ABI bool isSupportedExtensionWithVersion(StringRef Ext)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represent a constant reference to a string, i.e.
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
char front() const
Get the first character in the string.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
size_t count(char C) const
Return the number of occurrences of C in the string.
std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr StringLiteral AllStdExts
std::map< std::string, ExtensionVersion, ExtensionComparator > OrderedExtensionMap
OrderedExtensionMap is std::map, it's specialized to keep entries in canonical order of extension.
static constexpr uint64_t DefaultVersion
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool isLower(char C)
Checks if character C is a lowercase letter as classified by "C" locale.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utostr(uint64_t X, bool isNeg=false)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
ArrayRef(const T &OneElt) -> ArrayRef< T >
void consumeError(Error Err)
Consume a Error without doing anything.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
bool operator<(const ImpliedExtsEntry &Other) const
Represents the major and version number components of a RISC-V extension.