27 struct RISCVExtensionVersion {
32 struct RISCVSupportedExtension {
43 {
"i", RISCVExtensionVersion{2, 0}},
44 {
"e", RISCVExtensionVersion{1, 9}},
45 {
"m", RISCVExtensionVersion{2, 0}},
46 {
"a", RISCVExtensionVersion{2, 0}},
47 {
"f", RISCVExtensionVersion{2, 0}},
48 {
"d", RISCVExtensionVersion{2, 0}},
49 {
"c", RISCVExtensionVersion{2, 0}},
51 {
"zihintpause", RISCVExtensionVersion{2, 0}},
53 {
"zfhmin", RISCVExtensionVersion{1, 0}},
54 {
"zfh", RISCVExtensionVersion{1, 0}},
56 {
"zfinx", RISCVExtensionVersion{1, 0}},
57 {
"zdinx", RISCVExtensionVersion{1, 0}},
58 {
"zhinxmin", RISCVExtensionVersion{1, 0}},
59 {
"zhinx", RISCVExtensionVersion{1, 0}},
61 {
"zba", RISCVExtensionVersion{1, 0}},
62 {
"zbb", RISCVExtensionVersion{1, 0}},
63 {
"zbc", RISCVExtensionVersion{1, 0}},
64 {
"zbs", RISCVExtensionVersion{1, 0}},
66 {
"zbkb", RISCVExtensionVersion{1, 0}},
67 {
"zbkc", RISCVExtensionVersion{1, 0}},
68 {
"zbkx", RISCVExtensionVersion{1, 0}},
69 {
"zknd", RISCVExtensionVersion{1, 0}},
70 {
"zkne", RISCVExtensionVersion{1, 0}},
71 {
"zknh", RISCVExtensionVersion{1, 0}},
72 {
"zksed", RISCVExtensionVersion{1, 0}},
73 {
"zksh", RISCVExtensionVersion{1, 0}},
74 {
"zkr", RISCVExtensionVersion{1, 0}},
75 {
"zkn", RISCVExtensionVersion{1, 0}},
76 {
"zks", RISCVExtensionVersion{1, 0}},
77 {
"zkt", RISCVExtensionVersion{1, 0}},
78 {
"zk", RISCVExtensionVersion{1, 0}},
80 {
"v", RISCVExtensionVersion{1, 0}},
81 {
"zvl32b", RISCVExtensionVersion{1, 0}},
82 {
"zvl64b", RISCVExtensionVersion{1, 0}},
83 {
"zvl128b", RISCVExtensionVersion{1, 0}},
84 {
"zvl256b", RISCVExtensionVersion{1, 0}},
85 {
"zvl512b", RISCVExtensionVersion{1, 0}},
86 {
"zvl1024b", RISCVExtensionVersion{1, 0}},
87 {
"zvl2048b", RISCVExtensionVersion{1, 0}},
88 {
"zvl4096b", RISCVExtensionVersion{1, 0}},
89 {
"zvl8192b", RISCVExtensionVersion{1, 0}},
90 {
"zvl16384b", RISCVExtensionVersion{1, 0}},
91 {
"zvl32768b", RISCVExtensionVersion{1, 0}},
92 {
"zvl65536b", RISCVExtensionVersion{1, 0}},
93 {
"zve32x", RISCVExtensionVersion{1, 0}},
94 {
"zve32f", RISCVExtensionVersion{1, 0}},
95 {
"zve64x", RISCVExtensionVersion{1, 0}},
96 {
"zve64f", RISCVExtensionVersion{1, 0}},
97 {
"zve64d", RISCVExtensionVersion{1, 0}},
101 {
"zbe", RISCVExtensionVersion{0, 93}},
102 {
"zbf", RISCVExtensionVersion{0, 93}},
103 {
"zbm", RISCVExtensionVersion{0, 93}},
104 {
"zbp", RISCVExtensionVersion{0, 93}},
105 {
"zbr", RISCVExtensionVersion{0, 93}},
106 {
"zbt", RISCVExtensionVersion{0, 93}},
107 {
"zvfh", RISCVExtensionVersion{0, 1}},
111 return Ext.consume_front(
"experimental-");
123 "Already guarded by if-statement in ::parseArchString");
125 int Pos =
Ext.size() - 1;
140 return ExtInfo.Name ==
Ext;
151 if (ExtensionInfoIterator == ExtInfo.end()) {
154 return ExtensionInfoIterator->Version;
159 void RISCVISAInfo::addExtension(
StringRef ExtName,
unsigned MajorVersion,
160 unsigned MinorVersion) {
162 Ext.ExtName = ExtName.
str();
163 Ext.MajorVersion = MajorVersion;
164 Ext.MinorVersion = MinorVersion;
165 Exts[ExtName.
str()] =
Ext;
169 if (
Ext.startswith(
"sx"))
170 return "non-standard supervisor-level extension";
171 if (
Ext.startswith(
"s"))
172 return "standard supervisor-level extension";
173 if (
Ext.startswith(
"x"))
174 return "non-standard user-level extension";
175 if (
Ext.startswith(
"z"))
176 return "standard user-level extension";
181 if (
Ext.startswith(
"sx"))
183 if (
Ext.startswith(
"s"))
185 if (
Ext.startswith(
"x"))
187 if (
Ext.startswith(
"z"))
198 return ExtIterator->Version;
216 unsigned MinorVersion) {
217 auto FindByNameAndVersion = [=](
const RISCVSupportedExtension &ExtInfo) {
218 return ExtInfo.Name ==
Ext && (MajorVersion == ExtInfo.Version.Major) &&
219 (MinorVersion == ExtInfo.Version.Minor);
231 return Exts.count(
Ext.str()) != 0;
261 assert(ExtName.length() >= 2);
265 char ExtClass = ExtName[0];
287 return (HighOrder << 8) + LowOrder;
293 const std::string &
RHS) {
294 size_t LHSLen =
LHS.length();
295 size_t RHSLen =
RHS.length();
296 if (LHSLen == 1 && RHSLen != 1)
299 if (LHSLen != 1 && RHSLen == 1)
302 if (LHSLen == 1 && RHSLen == 1)
309 if (LHSRank != RHSRank)
310 return LHSRank < RHSRank;
317 std::vector<StringRef> &Features,
319 for (
auto const &
Ext : Exts) {
326 Features.push_back(StrAlloc(
"+experimental-" + ExtName));
328 Features.push_back(StrAlloc(
"+" + ExtName));
339 unsigned &Minor,
unsigned &ConsumeLength,
340 bool EnableExperimentalExtension,
341 bool ExperimentalExtensionVersionCheck) {
349 if (!MajorStr.
empty() &&
In.consume_front(
"p")) {
351 In =
In.substr(MajorStr.
size() + 1);
354 if (MinorStr.
empty()) {
357 "minor version number missing after 'p' for extension '" +
Ext +
"'");
364 "Failed to parse major version number for extension '" +
Ext +
"'");
369 "Failed to parse minor version number for extension '" +
Ext +
"'");
371 ConsumeLength = MajorStr.
size();
373 if (!MinorStr.
empty())
374 ConsumeLength += MinorStr.
size() + 1 ;
379 if (
Ext.size() > 1 &&
In.size()) {
381 "multi-character extensions must be separated by underscores";
387 if (!EnableExperimentalExtension) {
388 std::string
Error =
"requires '-menable-experimental-extensions' for "
389 "experimental extension '" +
394 if (ExperimentalExtensionVersionCheck &&
397 "experimental extension requires explicit version number `" +
402 auto SupportedVers = *ExperimentalExtension;
403 if (ExperimentalExtensionVersionCheck &&
404 (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
405 std::string
Error =
"unsupported version number " + MajorStr.
str();
406 if (!MinorStr.
empty())
408 Error +=
" for experimental extension '" +
Ext.str() +
409 "' (this compiler supports " + utostr(SupportedVers.Major) +
410 "." + utostr(SupportedVers.Minor) +
")";
423 Major = DefaultVersion->Major;
424 Minor = DefaultVersion->Minor;
434 std::string
Error =
"unsupported version number " + std::string(MajorStr);
435 if (!MinorStr.
empty())
437 Error +=
" for extension '" +
Ext.str() +
"'";
443 const std::vector<std::string> &Features) {
444 assert(XLen == 32 || XLen == 64);
445 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
447 for (
auto &Feature : Features) {
449 bool Experimental =
false;
450 assert(ExtName.
size() > 1 && (ExtName[0] ==
'+' || ExtName[0] ==
'-'));
451 bool Add = ExtName[0] ==
'+';
454 auto ExtensionInfos = Experimental
457 auto ExtensionInfoIterator =
462 if (ExtensionInfoIterator == ExtensionInfos.end())
466 ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
467 ExtensionInfoIterator->Version.Minor);
469 ISAInfo->Exts.erase(ExtName.
str());
472 return RISCVISAInfo::postProcessAndChecking(
std::move(ISAInfo));
477 bool ExperimentalExtensionVersionCheck) {
481 "string must be lowercase");
488 "string must begin with rv32{i,e,g} or rv64{i,g}");
491 unsigned XLen = HasRV64 ? 64 : 32;
492 std::unique_ptr<RISCVISAInfo> ISAInfo(
new RISCVISAInfo(XLen));
497 char Baseline = Arch[4];
503 "first letter should be 'e', 'i' or 'g'");
509 "standard user-level extension 'e' requires 'rv32'");
530 OtherExts = Exts.
substr(Pos);
531 Exts = Exts.
substr(0, Pos);
534 unsigned Major, Minor, ConsumeLength;
536 ConsumeLength, EnableExperimentalExtension,
537 ExperimentalExtensionVersionCheck))
540 if (Baseline ==
'g') {
544 for (
auto Ext : {
"i",
"m",
"a",
"f",
"d"})
551 ISAInfo->addExtension(std::string(1, Baseline), Major, Minor);
560 auto StdExtsItr = StdExts.
begin();
561 auto StdExtsEnd = StdExts.
end();
566 while (StdExtsItr != StdExtsEnd && *StdExtsItr !=
C)
569 if (StdExtsItr == StdExtsEnd) {
575 "standard user-level extension not given in canonical order '%c'",
580 "invalid standard user-level extension '%c'",
C);
587 unsigned Major, Minor, ConsumeLength;
588 if (std::next(
I) !=
E)
589 Next = std::string(std::next(
I),
E);
591 ConsumeLength, EnableExperimentalExtension,
592 ExperimentalExtensionVersionCheck))
598 StringRef SupportedStandardExtension =
"mafdcbv";
599 if (!SupportedStandardExtension.
contains(
C))
601 "unsupported standard user-level extension '%c'",
603 ISAInfo->addExtension(std::string(1,
C), Major, Minor);
626 OtherExts.
split(Split,
'_');
629 std::array<StringRef, 4>
Prefix{
"z",
"x",
"s",
"sx"};
632 if (Split.size() > 1 || Split[0] !=
"") {
636 "extension name missing after separator '_'");
646 "invalid extension prefix '" +
Ext +
"'");
654 "%s not given in canonical order '%s'",
655 Desc.
str().c_str(),
Ext.str().c_str());
659 "%s name missing after '%s'",
660 Desc.
str().c_str(),
Type.str().c_str());
663 unsigned Major, Minor, ConsumeLength;
665 EnableExperimentalExtension,
666 ExperimentalExtensionVersionCheck))
672 Desc.
str().c_str(),
Name.str().c_str());
674 ISAInfo->addExtension(
Name, Major, Minor);
677 AllExts.push_back(
Name);
681 for (
auto Ext : AllExts) {
685 Desc.
str().c_str(),
Ext.str().c_str());
689 return RISCVISAInfo::postProcessAndChecking(
std::move(ISAInfo));
692 Error RISCVISAInfo::checkDependency() {
693 bool IsRv32 = XLen == 32;
694 bool HasE = Exts.count(
"e") != 0;
695 bool HasD = Exts.count(
"d") != 0;
696 bool HasF = Exts.count(
"f") != 0;
697 bool HasZfinx = Exts.count(
"zfinx") != 0;
698 bool HasZdinx = Exts.count(
"zdinx") != 0;
699 bool HasVector = Exts.count(
"zve32x") != 0;
700 bool HasZve32f = Exts.count(
"zve32f") != 0;
701 bool HasZve64d = Exts.count(
"zve64d") != 0;
702 bool HasZvl = MinVLen != 0;
707 "standard user-level extension 'e' requires 'rv32'");
715 "d requires f extension to also be specified");
717 if (HasZve32f && !HasF && !HasZfinx)
720 "zve32f requires f or zfinx extension to also be specified");
722 if (HasZve64d && !HasD && !HasZdinx)
725 "zve64d requires d or zdinx extension to also be specified");
727 if (Exts.count(
"zvfh") && !Exts.count(
"zfh") && !Exts.count(
"zfhmin") &&
728 !Exts.count(
"zhinx") && !Exts.count(
"zhinxmin"))
731 "zvfh requires zfh, zfhmin, zhinx or zhinxmin extension to also be "
734 if (HasZvl && !HasVector)
737 "zvl*b requires v or zve* extension to also be specified");
769 static const char *
ImpliedExtsZkn[] = {
"zbkb",
"zbkc",
"zbkx",
"zkne",
"zknd",
"zknh"};
814 void RISCVISAInfo::updateImplication() {
815 bool HasE = Exts.count(
"e") != 0;
816 bool HasI = Exts.count(
"i") != 0;
820 if (!HasE && !HasI) {
830 for (
auto const &
Ext : Exts)
833 while (!WorkList.
empty()) {
837 for (
const char *ImpliedExt :
I->Exts) {
838 if (WorkList.
count(ImpliedExt))
840 if (Exts.count(ImpliedExt))
844 WorkList.
insert(ImpliedExt);
861 void RISCVISAInfo::updateCombination() {
862 bool IsNewCombine =
false;
864 IsNewCombine =
false;
866 auto CombineExt = CombineIntoExt.CombineExt;
867 auto RequiredExts = CombineIntoExt.RequiredExts;
870 bool IsAllRequiredFeatureExist =
true;
871 for (
const char *
Ext : RequiredExts)
873 if (IsAllRequiredFeatureExist) {
879 }
while (IsNewCombine);
882 void RISCVISAInfo::updateFLen() {
887 else if (Exts.count(
"f"))
891 void RISCVISAInfo::updateMinVLen() {
892 for (
auto const &
Ext : Exts) {
898 MinVLen =
std::max(MinVLen, ZvlLen);
903 void RISCVISAInfo::updateMaxELen() {
905 for (
auto const &
Ext : Exts) {
909 if (ExtName.
back() ==
'f')
910 MaxELenFp =
std::max(MaxELenFp, 32u);
911 if (ExtName.
back() ==
'd')
912 MaxELenFp =
std::max(MaxELenFp, 64u);
916 MaxELen =
std::max(MaxELen, ZveELen);
925 Arch <<
"rv" << XLen;
927 ListSeparator
LS(
"_");
928 for (
auto const &
Ext : Exts) {
930 auto ExtInfo =
Ext.second;
931 Arch <<
LS << ExtName;
932 Arch << ExtInfo.MajorVersion <<
"p" << ExtInfo.MinorVersion;
939 std::vector<std::string> FeatureVector;
940 for (
auto const &
Ext : Exts) {
941 std::string ExtName =
Ext.first;
945 ?
"+experimental-" + ExtName
947 FeatureVector.push_back(Feature);
949 return FeatureVector;
953 RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
954 ISAInfo->updateImplication();
955 ISAInfo->updateCombination();
956 ISAInfo->updateFLen();
957 ISAInfo->updateMinVLen();
958 ISAInfo->updateMaxELen();
960 if (
Error Result = ISAInfo->checkDependency())
972 }
else if (XLen == 64) {