[PATCH] D137517: [TargetSupport] Generate the defs for RISCV CPUs using llvm-tblgen.
Wang Pengcheng via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 7 19:25:10 PST 2022
pcwang-thead added a comment.
A rough implementation just for your reference:
diff --git a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
index 47e11b9a1eab..f91f969c2b17 100644
--- a/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
+++ b/llvm/utils/TableGen/RISCVTargetDefEmitter.cpp
@@ -14,6 +14,32 @@
#include "llvm/TableGen/Record.h"
namespace llvm {
+struct CPUInfo {
+ std::string EnumName;
+ std::string MArch;
+ std::string Features;
+};
+
+static CPUInfo getCPUInfoFromFeatures(const Record &Record) {
+ std::string EnumName = Record.getValueAsString("Name").upper();
+ EnumName = EnumName.replace(EnumName.find_first_of('-'), 1, "_");
+ std::string MArch;
+ // FIXME: MArch should be in alphabetical order.
+ std::string Features;
+ for (auto *Feature : Record.getValueAsListOfDefs("Features")) {
+ StringRef FeatureName = Feature->getValueAsString("Name");
+ if (FeatureName == "32bit") {
+ MArch += "rv32i";
+ Features = "FK_NONE";
+ } else if (FeatureName == "64bit") {
+ MArch += "rv64i";
+ Features = "FK_64BIT";
+ } else
+ MArch += FeatureName;
+ }
+ return {EnumName, MArch, Features};
+}
+
void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {
const auto &Map = RK.getDefs();
@@ -26,11 +52,17 @@ void EmitRISCVTargetDef(RecordKeeper &RK, raw_ostream &OS) {
for (auto &Def : Map) {
const auto &Record = Def.second;
if (Record->isSubClassOf("RISCVProcessorModelPROC") &&
- Record->isSubClassOf("ProcessorModel"))
+ Record->isSubClassOf("ProcessorModel")) {
OS << "PROC(" << Record->getValueAsString("Enum") << ", "
<< "{\"" << Record->getValueAsString("Name") << "\"}, "
<< Record->getValueAsString("EnumFeatures") << ", "
<< "{\"" << Record->getValueAsString("DefaultMarch") << "\"})\n";
+ const CPUInfo &Info = getCPUInfoFromFeatures(*Record);
+ OS << "// PROC(" << Info.EnumName << ", "
+ << "{\"" << Record->getValueAsString("Name") << "\"}, "
+ << Info.Features << ", "
+ << "{\"" << Info.MArch << "\"})\n";
+ }
}
OS << "\n#undef PROC\n";
OS << "\n";
The generated header would be like:
#ifndef PROC
#define PROC(ENUM, NAME, FEATURES, DEFAULT_MARCH)
#endif
PROC(INVALID, {"invalid"}, FK_INVALID, {""})
PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {""})
// PROC(GENERIC_RV32, {"generic-rv32"}, FK_NONE, {"rv32i"})
PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {""})
// PROC(GENERIC_RV64, {"generic-rv64"}, FK_64BIT, {"rv64i"})
PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {""})
// PROC(ROCKET_RV32, {"rocket-rv32"}, FK_NONE, {"rv32i"})
PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {""})
// PROC(ROCKET_RV64, {"rocket-rv64"}, FK_64BIT, {"rv64i"})
PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"})
// PROC(SIFIVE_E20, {"sifive-e20"}, FK_NONE, {"rv32imc"})
PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"})
// PROC(SIFIVE_E21, {"sifive-e21"}, FK_NONE, {"rv32imac"})
PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"})
// PROC(SIFIVE_E24, {"sifive-e24"}, FK_NONE, {"rv32imafc"})
PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
// PROC(SIFIVE_E31, {"sifive-e31"}, FK_NONE, {"rv32imac"})
PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"})
// PROC(SIFIVE_E34, {"sifive-e34"}, FK_NONE, {"rv32imafc"})
PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
// PROC(SIFIVE_E76, {"sifive-e76"}, FK_NONE, {"rv32imafc"})
PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"})
// PROC(SIFIVE_S21, {"sifive-s21"}, FK_64BIT, {"rv64imac"})
PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"})
// PROC(SIFIVE_S51, {"sifive-s51"}, FK_64BIT, {"rv64imac"})
PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64gc"})
// PROC(SIFIVE_S54, {"sifive-s54"}, FK_64BIT, {"rv64imafdc"})
PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64gc"})
// PROC(SIFIVE_S76, {"sifive-s76"}, FK_64BIT, {"rv64imafdc"})
PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64gc"})
// PROC(SIFIVE_U54, {"sifive-u54"}, FK_64BIT, {"rv64imafdc"})
PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64gc"})
// PROC(SIFIVE_U74, {"sifive-u74"}, FK_64BIT, {"rv64imafdc"})
#undef PROC
#ifndef TUNE_PROC
#define TUNE_PROC(ENUM, NAME)
#endif
TUNE_PROC(GENERIC, "generic")
TUNE_PROC(ROCKET, "rocket")
TUNE_PROC(SIFIVE_7, "sifive-7-series")
#undef TUNE_PROC
---
> My preference would be to keep the Enum explicit as it would help using those enums in the code. Also, sometimes the enum cannot be derived from the Name (see for example "sifive-7-series" vs "SIFIVE_7").
I believe that we can change it to "SIFIVE-7-SERIES" since this enum name haven't been used in anywhere and it's just an enum name. :-)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137517/new/
https://reviews.llvm.org/D137517
More information about the cfe-commits
mailing list