Index: clang/include/clang/Basic/BuiltinsRISCV.def =================================================================== --- clang/include/clang/Basic/BuiltinsRISCV.def +++ clang/include/clang/Basic/BuiltinsRISCV.def @@ -16,46 +16,46 @@ #endif // Zbb extension -TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "experimental-zbb") -TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "experimental-zbb,64bit") +TARGET_BUILTIN(__builtin_riscv_orc_b_32, "ZiZi", "nc", "experimental-zbb1p0") +TARGET_BUILTIN(__builtin_riscv_orc_b_64, "WiWi", "nc", "experimental-zbb1p0,64bit") // Zbc extension -TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "experimental-zbc") -TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "experimental-zbc") -TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "experimental-zbc") +TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "experimental-zbc1p0") +TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "experimental-zbc1p0") +TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "experimental-zbc1p0") // Zbe extension -TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe") +TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe0p93") TARGET_BUILTIN(__builtin_riscv_bcompress_64, "WiWiWi", "nc", - "experimental-zbe,64bit") + "experimental-zbe0p93,64bit") TARGET_BUILTIN(__builtin_riscv_bdecompress_32, "ZiZiZi", "nc", - "experimental-zbe") + "experimental-zbe0p93") TARGET_BUILTIN(__builtin_riscv_bdecompress_64, "WiWiWi", "nc", - "experimental-zbe,64bit") + "experimental-zbe0p93,64bit") // Zbp extension -TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit") -TARGET_BUILTIN(__builtin_riscv_gorc_32, "ZiZiZi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_gorc_64, "WiWiWi", "nc", "experimental-zbp,64bit") -TARGET_BUILTIN(__builtin_riscv_shfl_32, "ZiZiZi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_shfl_64, "WiWiWi", "nc", "experimental-zbp,64bit") -TARGET_BUILTIN(__builtin_riscv_unshfl_32, "ZiZiZi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_unshfl_64, "WiWiWi", "nc", "experimental-zbp,64bit") -TARGET_BUILTIN(__builtin_riscv_xperm_n, "LiLiLi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_xperm_b, "LiLiLi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_xperm_h, "LiLiLi", "nc", "experimental-zbp") -TARGET_BUILTIN(__builtin_riscv_xperm_w, "WiWiWi", "nc", "experimental-zbp,64bit") +TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp0p93,64bit") +TARGET_BUILTIN(__builtin_riscv_gorc_32, "ZiZiZi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_gorc_64, "WiWiWi", "nc", "experimental-zbp0p93,64bit") +TARGET_BUILTIN(__builtin_riscv_shfl_32, "ZiZiZi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_shfl_64, "WiWiWi", "nc", "experimental-zbp0p93,64bit") +TARGET_BUILTIN(__builtin_riscv_unshfl_32, "ZiZiZi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_unshfl_64, "WiWiWi", "nc", "experimental-zbp0p93,64bit") +TARGET_BUILTIN(__builtin_riscv_xperm_n, "LiLiLi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_xperm_b, "LiLiLi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_xperm_h, "LiLiLi", "nc", "experimental-zbp0p93") +TARGET_BUILTIN(__builtin_riscv_xperm_w, "WiWiWi", "nc", "experimental-zbp0p93,64bit") // Zbr extension -TARGET_BUILTIN(__builtin_riscv_crc32_b, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32_h, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32_w, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32c_b, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32c_h, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32c_w, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr") -TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr") +TARGET_BUILTIN(__builtin_riscv_crc32_b, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32_h, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32_w, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32c_b, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32c_h, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32c_w, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr0p93") +TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr0p93") #undef BUILTIN #undef TARGET_BUILTIN Index: clang/lib/Basic/Targets/RISCV.cpp =================================================================== --- clang/lib/Basic/Targets/RISCV.cpp +++ clang/lib/Basic/Targets/RISCV.cpp @@ -150,7 +150,7 @@ auto ExtName = Extension.first; auto ExtInfo = Extension.second; unsigned Version = - (ExtInfo.MajorVersion * 1000000) + (ExtInfo.MinorVersion * 1000); + (ExtInfo.Version.Major * 1000000) + (ExtInfo.Version.Minor * 1000); Builder.defineMacro(Twine("__riscv_", ExtName), Twine(Version)); } @@ -223,8 +223,9 @@ if (Result.hasValue()) return Result.getValue(); - if (ISAInfo->isSupportedExtensionFeature(Feature)) - return ISAInfo->hasExtension(Feature); + if (ISAInfo->isSupportedExtensionFeature(Feature)) { + return ISAInfo->hasExtensionWithVersion(Feature); + } return false; } Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -41,8 +41,12 @@ return false; } - (*ISAInfo)->toFeatures( - Features, [&Args](const Twine &Str) { return Args.MakeArgString(Str); }); + std::vector ToFeatures; + (*ISAInfo)->toFeatures(ToFeatures); + + for (const auto &Feature : ToFeatures) + Features.push_back(Args.MakeArgString("+" + Feature)); + return true; } Index: clang/utils/TableGen/RISCVVEmitter.cpp =================================================================== --- clang/utils/TableGen/RISCVVEmitter.cpp +++ clang/utils/TableGen/RISCVVEmitter.cpp @@ -1021,7 +1021,7 @@ OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n"; OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, " - "ATTRS, \"experimental-v\")\n"; + "ATTRS, \"experimental-v0p10\")\n"; OS << "#endif\n"; for (auto &Def : Defs) { auto P = Index: llvm/include/llvm/Support/RISCVISAInfo.h =================================================================== --- llvm/include/llvm/Support/RISCVISAInfo.h +++ llvm/include/llvm/Support/RISCVISAInfo.h @@ -19,10 +19,29 @@ #include namespace llvm { + +/// Represents the major and version number components of a RISC-V extension +struct RISCVExtensionVersion { + unsigned Major; + unsigned Minor; + + bool operator==(const RISCVExtensionVersion &Version) const { + return Major == Version.Major && Minor == Version.Minor; + } + + bool operator!=(const RISCVExtensionVersion &Version) const { + return !operator==(Version); + } + + bool operator<(const RISCVExtensionVersion &Version) const { + return (Major < Version.Major) || + (Major == Version.Major && Minor < Version.Minor); + } +}; + struct RISCVExtensionInfo { std::string ExtName; - unsigned MajorVersion; - unsigned MinorVersion; + RISCVExtensionVersion Version; }; class RISCVISAInfo { @@ -47,15 +66,15 @@ /// Parse RISCV ISA info from arch string. static llvm::Expected> parseArchString(StringRef Arch, bool EnableExperimentalExtension, - bool ExperimentalExtensionVersionCheck = true); + bool ExperimentalExtensionVersionCheck = true, + bool IgnoreUnknownExtension = false); /// Parse RISCV ISA info from feature vector. static llvm::Expected> parseFeatures(unsigned XLen, const std::vector &Features); /// Convert RISCV ISA info to a feature vector. - void toFeatures(std::vector &Features, - std::function StrAlloc) const; + void toFeatures(std::vector &Features) const; const OrderedExtensionMap &getExtensions() const { return Exts; }; @@ -63,6 +82,7 @@ unsigned getFLen() const { return FLen; }; bool hasExtension(StringRef Ext) const; + bool hasExtensionWithVersion(StringRef Ext) const; std::string toString() const; static bool isSupportedExtensionFeature(StringRef Ext); Index: llvm/lib/Object/ELFObjectFile.cpp =================================================================== --- llvm/lib/Object/ELFObjectFile.cpp +++ llvm/lib/Object/ELFObjectFile.cpp @@ -26,6 +26,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/RISCVAttributeParser.h" #include "llvm/Support/RISCVAttributes.h" +#include "llvm/Support/RISCVISAInfo.h" #include #include #include @@ -292,7 +293,7 @@ unsigned PlatformFlags = getPlatformFlags(); if (PlatformFlags & ELF::EF_RISCV_RVC) { - Features.AddFeature("c"); + Features.AddFeature("c2p0"); } // Add features according to the ELF attribute section. @@ -306,38 +307,23 @@ Optional Attr = Attributes.getAttributeString(RISCVAttrs::ARCH); if (Attr.hasValue()) { - // The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)* - // Version string pattern is (major)p(minor). Major and minor are optional. - // For example, a version number could be 2p0, 2, or p92. - StringRef Arch = Attr.getValue(); - if (Arch.consume_front("rv32")) + auto ParseResult = + llvm::RISCVISAInfo::parseArchString(Attr.getValue(), true, true, true); + if (!ParseResult) + return Features; + + auto &ISAInfo = *ParseResult; + + if (ISAInfo->getXLen() == 32) Features.AddFeature("64bit", false); - else if (Arch.consume_front("rv64")) + else if (ISAInfo->getXLen() == 64) Features.AddFeature("64bit"); - while (!Arch.empty()) { - switch (Arch[0]) { - default: - break; // Ignore unexpected features. - case 'i': - Features.AddFeature("e", false); - break; - case 'd': - Features.AddFeature("f"); // D-ext will imply F-ext. - LLVM_FALLTHROUGH; - case 'e': - case 'm': - case 'a': - case 'f': - case 'c': - Features.AddFeature(Arch.take_front()); - break; - } - - // FIXME: Handle version numbers. - Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; }); - Arch = Arch.drop_while([](char c) { return c == '_'; }); - } + std::vector ToFeatures; + ISAInfo->toFeatures(ToFeatures); + + for (const auto &Feature : ToFeatures) + Features.AddFeature(Feature); } return Features; Index: llvm/lib/Support/RISCVISAInfo.cpp =================================================================== --- llvm/lib/Support/RISCVISAInfo.cpp +++ llvm/lib/Support/RISCVISAInfo.cpp @@ -22,11 +22,6 @@ using namespace llvm; namespace { -/// Represents the major and version number components of a RISC-V extension -struct RISCVExtensionVersion { - unsigned Major; - unsigned Minor; -}; struct RISCVSupportedExtension { const char *Name; @@ -68,6 +63,11 @@ {"zfh", RISCVExtensionVersion{0, 1}}, }; +static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major, + unsigned &Minor, unsigned &ConsumeLength, + bool EnableExperimentalExtension, + bool ExperimentalExtensionVersionCheck); + static bool stripExperimentalPrefix(StringRef &Ext) { return Ext.consume_front("experimental-"); } @@ -121,8 +121,8 @@ unsigned MinorVersion) { RISCVExtensionInfo Ext; Ext.ExtName = ExtName.str(); - Ext.MajorVersion = MajorVersion; - Ext.MinorVersion = MinorVersion; + Ext.Version.Major = MajorVersion; + Ext.Version.Minor = MinorVersion; Exts[ExtName.str()] = Ext; } @@ -160,12 +160,23 @@ } bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) { - bool IsExperimental = stripExperimentalPrefix(Ext); + stripExperimentalPrefix(Ext); - if (IsExperimental) - return llvm::any_of(SupportedExperimentalExtensions, FindByName(Ext)); - else - return llvm::any_of(SupportedExtensions, FindByName(Ext)); + auto Pos = findFirstNonVersionCharacter(Ext) + 1; + StringRef Name(Ext.substr(0, Pos)); + StringRef Vers(Ext.substr(Pos)); + + unsigned Major, Minor, ConsumeLength; + if (auto E = getExtensionVersion(Name, Vers, Major, Minor, ConsumeLength, + true, false)) { + consumeError(std::move(E)); + return false; + } + + if (!isSupportedExtension(Name, Major, Minor)) + return false; + + return true; } bool RISCVISAInfo::isSupportedExtension(StringRef Ext) { @@ -192,6 +203,18 @@ return Exts.count(Ext.str()) != 0; } +bool RISCVISAInfo::hasExtensionWithVersion(StringRef Ext) const { + stripExperimentalPrefix(Ext); + + auto Pos = findFirstNonVersionCharacter(Ext) + 1; + StringRef Name(Ext.substr(0, Pos)); + + if (!isSupportedExtension(Name)) + return false; + + return Exts.count(Name.str()) != 0; +} + // Get the rank for single-letter extension, lower value meaning higher // priority. static int singleLetterExtensionRank(char Ext) { @@ -274,26 +297,35 @@ return LHS < RHS; } -void RISCVISAInfo::toFeatures( - std::vector &Features, - std::function StrAlloc) const { +static std::string addVersionSuffix(Twine ExtName, unsigned Major, unsigned Minor) { + return (ExtName + Twine(Major) + "p" + Twine(Minor)).str(); +} + +void RISCVISAInfo::toFeatures(std::vector &Features) const { + for (auto &Ext : Exts) { StringRef ExtName = Ext.first; + auto Extension = Ext.second; + unsigned Major = Ext.second.Version.Major; + unsigned Minor = Ext.second.Version.Minor; if (ExtName == "i") continue; if (ExtName == "zvlsseg") { - Features.push_back("+experimental-v"); - Features.push_back("+experimental-zvlsseg"); + Features.push_back(addVersionSuffix("experimental-v", Major, Minor)); + Features.push_back( + addVersionSuffix("experimental-zvlsseg", Major, Minor)); } else if (ExtName == "zvamo") { - Features.push_back("+experimental-v"); - Features.push_back("+experimental-zvlsseg"); - Features.push_back("+experimental-zvamo"); + Features.push_back(addVersionSuffix("experimental-v", Major, Minor)); + Features.push_back( + addVersionSuffix("experimental-zvlsseg", Major, Minor)); + Features.push_back(addVersionSuffix("experimental-zvamo", Major, Minor)); } else if (isExperimentalExtension(ExtName)) { - Features.push_back(StrAlloc("+experimental-" + ExtName)); + Features.push_back( + addVersionSuffix("experimental-" + ExtName, Major, Minor)); } else { - Features.push_back(StrAlloc("+" + ExtName)); + Features.push_back(addVersionSuffix(ExtName, Major, Minor)); } } } @@ -419,11 +451,15 @@ bool Add = ExtName[0] == '+'; ExtName = ExtName.drop_front(1); // Drop '+' or '-' Experimental = stripExperimentalPrefix(ExtName); + auto Pos = findFirstNonVersionCharacter(ExtName) + 1; + StringRef Name(ExtName.substr(0, Pos)); + StringRef Vers(ExtName.substr(Pos)); + auto ExtensionInfos = Experimental ? makeArrayRef(SupportedExperimentalExtensions) : makeArrayRef(SupportedExtensions); auto ExtensionInfoIterator = - llvm::find_if(ExtensionInfos, FindByName(ExtName)); + llvm::find_if(ExtensionInfos, FindByName(Name)); // Not all features is related to ISA extension, like `relax` or // `save-restore`, skip those feature. @@ -431,10 +467,10 @@ continue; if (Add) - ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major, + ISAInfo->addExtension(Name, ExtensionInfoIterator->Version.Major, ExtensionInfoIterator->Version.Minor); else - ISAInfo->Exts.erase(ExtName.str()); + ISAInfo->Exts.erase(Name.str()); } ISAInfo->updateImplication(); @@ -448,7 +484,8 @@ llvm::Expected> RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, - bool ExperimentalExtensionVersionCheck) { + bool ExperimentalExtensionVersionCheck, + bool IgnoreUnknownExtension) { // RISC-V ISA strings must be lowercase. if (llvm::any_of(Arch, isupper)) { return createStringError(errc::invalid_argument, @@ -549,9 +586,10 @@ "standard user-level extension not given in canonical order '%c'", C); } - - return createStringError(errc::invalid_argument, - "invalid standard user-level extension '%c'", C); + if (!IgnoreUnknownExtension) + return createStringError(errc::invalid_argument, + "invalid standard user-level extension '%c'", + C); } // Move to next char to prevent repeated letter. @@ -563,18 +601,22 @@ Next = std::string(std::next(I), E); if (auto E = getExtensionVersion(std::string(1, C), Next, Major, Minor, ConsumeLength, EnableExperimentalExtension, - ExperimentalExtensionVersionCheck)) - return std::move(E); - - // The order is OK, then push it into features. - // TODO: Use version number when setting target features - // Currently LLVM supports only "mafdcbv". - StringRef SupportedStandardExtension = "mafdcbv"; - if (SupportedStandardExtension.find(C) == StringRef::npos) - return createStringError(errc::invalid_argument, - "unsupported standard user-level extension '%c'", - C); - ISAInfo->addExtension(std::string(1, C), Major, Minor); + ExperimentalExtensionVersionCheck)) { + if (IgnoreUnknownExtension) + consumeError(std::move(E)); + else + return std::move(E); + } else { + // The order is OK, then push it into features. + // TODO: Use version number when setting target features + // Currently LLVM supports only "mafdcbv". + StringRef SupportedStandardExtension = "mafdcbv"; + if (SupportedStandardExtension.find(C) == StringRef::npos) + return createStringError( + errc::invalid_argument, + "unsupported standard user-level extension '%c'", C); + ISAInfo->addExtension(std::string(1, C), Major, Minor); + } // Consume full extension name and version, including any optional '_' // between this extension and the next @@ -757,7 +799,7 @@ StringRef ExtName = Ext.first; auto ExtInfo = Ext.second; Arch << LS << ExtName; - Arch << ExtInfo.MajorVersion << "p" << ExtInfo.MinorVersion; + Arch << ExtInfo.Version.Major << "p" << ExtInfo.Version.Minor; } return Arch.str(); Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1990,7 +1990,7 @@ return Error(Parser.getTok().getLoc(), "unexpected token, expected end of statement"); - setFeatureBits(RISCV::FeatureStdExtC, "c"); + setFeatureBits(RISCV::FeatureStdExtC, "c2p0"); return false; } @@ -2002,7 +2002,7 @@ return Error(Parser.getTok().getLoc(), "unexpected token, expected end of statement"); - clearFeatureBits(RISCV::FeatureStdExtC, "c"); + clearFeatureBits(RISCV::FeatureStdExtC, "c2p0"); return false; } @@ -2154,7 +2154,7 @@ auto &ISAInfo = *ParseResult; for (auto Feature : RISCVFeatureKV) - if (ISAInfo->hasExtension(Feature.Key)) + if (ISAInfo->hasExtensionWithVersion(Feature.Key)) setFeatureBits(Feature.Value, Feature.Key); if (ISAInfo->getXLen() == 32) Index: llvm/lib/Target/RISCV/RISCV.td =================================================================== --- llvm/lib/Target/RISCV/RISCV.td +++ llvm/lib/Target/RISCV/RISCV.td @@ -13,28 +13,28 @@ //===----------------------------------------------------------------------===// def FeatureStdExtM - : SubtargetFeature<"m", "HasStdExtM", "true", + : SubtargetFeature<"m2p0", "StdExtM", "RISCVExtensionVersion{2, 0}", "'M' (Integer Multiplication and Division)">; def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">, AssemblerPredicate<(all_of FeatureStdExtM), "'M' (Integer Multiplication and Division)">; def FeatureStdExtA - : SubtargetFeature<"a", "HasStdExtA", "true", + : SubtargetFeature<"a2p0", "StdExtA", "RISCVExtensionVersion{2, 0}", "'A' (Atomic Instructions)">; def HasStdExtA : Predicate<"Subtarget->hasStdExtA()">, AssemblerPredicate<(all_of FeatureStdExtA), "'A' (Atomic Instructions)">; def FeatureStdExtF - : SubtargetFeature<"f", "HasStdExtF", "true", + : SubtargetFeature<"f2p0", "StdExtF", "RISCVExtensionVersion{2, 0}", "'F' (Single-Precision Floating-Point)">; def HasStdExtF : Predicate<"Subtarget->hasStdExtF()">, AssemblerPredicate<(all_of FeatureStdExtF), "'F' (Single-Precision Floating-Point)">; def FeatureStdExtD - : SubtargetFeature<"d", "HasStdExtD", "true", + : SubtargetFeature<"d2p0", "StdExtD", "RISCVExtensionVersion{2, 0}", "'D' (Double-Precision Floating-Point)", [FeatureStdExtF]>; def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">, @@ -42,7 +42,7 @@ "'D' (Double-Precision Floating-Point)">; def FeatureStdExtZfhmin - : SubtargetFeature<"experimental-zfhmin", "HasStdExtZfhmin", "true", + : SubtargetFeature<"experimental-zfhmin0p1", "StdExtZfhmin", "RISCVExtensionVersion{0, 1}", "'Zfhmin' (Half-Precision Floating-Point Minimal)", [FeatureStdExtF]>; def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">, @@ -50,7 +50,7 @@ "'Zfhmin' (Half-Precision Floating-Point Minimal)">; def FeatureStdExtZfh - : SubtargetFeature<"experimental-zfh", "HasStdExtZfh", "true", + : SubtargetFeature<"experimental-zfh0p1", "StdExtZfh", "RISCVExtensionVersion{0, 1}", "'Zfh' (Half-Precision Floating-Point)", [FeatureStdExtZfhmin, FeatureStdExtF]>; def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">, @@ -58,14 +58,14 @@ "'Zfh' (Half-Precision Floating-Point)">; def FeatureStdExtC - : SubtargetFeature<"c", "HasStdExtC", "true", + : SubtargetFeature<"c2p0", "StdExtC", "RISCVExtensionVersion{2, 0}", "'C' (Compressed Instructions)">; def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">, AssemblerPredicate<(all_of FeatureStdExtC), "'C' (Compressed Instructions)">; def FeatureStdExtZba - : SubtargetFeature<"experimental-zba", "HasStdExtZba", "true", + : SubtargetFeature<"experimental-zba1p0", "StdExtZba", "RISCVExtensionVersion{1, 0}", "'Zba' (Address calculation 'B' Instructions)">; def HasStdExtZba : Predicate<"Subtarget->hasStdExtZba()">, AssemblerPredicate<(all_of FeatureStdExtZba), @@ -73,63 +73,63 @@ def NotHasStdExtZba : Predicate<"!Subtarget->hasStdExtZba()">; def FeatureStdExtZbb - : SubtargetFeature<"experimental-zbb", "HasStdExtZbb", "true", + : SubtargetFeature<"experimental-zbb1p0", "StdExtZbb", "RISCVExtensionVersion{1, 0}", "'Zbb' (Base 'B' Instructions)">; def HasStdExtZbb : Predicate<"Subtarget->hasStdExtZbb()">, AssemblerPredicate<(all_of FeatureStdExtZbb), "'Zbb' (Base 'B' Instructions)">; def FeatureStdExtZbc - : SubtargetFeature<"experimental-zbc", "HasStdExtZbc", "true", + : SubtargetFeature<"experimental-zbc1p0", "StdExtZbc", "RISCVExtensionVersion{1, 0}", "'Zbc' (Carry-Less 'B' Instructions)">; def HasStdExtZbc : Predicate<"Subtarget->hasStdExtZbc()">, AssemblerPredicate<(all_of FeatureStdExtZbc), "'Zbc' (Carry-Less 'B' Instructions)">; def FeatureStdExtZbe - : SubtargetFeature<"experimental-zbe", "HasStdExtZbe", "true", + : SubtargetFeature<"experimental-zbe0p93", "StdExtZbe", "RISCVExtensionVersion{0, 93}", "'Zbe' (Extract-Deposit 'B' Instructions)">; def HasStdExtZbe : Predicate<"Subtarget->hasStdExtZbe()">, AssemblerPredicate<(all_of FeatureStdExtZbe), "'Zbe' (Extract-Deposit 'B' Instructions)">; def FeatureStdExtZbf - : SubtargetFeature<"experimental-zbf", "HasStdExtZbf", "true", + : SubtargetFeature<"experimental-zbf0p93", "StdExtZbf", "RISCVExtensionVersion{0, 93}", "'Zbf' (Bit-Field 'B' Instructions)">; def HasStdExtZbf : Predicate<"Subtarget->hasStdExtZbf()">, AssemblerPredicate<(all_of FeatureStdExtZbf), "'Zbf' (Bit-Field 'B' Instructions)">; def FeatureStdExtZbm - : SubtargetFeature<"experimental-zbm", "HasStdExtZbm", "true", + : SubtargetFeature<"experimental-zbm0p93", "StdExtZbm", "RISCVExtensionVersion{0, 93}", "'Zbm' (Matrix 'B' Instructions)">; def HasStdExtZbm : Predicate<"Subtarget->hasStdExtZbm()">, AssemblerPredicate<(all_of FeatureStdExtZbm), "'Zbm' (Matrix 'B' Instructions)">; def FeatureStdExtZbp - : SubtargetFeature<"experimental-zbp", "HasStdExtZbp", "true", + : SubtargetFeature<"experimental-zbp0p93", "StdExtZbp", "RISCVExtensionVersion{0, 93}", "'Zbp' (Permutation 'B' Instructions)">; def HasStdExtZbp : Predicate<"Subtarget->hasStdExtZbp()">, AssemblerPredicate<(all_of FeatureStdExtZbp), "'Zbp' (Permutation 'B' Instructions)">; def FeatureStdExtZbr - : SubtargetFeature<"experimental-zbr", "HasStdExtZbr", "true", + : SubtargetFeature<"experimental-zbr0p93", "StdExtZbr", "RISCVExtensionVersion{0, 93}", "'Zbr' (Polynomial Reduction 'B' Instructions)">; def HasStdExtZbr : Predicate<"Subtarget->hasStdExtZbr()">, AssemblerPredicate<(all_of FeatureStdExtZbr), "'Zbr' (Polynomial Reduction 'B' Instructions)">; def FeatureStdExtZbs - : SubtargetFeature<"experimental-zbs", "HasStdExtZbs", "true", + : SubtargetFeature<"experimental-zbs1p0", "StdExtZbs", "RISCVExtensionVersion{1, 0}", "'Zbs' (Single-Bit 'B' Instructions)">; def HasStdExtZbs : Predicate<"Subtarget->hasStdExtZbs()">, AssemblerPredicate<(all_of FeatureStdExtZbs), "'Zbs' (Single-Bit 'B' Instructions)">; def FeatureStdExtZbt - : SubtargetFeature<"experimental-zbt", "HasStdExtZbt", "true", + : SubtargetFeature<"experimental-zbt0p93", "StdExtZbt", "RISCVExtensionVersion{0, 93}", "'Zbt' (Ternary 'B' Instructions)">; def HasStdExtZbt : Predicate<"Subtarget->hasStdExtZbt()">, AssemblerPredicate<(all_of FeatureStdExtZbt), @@ -151,7 +151,7 @@ "RVC Hint Instructions">; def FeatureStdExtV - : SubtargetFeature<"experimental-v", "HasStdExtV", "true", + : SubtargetFeature<"experimental-v0p10", "StdExtV", "RISCVExtensionVersion{0, 10}", "'V' (Vector Instructions)">; def HasStdExtV : Predicate<"Subtarget->hasStdExtV()">, AssemblerPredicate<(all_of FeatureStdExtV), @@ -161,7 +161,7 @@ def HasVInstructionsAnyF : Predicate<"Subtarget->hasVInstructionsAnyF()">; def FeatureStdExtZvlsseg - : SubtargetFeature<"experimental-zvlsseg", "HasStdExtZvlsseg", "true", + : SubtargetFeature<"experimental-zvlsseg0p10", "StdExtZvlsseg", "RISCVExtensionVersion{0, 10}", "'Zvlsseg' (Vector segment load/store instructions)", [FeatureStdExtV]>; def HasStdExtZvlsseg : Predicate<"Subtarget->hasStdExtZvlsseg()">, @@ -169,7 +169,7 @@ "'Zvlsseg' (Vector segment load/store instructions)">; def FeatureStdExtZvamo - : SubtargetFeature<"experimental-zvamo", "HasStdExtZvamo", "true", + : SubtargetFeature<"experimental-zvamo0p10", "StdExtZvamo", "RISCVExtensionVersion{0, 10}", "'Zvamo' (Vector AMO Operations)", [FeatureStdExtV]>; def HasStdExtZvamo : Predicate<"Subtarget->hasStdExtZvamo()">, @@ -189,7 +189,7 @@ def RV64 : HwMode<"+64bit">; def FeatureRV32E - : SubtargetFeature<"e", "IsRV32E", "true", + : SubtargetFeature<"e1p9", "StdExtE", "RISCVExtensionVersion{1, 9}", "Implements RV32E (provides 16 rather than 32 GPRs)">; def IsRV32E : Predicate<"Subtarget->isRV32E()">, AssemblerPredicate<(all_of FeatureRV32E)>; Index: llvm/lib/Target/RISCV/RISCVSubtarget.h =================================================================== --- llvm/lib/Target/RISCV/RISCVSubtarget.h +++ llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -24,6 +24,7 @@ #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" +#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Target/TargetMachine.h" #define GET_SUBTARGETINFO_HEADER @@ -34,28 +35,28 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { virtual void anchor(); - bool HasStdExtM = false; - bool HasStdExtA = false; - bool HasStdExtF = false; - bool HasStdExtD = false; - bool HasStdExtC = false; - bool HasStdExtZba = false; - bool HasStdExtZbb = false; - bool HasStdExtZbc = false; - bool HasStdExtZbe = false; - bool HasStdExtZbf = false; - bool HasStdExtZbm = false; - bool HasStdExtZbp = false; - bool HasStdExtZbr = false; - bool HasStdExtZbs = false; - bool HasStdExtZbt = false; - bool HasStdExtV = false; - bool HasStdExtZvlsseg = false; - bool HasStdExtZvamo = false; - bool HasStdExtZfhmin = false; - bool HasStdExtZfh = false; + RISCVExtensionVersion StdExtM = {0, 0}; + RISCVExtensionVersion StdExtA = {0, 0}; + RISCVExtensionVersion StdExtF = {0, 0}; + RISCVExtensionVersion StdExtD = {0, 0}; + RISCVExtensionVersion StdExtC = {0, 0}; + RISCVExtensionVersion StdExtZba = {0, 0}; + RISCVExtensionVersion StdExtZbb = {0, 0}; + RISCVExtensionVersion StdExtZbc = {0, 0}; + RISCVExtensionVersion StdExtZbe = {0, 0}; + RISCVExtensionVersion StdExtZbf = {0, 0}; + RISCVExtensionVersion StdExtZbm = {0, 0}; + RISCVExtensionVersion StdExtZbp = {0, 0}; + RISCVExtensionVersion StdExtZbr = {0, 0}; + RISCVExtensionVersion StdExtZbs = {0, 0}; + RISCVExtensionVersion StdExtZbt = {0, 0}; + RISCVExtensionVersion StdExtV = {0, 0}; + RISCVExtensionVersion StdExtZvlsseg = {0, 0}; + RISCVExtensionVersion StdExtZvamo = {0, 0}; + RISCVExtensionVersion StdExtZfhmin = {0, 0}; + RISCVExtensionVersion StdExtZfh = {0, 0}; + RISCVExtensionVersion StdExtE = {0, 0}; bool HasRV64 = false; - bool IsRV32E = false; bool EnableLinkerRelax = false; bool EnableRVCHintInstrs = true; bool EnableSaveRestore = false; @@ -101,28 +102,34 @@ return &TSInfo; } bool enableMachineScheduler() const override { return true; } - bool hasStdExtM() const { return HasStdExtM; } - bool hasStdExtA() const { return HasStdExtA; } - bool hasStdExtF() const { return HasStdExtF; } - bool hasStdExtD() const { return HasStdExtD; } - bool hasStdExtC() const { return HasStdExtC; } - bool hasStdExtZba() const { return HasStdExtZba; } - bool hasStdExtZbb() const { return HasStdExtZbb; } - bool hasStdExtZbc() const { return HasStdExtZbc; } - bool hasStdExtZbe() const { return HasStdExtZbe; } - bool hasStdExtZbf() const { return HasStdExtZbf; } - bool hasStdExtZbm() const { return HasStdExtZbm; } - bool hasStdExtZbp() const { return HasStdExtZbp; } - bool hasStdExtZbr() const { return HasStdExtZbr; } - bool hasStdExtZbs() const { return HasStdExtZbs; } - bool hasStdExtZbt() const { return HasStdExtZbt; } - bool hasStdExtV() const { return HasStdExtV; } - bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; } - bool hasStdExtZvamo() const { return HasStdExtZvamo; } - bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } - bool hasStdExtZfh() const { return HasStdExtZfh; } + bool hasStdExtM() const { return StdExtM != RISCVExtensionVersion{0, 0}; } + bool hasStdExtA() const { return StdExtA != RISCVExtensionVersion{0, 0}; } + bool hasStdExtF() const { return StdExtF != RISCVExtensionVersion{0, 0}; } + bool hasStdExtD() const { return StdExtD != RISCVExtensionVersion{0, 0}; } + bool hasStdExtC() const { return StdExtC != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZba() const { return StdExtZba != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbb() const { return StdExtZbb != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbc() const { return StdExtZbc != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbe() const { return StdExtZbe != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbf() const { return StdExtZbf != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbm() const { return StdExtZbm != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbp() const { return StdExtZbp != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbr() const { return StdExtZbr != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbs() const { return StdExtZbs != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZbt() const { return StdExtZbt != RISCVExtensionVersion{0, 0}; } + bool hasStdExtV() const { return StdExtV != RISCVExtensionVersion{0, 0}; } + bool hasStdExtZvlsseg() const { + return StdExtZvlsseg != RISCVExtensionVersion{0, 0}; + } + bool hasStdExtZvamo() const { + return StdExtZvamo != RISCVExtensionVersion{0, 0}; + } + bool hasStdExtZfhmin() const { + return StdExtZfhmin != RISCVExtensionVersion{0, 0}; + } + bool hasStdExtZfh() const { return StdExtZfh != RISCVExtensionVersion{0, 0}; } bool is64Bit() const { return HasRV64; } - bool isRV32E() const { return IsRV32E; } + bool isRV32E() const { return StdExtE != RISCVExtensionVersion{0, 0}; } bool enableLinkerRelax() const { return EnableLinkerRelax; } bool enableRVCHintInstrs() const { return EnableRVCHintInstrs; } bool enableSaveRestore() const { return EnableSaveRestore; } @@ -135,11 +142,21 @@ } // Vector codegen related methods. - bool hasVInstructions() const { return HasStdExtV; } - bool hasVInstructionsI64() const { return HasStdExtV; } - bool hasVInstructionsF16() const { return HasStdExtV && hasStdExtZfh(); } - bool hasVInstructionsF32() const { return HasStdExtV && hasStdExtF(); } - bool hasVInstructionsF64() const { return HasStdExtV && hasStdExtD(); } + bool hasVInstructions() const { + return StdExtV != RISCVExtensionVersion{0, 0}; + } + bool hasVInstructionsI64() const { + return StdExtV != RISCVExtensionVersion{0, 0}; + } + bool hasVInstructionsF16() const { + return StdExtV != RISCVExtensionVersion{0, 0} && hasStdExtZfh(); + } + bool hasVInstructionsF32() const { + return StdExtV != RISCVExtensionVersion{0, 0} && hasStdExtF(); + } + bool hasVInstructionsF64() const { + return StdExtV != RISCVExtensionVersion{0, 0} && hasStdExtD(); + } // F16 and F64 both require F32. bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); } unsigned getMaxInterleaveFactor() const {