aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/RISCVISAInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/RISCVISAInfo.cpp')
-rw-r--r--llvm/lib/Support/RISCVISAInfo.cpp106
1 files changed, 87 insertions, 19 deletions
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 2b3395b669b8..7fe04af4696b 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -37,7 +37,7 @@ struct RISCVSupportedExtension {
} // end anonymous namespace
-static constexpr StringLiteral AllStdExts = "mafdqlcbjtpvn";
+static constexpr StringLiteral AllStdExts = "mafdqlcbkjtpvn";
static const RISCVSupportedExtension SupportedExtensions[] = {
{"i", RISCVExtensionVersion{2, 0}},
@@ -48,9 +48,16 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"d", RISCVExtensionVersion{2, 0}},
{"c", RISCVExtensionVersion{2, 0}},
+ {"zihintpause", RISCVExtensionVersion{2, 0}},
+
{"zfhmin", RISCVExtensionVersion{1, 0}},
{"zfh", RISCVExtensionVersion{1, 0}},
+ {"zfinx", RISCVExtensionVersion{1, 0}},
+ {"zdinx", RISCVExtensionVersion{1, 0}},
+ {"zhinxmin", RISCVExtensionVersion{1, 0}},
+ {"zhinx", RISCVExtensionVersion{1, 0}},
+
{"zba", RISCVExtensionVersion{1, 0}},
{"zbb", RISCVExtensionVersion{1, 0}},
{"zbc", RISCVExtensionVersion{1, 0}},
@@ -88,6 +95,10 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"zve64x", RISCVExtensionVersion{1, 0}},
{"zve64f", RISCVExtensionVersion{1, 0}},
{"zve64d", RISCVExtensionVersion{1, 0}},
+
+ {"zicbom", RISCVExtensionVersion{1, 0}},
+ {"zicboz", RISCVExtensionVersion{1, 0}},
+ {"zicbop", RISCVExtensionVersion{1, 0}},
};
static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
@@ -97,6 +108,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zbp", RISCVExtensionVersion{0, 93}},
{"zbr", RISCVExtensionVersion{0, 93}},
{"zbt", RISCVExtensionVersion{0, 93}},
+ {"zvfh", RISCVExtensionVersion{0, 1}},
};
static bool stripExperimentalPrefix(StringRef &Ext) {
@@ -340,7 +352,7 @@ static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major,
if (!MajorStr.empty() && In.consume_front("p")) {
MinorStr = In.take_while(isDigit);
- In = In.substr(MajorStr.size() + 1);
+ In = In.substr(MajorStr.size() + MinorStr.size() - 1);
// Expected 'p' to be followed by minor version number.
if (MinorStr.empty()) {
@@ -398,8 +410,8 @@ static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major,
if (!MinorStr.empty())
Error += "." + MinorStr.str();
Error += " for experimental extension '" + Ext.str() +
- "'(this compiler supports " + utostr(SupportedVers.Major) + "." +
- utostr(SupportedVers.Minor) + ")";
+ "' (this compiler supports " + utostr(SupportedVers.Major) +
+ "." + utostr(SupportedVers.Minor) + ")";
return createStringError(errc::invalid_argument, Error);
}
return Error::success();
@@ -686,11 +698,11 @@ Error RISCVISAInfo::checkDependency() {
bool HasE = Exts.count("e") != 0;
bool HasD = Exts.count("d") != 0;
bool HasF = Exts.count("f") != 0;
- bool HasZve32x = Exts.count("zve32x") != 0;
+ bool HasZfinx = Exts.count("zfinx") != 0;
+ bool HasZdinx = Exts.count("zdinx") != 0;
+ bool HasVector = Exts.count("zve32x") != 0;
bool HasZve32f = Exts.count("zve32f") != 0;
bool HasZve64d = Exts.count("zve64d") != 0;
- bool HasV = Exts.count("v") != 0;
- bool HasVector = HasZve32x || HasV;
bool HasZvl = MinVLen != 0;
if (HasE && !IsRv32)
@@ -706,17 +718,22 @@ Error RISCVISAInfo::checkDependency() {
return createStringError(errc::invalid_argument,
"d requires f extension to also be specified");
- // FIXME: Consider Zfinx in the future
- if (HasZve32f && !HasF)
+ if (HasZve32f && !HasF && !HasZfinx)
+ return createStringError(
+ errc::invalid_argument,
+ "zve32f requires f or zfinx extension to also be specified");
+
+ if (HasZve64d && !HasD && !HasZdinx)
return createStringError(
errc::invalid_argument,
- "zve32f requires f extension to also be specified");
+ "zve64d requires d or zdinx extension to also be specified");
- // FIXME: Consider Zdinx in the future
- if (HasZve64d && !HasD)
+ if (Exts.count("zvfh") && !Exts.count("zfh") && !Exts.count("zfhmin") &&
+ !Exts.count("zhinx") && !Exts.count("zhinxmin"))
return createStringError(
errc::invalid_argument,
- "zve64d requires d extension to also be specified");
+ "zvfh requires zfh, zfhmin, zhinx or zhinxmin extension to also be "
+ "specified");
if (HasZvl && !HasVector)
return createStringError(
@@ -730,9 +747,12 @@ Error RISCVISAInfo::checkDependency() {
return Error::success();
}
-static const char *ImpliedExtsV[] = {"zvl128b", "f", "d"};
+static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"};
static const char *ImpliedExtsZfhmin[] = {"f"};
static const char *ImpliedExtsZfh[] = {"f"};
+static const char *ImpliedExtsZdinx[] = {"zfinx"};
+static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
+static const char *ImpliedExtsZhinx[] = {"zfinx"};
static const char *ImpliedExtsZve64d[] = {"zve64f"};
static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"};
static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"};
@@ -752,6 +772,7 @@ static const char *ImpliedExtsZvl64b[] = {"zvl32b"};
static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"};
static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"};
static const char *ImpliedExtsZks[] = {"zbkb", "zbkc", "zbkx", "zksed", "zksh"};
+static const char *ImpliedExtsZvfh[] = {"zve32f"};
struct ImpliedExtsEntry {
StringLiteral Name;
@@ -767,8 +788,11 @@ struct ImpliedExtsEntry {
// Note: The table needs to be sorted by name.
static constexpr ImpliedExtsEntry ImpliedExts[] = {
{{"v"}, {ImpliedExtsV}},
+ {{"zdinx"}, {ImpliedExtsZdinx}},
{{"zfh"}, {ImpliedExtsZfh}},
{{"zfhmin"}, {ImpliedExtsZfhmin}},
+ {{"zhinx"}, {ImpliedExtsZhinx}},
+ {{"zhinxmin"}, {ImpliedExtsZhinxmin}},
{{"zk"}, {ImpliedExtsZk}},
{{"zkn"}, {ImpliedExtsZkn}},
{{"zks"}, {ImpliedExtsZks}},
@@ -777,6 +801,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
{{"zve64d"}, {ImpliedExtsZve64d}},
{{"zve64f"}, {ImpliedExtsZve64f}},
{{"zve64x"}, {ImpliedExtsZve64x}},
+ {{"zvfh"}, {ImpliedExtsZvfh}},
{{"zvl1024b"}, {ImpliedExtsZvl1024b}},
{{"zvl128b"}, {ImpliedExtsZvl128b}},
{{"zvl16384b"}, {ImpliedExtsZvl16384b}},
@@ -826,6 +851,38 @@ void RISCVISAInfo::updateImplication() {
}
}
+struct CombinedExtsEntry {
+ StringLiteral CombineExt;
+ ArrayRef<const char *> RequiredExts;
+};
+
+static constexpr CombinedExtsEntry CombineIntoExts[] = {
+ {{"zk"}, {ImpliedExtsZk}},
+ {{"zkn"}, {ImpliedExtsZkn}},
+ {{"zks"}, {ImpliedExtsZks}},
+};
+
+void RISCVISAInfo::updateCombination() {
+ bool IsNewCombine = false;
+ do {
+ IsNewCombine = false;
+ for (CombinedExtsEntry CombineIntoExt : CombineIntoExts) {
+ auto CombineExt = CombineIntoExt.CombineExt;
+ auto RequiredExts = CombineIntoExt.RequiredExts;
+ if (hasExtension(CombineExt))
+ continue;
+ bool IsAllRequiredFeatureExist = true;
+ for (const char *Ext : RequiredExts)
+ IsAllRequiredFeatureExist &= hasExtension(Ext);
+ if (IsAllRequiredFeatureExist) {
+ auto Version = findDefaultVersion(CombineExt);
+ addExtension(CombineExt, Version->Major, Version->Minor);
+ IsNewCombine = true;
+ }
+ }
+ } while (IsNewCombine);
+}
+
void RISCVISAInfo::updateFLen() {
FLen = 0;
// TODO: Handle q extension.
@@ -862,11 +919,6 @@ void RISCVISAInfo::updateMaxELen() {
ExtName.getAsInteger(10, ZveELen);
MaxELen = std::max(MaxELen, ZveELen);
}
- if (ExtName == "v") {
- MaxELenFp = 64;
- MaxELen = 64;
- return;
- }
}
}
@@ -904,6 +956,7 @@ std::vector<std::string> RISCVISAInfo::toFeatureVector() const {
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
ISAInfo->updateImplication();
+ ISAInfo->updateCombination();
ISAInfo->updateFLen();
ISAInfo->updateMinVLen();
ISAInfo->updateMaxELen();
@@ -912,3 +965,18 @@ RISCVISAInfo::postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo) {
return std::move(Result);
return std::move(ISAInfo);
}
+
+StringRef RISCVISAInfo::computeDefaultABI() const {
+ if (XLen == 32) {
+ if (hasExtension("d"))
+ return "ilp32d";
+ if (hasExtension("e"))
+ return "ilp32e";
+ return "ilp32";
+ } else if (XLen == 64) {
+ if (hasExtension("d"))
+ return "lp64d";
+ return "lp64";
+ }
+ llvm_unreachable("Invalid XLEN");
+}