diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp index 39cb3f2c2fe17..ea0b56b9a1339 100644 --- a/llvm/lib/TargetParser/RISCVISAInfo.cpp +++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp @@ -47,204 +47,8 @@ static const char *RISCVGImplications[] = { "i", "m", "a", "f", "d", "zicsr", "zifencei" }; -// NOTE: This table should be sorted alphabetically by extension name. -static const RISCVSupportedExtension SupportedExtensions[] = { - {"a", {2, 1}}, - {"c", {2, 0}}, - {"d", {2, 2}}, - {"e", {2, 0}}, - {"f", {2, 2}}, - {"h", {1, 0}}, - {"i", {2, 1}}, - {"m", {2, 0}}, - - {"shcounterenw", {1, 0}}, - {"shgatpa", {1, 0}}, - {"shtvala", {1, 0}}, - {"shvsatpa", {1, 0}}, - {"shvstvala", {1, 0}}, - {"shvstvecd", {1, 0}}, - {"smaia", {1, 0}}, - {"smepmp", {1, 0}}, - {"ssaia", {1, 0}}, - {"ssccptr", {1, 0}}, - {"sscofpmf", {1, 0}}, - {"sscounterenw", {1, 0}}, - {"ssstateen", {1, 0}}, - {"ssstrict", {1, 0}}, - {"sstc", {1, 0}}, - {"sstvala", {1, 0}}, - {"sstvecd", {1, 0}}, - {"ssu64xl", {1, 0}}, - {"svade", {1, 0}}, - {"svadu", {1, 0}}, - {"svbare", {1, 0}}, - {"svinval", {1, 0}}, - {"svnapot", {1, 0}}, - {"svpbmt", {1, 0}}, - - {"v", {1, 0}}, - - // vendor-defined ('X') extensions - {"xcvalu", {1, 0}}, - {"xcvbi", {1, 0}}, - {"xcvbitmanip", {1, 0}}, - {"xcvelw", {1, 0}}, - {"xcvmac", {1, 0}}, - {"xcvmem", {1, 0}}, - {"xcvsimd", {1, 0}}, - {"xsfcease", {1, 0}}, - {"xsfvcp", {1, 0}}, - {"xsfvfnrclipxfqf", {1, 0}}, - {"xsfvfwmaccqqq", {1, 0}}, - {"xsfvqmaccdod", {1, 0}}, - {"xsfvqmaccqoq", {1, 0}}, - {"xsifivecdiscarddlone", {1, 0}}, - {"xsifivecflushdlone", {1, 0}}, - {"xtheadba", {1, 0}}, - {"xtheadbb", {1, 0}}, - {"xtheadbs", {1, 0}}, - {"xtheadcmo", {1, 0}}, - {"xtheadcondmov", {1, 0}}, - {"xtheadfmemidx", {1, 0}}, - {"xtheadmac", {1, 0}}, - {"xtheadmemidx", {1, 0}}, - {"xtheadmempair", {1, 0}}, - {"xtheadsync", {1, 0}}, - {"xtheadvdot", {1, 0}}, - {"xventanacondops", {1, 0}}, - - {"za128rs", {1, 0}}, - {"za64rs", {1, 0}}, - {"zacas", {1, 0}}, - {"zama16b", {1, 0}}, - {"zawrs", {1, 0}}, - - {"zba", {1, 0}}, - {"zbb", {1, 0}}, - {"zbc", {1, 0}}, - {"zbkb", {1, 0}}, - {"zbkc", {1, 0}}, - {"zbkx", {1, 0}}, - {"zbs", {1, 0}}, - - {"zca", {1, 0}}, - {"zcb", {1, 0}}, - {"zcd", {1, 0}}, - {"zce", {1, 0}}, - {"zcf", {1, 0}}, - {"zcmop", {1, 0}}, - {"zcmp", {1, 0}}, - {"zcmt", {1, 0}}, - - {"zdinx", {1, 0}}, - - {"zfa", {1, 0}}, - {"zfh", {1, 0}}, - {"zfhmin", {1, 0}}, - {"zfinx", {1, 0}}, - - {"zhinx", {1, 0}}, - {"zhinxmin", {1, 0}}, - - {"zic64b", {1, 0}}, - {"zicbom", {1, 0}}, - {"zicbop", {1, 0}}, - {"zicboz", {1, 0}}, - {"ziccamoa", {1, 0}}, - {"ziccif", {1, 0}}, - {"zicclsm", {1, 0}}, - {"ziccrse", {1, 0}}, - {"zicntr", {2, 0}}, - {"zicond", {1, 0}}, - {"zicsr", {2, 0}}, - {"zifencei", {2, 0}}, - {"zihintntl", {1, 0}}, - {"zihintpause", {2, 0}}, - {"zihpm", {2, 0}}, - {"zimop", {1, 0}}, - - {"zk", {1, 0}}, - {"zkn", {1, 0}}, - {"zknd", {1, 0}}, - {"zkne", {1, 0}}, - {"zknh", {1, 0}}, - {"zkr", {1, 0}}, - {"zks", {1, 0}}, - {"zksed", {1, 0}}, - {"zksh", {1, 0}}, - {"zkt", {1, 0}}, - - {"zmmul", {1, 0}}, - - {"zvbb", {1, 0}}, - {"zvbc", {1, 0}}, - - {"zve32f", {1, 0}}, - {"zve32x", {1, 0}}, - {"zve64d", {1, 0}}, - {"zve64f", {1, 0}}, - {"zve64x", {1, 0}}, - - {"zvfh", {1, 0}}, - {"zvfhmin", {1, 0}}, - - // vector crypto - {"zvkb", {1, 0}}, - {"zvkg", {1, 0}}, - {"zvkn", {1, 0}}, - {"zvknc", {1, 0}}, - {"zvkned", {1, 0}}, - {"zvkng", {1, 0}}, - {"zvknha", {1, 0}}, - {"zvknhb", {1, 0}}, - {"zvks", {1, 0}}, - {"zvksc", {1, 0}}, - {"zvksed", {1, 0}}, - {"zvksg", {1, 0}}, - {"zvksh", {1, 0}}, - {"zvkt", {1, 0}}, - - {"zvl1024b", {1, 0}}, - {"zvl128b", {1, 0}}, - {"zvl16384b", {1, 0}}, - {"zvl2048b", {1, 0}}, - {"zvl256b", {1, 0}}, - {"zvl32768b", {1, 0}}, - {"zvl32b", {1, 0}}, - {"zvl4096b", {1, 0}}, - {"zvl512b", {1, 0}}, - {"zvl64b", {1, 0}}, - {"zvl65536b", {1, 0}}, - {"zvl8192b", {1, 0}}, -}; - -// NOTE: This table should be sorted alphabetically by extension name. -// clang-format off -static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { - {"smmpm", {0, 8}}, - {"smnpm", {0, 8}}, - {"ssnpm", {0, 8}}, - {"sspm", {0, 8}}, - {"ssqosid", {1, 0}}, - {"supm", {0, 8}}, - - {"zaamo", {0, 2}}, - {"zabha", {1, 0}}, - {"zalasr", {0, 1}}, - {"zalrsc", {0, 2}}, - - {"zfbfmin", {1, 0}}, - - {"zicfilp", {0, 4}}, - {"zicfiss", {0, 4}}, - - {"ztso", {0, 1}}, - - {"zvfbfmin", {1, 0}}, - {"zvfbfwma", {1, 0}}, -}; -// clang-format on +#define GET_SUPPORTED_EXTENSIONS +#include "llvm/TargetParser/RISCVTargetParserDef.inc" static constexpr RISCVProfile SupportedProfiles[] = { {"rvi20u32", "rv32i"}, @@ -1041,66 +845,6 @@ Error RISCVISAInfo::checkDependency() { return Error::success(); } -static const char *ImpliedExtsD[] = {"f"}; -static const char *ImpliedExtsF[] = {"zicsr"}; -static const char *ImpliedExtsV[] = {"zvl128b", "zve64d"}; -static const char *ImpliedExtsXSfvcp[] = {"zve32x"}; -static const char *ImpliedExtsXSfvfnrclipxfqf[] = {"zve32f"}; -static const char *ImpliedExtsXSfvfwmaccqqq[] = {"zvfbfmin"}; -static const char *ImpliedExtsXSfvqmaccdod[] = {"zve32x"}; -static const char *ImpliedExtsXSfvqmaccqoq[] = {"zve32x"}; -static const char *ImpliedExtsXTHeadVdot[] = {"v"}; -static const char *ImpliedExtsZcb[] = {"zca"}; -static const char *ImpliedExtsZcd[] = {"d", "zca"}; -static const char *ImpliedExtsZce[] = {"zcb", "zcmp", "zcmt"}; -static const char *ImpliedExtsZcf[] = {"f", "zca"}; -static const char *ImpliedExtsZcmop[] = {"zca"}; -static const char *ImpliedExtsZcmp[] = {"zca"}; -static const char *ImpliedExtsZcmt[] = {"zca", "zicsr"}; -static const char *ImpliedExtsZdinx[] = {"zfinx"}; -static const char *ImpliedExtsZfa[] = {"f"}; -static const char *ImpliedExtsZfbfmin[] = {"f"}; -static const char *ImpliedExtsZfh[] = {"zfhmin"}; -static const char *ImpliedExtsZfhmin[] = {"f"}; -static const char *ImpliedExtsZfinx[] = {"zicsr"}; -static const char *ImpliedExtsZhinx[] = {"zhinxmin"}; -static const char *ImpliedExtsZhinxmin[] = {"zfinx"}; -static const char *ImpliedExtsZicfiss[] = {"zicsr", "zimop"}; -static const char *ImpliedExtsZicntr[] = {"zicsr"}; -static const char *ImpliedExtsZihpm[] = {"zicsr"}; -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 *ImpliedExtsZvbb[] = {"zvkb"}; -static const char *ImpliedExtsZve32f[] = {"zve32x", "f"}; -static const char *ImpliedExtsZve32x[] = {"zvl32b", "zicsr"}; -static const char *ImpliedExtsZve64d[] = {"zve64f", "d"}; -static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"}; -static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"}; -static const char *ImpliedExtsZvfbfmin[] = {"zve32f"}; -static const char *ImpliedExtsZvfbfwma[] = {"zvfbfmin", "zfbfmin"}; -static const char *ImpliedExtsZvfh[] = {"zvfhmin", "zfhmin"}; -static const char *ImpliedExtsZvfhmin[] = {"zve32f"}; -static const char *ImpliedExtsZvkn[] = {"zvkb", "zvkned", "zvknhb", "zvkt"}; -static const char *ImpliedExtsZvknc[] = {"zvbc", "zvkn"}; -static const char *ImpliedExtsZvkng[] = {"zvkg", "zvkn"}; -static const char *ImpliedExtsZvknhb[] = {"zve64x"}; -static const char *ImpliedExtsZvks[] = {"zvkb", "zvksed", "zvksh", "zvkt"}; -static const char *ImpliedExtsZvksc[] = {"zvbc", "zvks"}; -static const char *ImpliedExtsZvksg[] = {"zvkg", "zvks"}; -static const char *ImpliedExtsZvl1024b[] = {"zvl512b"}; -static const char *ImpliedExtsZvl128b[] = {"zvl64b"}; -static const char *ImpliedExtsZvl16384b[] = {"zvl8192b"}; -static const char *ImpliedExtsZvl2048b[] = {"zvl1024b"}; -static const char *ImpliedExtsZvl256b[] = {"zvl128b"}; -static const char *ImpliedExtsZvl32768b[] = {"zvl16384b"}; -static const char *ImpliedExtsZvl4096b[] = {"zvl2048b"}; -static const char *ImpliedExtsZvl512b[] = {"zvl256b"}; -static const char *ImpliedExtsZvl64b[] = {"zvl32b"}; -static const char *ImpliedExtsZvl65536b[] = {"zvl32768b"}; -static const char *ImpliedExtsZvl8192b[] = {"zvl4096b"}; - struct ImpliedExtsEntry { StringLiteral Name; ArrayRef Exts; @@ -1112,67 +856,8 @@ struct ImpliedExtsEntry { bool operator<(StringRef Other) const { return Name < Other; } }; -// Note: The table needs to be sorted by name. -static constexpr ImpliedExtsEntry ImpliedExts[] = { - {{"d"}, {ImpliedExtsD}}, - {{"f"}, {ImpliedExtsF}}, - {{"v"}, {ImpliedExtsV}}, - {{"xsfvcp"}, {ImpliedExtsXSfvcp}}, - {{"xsfvfnrclipxfqf"}, {ImpliedExtsXSfvfnrclipxfqf}}, - {{"xsfvfwmaccqqq"}, {ImpliedExtsXSfvfwmaccqqq}}, - {{"xsfvqmaccdod"}, {ImpliedExtsXSfvqmaccdod}}, - {{"xsfvqmaccqoq"}, {ImpliedExtsXSfvqmaccqoq}}, - {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}}, - {{"zcb"}, {ImpliedExtsZcb}}, - {{"zcd"}, {ImpliedExtsZcd}}, - {{"zce"}, {ImpliedExtsZce}}, - {{"zcf"}, {ImpliedExtsZcf}}, - {{"zcmop"}, {ImpliedExtsZcmop}}, - {{"zcmp"}, {ImpliedExtsZcmp}}, - {{"zcmt"}, {ImpliedExtsZcmt}}, - {{"zdinx"}, {ImpliedExtsZdinx}}, - {{"zfa"}, {ImpliedExtsZfa}}, - {{"zfbfmin"}, {ImpliedExtsZfbfmin}}, - {{"zfh"}, {ImpliedExtsZfh}}, - {{"zfhmin"}, {ImpliedExtsZfhmin}}, - {{"zfinx"}, {ImpliedExtsZfinx}}, - {{"zhinx"}, {ImpliedExtsZhinx}}, - {{"zhinxmin"}, {ImpliedExtsZhinxmin}}, - {{"zicfiss"}, {ImpliedExtsZicfiss}}, - {{"zicntr"}, {ImpliedExtsZicntr}}, - {{"zihpm"}, {ImpliedExtsZihpm}}, - {{"zk"}, {ImpliedExtsZk}}, - {{"zkn"}, {ImpliedExtsZkn}}, - {{"zks"}, {ImpliedExtsZks}}, - {{"zvbb"}, {ImpliedExtsZvbb}}, - {{"zve32f"}, {ImpliedExtsZve32f}}, - {{"zve32x"}, {ImpliedExtsZve32x}}, - {{"zve64d"}, {ImpliedExtsZve64d}}, - {{"zve64f"}, {ImpliedExtsZve64f}}, - {{"zve64x"}, {ImpliedExtsZve64x}}, - {{"zvfbfmin"}, {ImpliedExtsZvfbfmin}}, - {{"zvfbfwma"}, {ImpliedExtsZvfbfwma}}, - {{"zvfh"}, {ImpliedExtsZvfh}}, - {{"zvfhmin"}, {ImpliedExtsZvfhmin}}, - {{"zvkn"}, {ImpliedExtsZvkn}}, - {{"zvknc"}, {ImpliedExtsZvknc}}, - {{"zvkng"}, {ImpliedExtsZvkng}}, - {{"zvknhb"}, {ImpliedExtsZvknhb}}, - {{"zvks"}, {ImpliedExtsZvks}}, - {{"zvksc"}, {ImpliedExtsZvksc}}, - {{"zvksg"}, {ImpliedExtsZvksg}}, - {{"zvl1024b"}, {ImpliedExtsZvl1024b}}, - {{"zvl128b"}, {ImpliedExtsZvl128b}}, - {{"zvl16384b"}, {ImpliedExtsZvl16384b}}, - {{"zvl2048b"}, {ImpliedExtsZvl2048b}}, - {{"zvl256b"}, {ImpliedExtsZvl256b}}, - {{"zvl32768b"}, {ImpliedExtsZvl32768b}}, - {{"zvl4096b"}, {ImpliedExtsZvl4096b}}, - {{"zvl512b"}, {ImpliedExtsZvl512b}}, - {{"zvl64b"}, {ImpliedExtsZvl64b}}, - {{"zvl65536b"}, {ImpliedExtsZvl65536b}}, - {{"zvl8192b"}, {ImpliedExtsZvl8192b}}, -}; +#define GET_IMPLIED_EXTENSIONS +#include "llvm/TargetParser/RISCVTargetParserDef.inc" void RISCVISAInfo::updateImplication() { bool HasE = Exts.count("e") != 0; diff --git a/llvm/test/TableGen/riscv-target-def.td b/llvm/test/TableGen/riscv-target-def.td index ab589b31192f3..b23c7e4d40198 100644 --- a/llvm/test/TableGen/riscv-target-def.td +++ b/llvm/test/TableGen/riscv-target-def.td @@ -2,8 +2,9 @@ include "llvm/Target/Target.td" -class RISCVExtension implies = [], +class RISCVExtension implies = [], + string fieldname = !subst("Feature", "Has", NAME), string value = "true"> : SubtargetFeature { int MajorVersion = major; @@ -11,18 +12,36 @@ class RISCVExtension implies = [], + string fieldname = !subst("Feature", "Has", NAME), + string value = "true"> + : RISCVExtension<"experimental-"#name, major, minor, desc, implies, + fieldname, value> { + let Experimental = true; +} + def FeatureStdExtI - : RISCVExtension<"i", 2, 1, "HasStdExtI", + : RISCVExtension<"i", 2, 1, "'I' (Base Integer Instruction Set)">; def FeatureStdExtZicsr - : RISCVExtension<"zicsr", 2, 0, "HasStdExtZicsr", + : RISCVExtension<"zicsr", 2, 0, "'zicsr' (CSRs)">; def FeatureStdExtZifencei - : RISCVExtension<"zifencei", 2, 0, "HasStdExtZifencei", + : RISCVExtension<"zifencei", 2, 0, "'Zifencei' (fence.i)">; +def FeatureStdExtF + : RISCVExtension<"f", 2, 2, + "'F' (Single-Precision Floating-Point)", + [FeatureStdExtZicsr]>; + +def FeatureStdExtZidummy + : RISCVExperimentalExtension<"zidummy", 0, 1, + "Dummy">; + def Feature32Bit : SubtargetFeature<"32bit", "IsRV32", "true", "Implements RV32">; def Feature64Bit @@ -75,22 +94,49 @@ def ROCKET_RV64 : RISCVProcessorModel<"rocket-rv64", def ROCKET : RISCVTuneProcessorModel<"rocket", NoSchedModel>; -// CHECK: #ifndef PROC -// CHECK: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS) -// CHECK: #endif +// CHECK: #ifdef GET_SUPPORTED_EXTENSIONS +// CHECK-NEXT: #undef GET_SUPPORTED_EXTENSIONS + +// CHECK: static const RISCVSupportedExtension SupportedExtensions[] = { +// CHECK-NEXT: {"f", {2, 2}}, +// CHECK-NEXT: {"i", {2, 1}}, +// CHECK-NEXT: {"zicsr", {2, 0}}, +// CHECK-NEXT: {"zifencei", {2, 0}}, +// CHECK-NEXT: }; + +// CHECK: static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { +// CHECK-NEXT: {"zidummy", {0, 1}}, +// CHECK-NEXT: }; + +// CHECK: #endif // GET_SUPPORTED_EXTENSIONS + +// CHECK: #ifdef GET_IMPLIED_EXTENSIONS +// CHECK-NEXT: #undef GET_IMPLIED_EXTENSIONS + +// CHECK: static const char *ImpliedExtsF[] = {"zicsr"}; + +// CHECK: static constexpr ImpliedExtsEntry ImpliedExts[] = { +// CHECK-NEXT: { {"f"}, {ImpliedExtsF} }, +// CHECK-NEXT: }; + +// CHECK: #endif // GET_IMPLIED_EXTENSIONS + +// CHECK: #ifndef PROC +// CHECK-NEXT: #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS) +// CHECK-NEXT: #endif -// CHECK: PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0) -// CHECK: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0) -// CHECK: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zifencei2p0"}, 0) -// CHECK: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zifencei2p0"}, 0) +// CHECK: PROC(GENERIC_RV32, {"generic-rv32"}, {"rv32i2p1"}, 0) +// CHECK-NEXT: PROC(GENERIC_RV64, {"generic-rv64"}, {"rv64i2p1"}, 0) +// CHECK-NEXT: PROC(ROCKET_RV32, {"rocket-rv32"}, {"rv32i2p1_zicsr2p0_zifencei2p0"}, 0) +// CHECK-NEXT: PROC(ROCKET_RV64, {"rocket-rv64"}, {"rv64i2p1_zicsr2p0_zifencei2p0"}, 0) // CHECK: #undef PROC -// CHECK: #ifndef TUNE_PROC -// CHECK: #define TUNE_PROC(ENUM, NAME) -// CHECK: #endif +// CHECK: #ifndef TUNE_PROC +// CHECK-NEXT: #define TUNE_PROC(ENUM, NAME) +// CHECK-NEXT: #endif // CHECK: TUNE_PROC(GENERIC, "generic") -// CHECK: TUNE_PROC(ROCKET, "rocket") +// CHECK-NEXT: TUNE_PROC(ROCKET, "rocket") // CHECK: #undef TUNE_PROC diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp index 26034e31ad8d1..217b531dcfd39 100644 --- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// // -// This tablegen backend emits the include file needed by the target -// parser to parse the RISC-V CPUs. +// This tablegen backend emits the include file needed by RISCVTargetParser.cpp +// and RISCVISAInfo.cpp to parse the RISC-V CPUs and extensions. // //===----------------------------------------------------------------------===// @@ -17,6 +17,94 @@ using namespace llvm; +static StringRef getExtensionName(const Record *R) { + StringRef Name = R->getValueAsString("Name"); + Name.consume_front("experimental-"); + return Name; +} + +static void printExtensionTable(raw_ostream &OS, + const std::vector &Extensions, + bool Experimental) { + OS << "static const RISCVSupportedExtension Supported"; + if (Experimental) + OS << "Experimental"; + OS << "Extensions[] = {\n"; + + for (Record *R : Extensions) { + if (R->getValueAsBit("Experimental") != Experimental) + continue; + + OS << " {\"" << getExtensionName(R) << "\", {" + << R->getValueAsInt("MajorVersion") << ", " + << R->getValueAsInt("MinorVersion") << "}},\n"; + } + + OS << "};\n\n"; +} + +// Get the extension name from the Record name. This gives the canonical +// capitalization. +static StringRef getExtensionNameFromRecordName(const Record *R) { + StringRef Name = R->getName(); + if (!Name.consume_front("FeatureStdExt")) + Name.consume_front("FeatureVendor"); + + return Name; +} + +static void emitRISCVExtensions(RecordKeeper &Records, raw_ostream &OS) { + OS << "#ifdef GET_SUPPORTED_EXTENSIONS\n"; + OS << "#undef GET_SUPPORTED_EXTENSIONS\n\n"; + + std::vector Extensions = + Records.getAllDerivedDefinitions("RISCVExtension"); + llvm::sort(Extensions, [](const Record *Rec1, const Record *Rec2) { + return getExtensionName(Rec1) < getExtensionName(Rec2); + }); + + printExtensionTable(OS, Extensions, /*Experimental=*/false); + printExtensionTable(OS, Extensions, /*Experimental=*/true); + + OS << "#endif // GET_SUPPORTED_EXTENSIONS\n\n"; + + OS << "#ifdef GET_IMPLIED_EXTENSIONS\n"; + OS << "#undef GET_IMPLIED_EXTENSIONS\n\n"; + + for (Record *Ext : Extensions) { + auto ImpliesList = Ext->getValueAsListOfDefs("Implies"); + if (ImpliesList.empty()) + continue; + + OS << "static const char *ImpliedExts" + << getExtensionNameFromRecordName(Ext) << "[] = {"; + + ListSeparator LS(", "); + for (auto *ImpliedExt : ImpliesList) { + if (!ImpliedExt->isSubClassOf("RISCVExtension")) + continue; + + OS << LS << '"' << getExtensionName(ImpliedExt) << '"'; + } + + OS << "};\n"; + } + + OS << "\nstatic constexpr ImpliedExtsEntry ImpliedExts[] = {\n"; + for (Record *Ext : Extensions) { + auto ImpliesList = Ext->getValueAsListOfDefs("Implies"); + if (ImpliesList.empty()) + continue; + + OS << " { {\"" << getExtensionName(Ext) << "\"}, {ImpliedExts" + << getExtensionNameFromRecordName(Ext) << "} },\n"; + } + + OS << "};\n\n"; + + OS << "#endif // GET_IMPLIED_EXTENSIONS\n\n"; +} + // We can generate march string from target features as what has been described // in RISC-V ISA specification (version 20191213) 'Chapter 27. ISA Extension // Naming Conventions'. @@ -54,7 +142,7 @@ static void printMArch(raw_ostream &OS, const Record &Rec) { OS << LS << Ext.first << Ext.second.Major << 'p' << Ext.second.Minor; } -static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { +static void emitRISCVProcs(RecordKeeper &RK, raw_ostream &OS) { OS << "#ifndef PROC\n" << "#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGNED_ACCESS)\n" << "#endif\n\n"; @@ -101,5 +189,11 @@ static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { OS << "\n#undef TUNE_PROC\n"; } +static void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) { + emitRISCVExtensions(RK, OS); + emitRISCVProcs(RK, OS); +} + static TableGen::Emitter::Opt X("gen-riscv-target-def", EmitRISCVTargetDef, - "Generate the list of CPU for RISCV"); + "Generate the list of CPUs and extensions for " + "RISC-V");