aboutsummaryrefslogtreecommitdiff
path: root/backend/utils/TableGen/GlobalISelEmitter.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-16 15:39:45 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-16 15:39:45 +0800
commit4f7b41c3c711d6c6fa4e422f3eec8961c91eea7a (patch)
treea825927a4a3ef91ec6e3489aa1f96e63788ff476 /backend/utils/TableGen/GlobalISelEmitter.cpp
parenta39d8f6f4ed2ad0f8435b73bd6b2a35769c6fead (diff)
downloadrcc-project-4f7b41c3c711d6c6fa4e422f3eec8961c91eea7a.tar.gz
rcc-project-4f7b41c3c711d6c6fa4e422f3eec8961c91eea7a.tar.xz
tablegen: Generate GlobalISel match tables
Diffstat (limited to 'backend/utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r--backend/utils/TableGen/GlobalISelEmitter.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/backend/utils/TableGen/GlobalISelEmitter.cpp b/backend/utils/TableGen/GlobalISelEmitter.cpp
new file mode 100644
index 0000000..1634eb3
--- /dev/null
+++ b/backend/utils/TableGen/GlobalISelEmitter.cpp
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "TableGenBackends.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <string_view>
+
+namespace rcc::targetgen {
+namespace {
+
+[[nodiscard]] std::string_view typeKindName(NormalizedSelectionTypeKind Kind) noexcept {
+ switch (Kind) {
+ case NormalizedSelectionTypeKind::Any:
+ return "Any";
+ case NormalizedSelectionTypeKind::Scalar:
+ return "Scalar";
+ case NormalizedSelectionTypeKind::Pointer:
+ return "Pointer";
+ }
+ return "Any";
+}
+
+void emitInstruction(std::ostream &Output, std::string_view Opcode, std::uint32_t OperandIndex,
+ std::uint32_t Value = 0, std::string_view Auxiliary = "0",
+ std::int64_t Immediate = 0) {
+ Output << " {GIMatchTableOpcode::" << Opcode << ", " << OperandIndex << ", " << Value << ", "
+ << Auxiliary << ", " << Immediate << "},\n";
+}
+
+void emitTypePredicate(std::ostream &Output, std::uint32_t OperandIndex,
+ const NormalizedSelectionTypePredicate &Predicate) {
+ emitInstruction(Output, "CheckOperandType", OperandIndex, Predicate.Bits,
+ "static_cast<std::uint32_t>(GIMatchTypeKind::" +
+ std::string(typeKindName(Predicate.Kind)) + ")");
+}
+
+[[nodiscard]] std::size_t instructionCount(const NormalizedSelectionRule &Rule) noexcept {
+ return 3U + (Rule.ResultType ? 1U : 0U) + Rule.OperandTypes.size() + Rule.OperandBanks.size() +
+ Rule.OperandClasses.size() + Rule.AppendedImmediates.size();
+}
+
+} // namespace
+
+std::string emitGlobalISel(const NormalizedTargetModel &Model, std::string_view SourceName) {
+ std::size_t InstructionCount = 0;
+ for (const NormalizedSelectionRule &Rule : Model.SelectionRules)
+ InstructionCount += instructionCount(Rule);
+
+ std::ostringstream Output;
+ Output << "// SPDX-License-Identifier: GPL-3.0-or-later\n\n";
+ Output << "// This file is generated by rcc-tblgen from ";
+ appendQuoted(Output, SourceName);
+ Output << ". Do not edit it manually.\n\n";
+ Output << "#ifdef GET_GLOBALISEL_MATCH_TABLE\n\n";
+ Output << "constexpr std::array<GIMatchTableInstruction, " << InstructionCount
+ << "> GeneratedGlobalISelInstructions = {{\n";
+ for (const NormalizedSelectionRule &Rule : Model.SelectionRules) {
+ emitInstruction(Output, "CheckOpcode", 0, Rule.MatchOpcode);
+ if (Rule.ResultType)
+ emitTypePredicate(Output, 0, *Rule.ResultType);
+ for (const NormalizedSelectionOperandTypePredicate &Predicate : Rule.OperandTypes)
+ emitTypePredicate(Output, Predicate.OperandIndex, Predicate.Type);
+ for (const NormalizedSelectionOperandBankPredicate &Predicate : Rule.OperandBanks)
+ emitInstruction(Output, "CheckOperandBank", Predicate.OperandIndex, Predicate.Bank);
+ for (const NormalizedSelectionOperandClassPredicate &Predicate : Rule.OperandClasses)
+ emitInstruction(Output, "CheckOperandClass", Predicate.OperandIndex, Predicate.RegClass);
+ emitInstruction(Output, "MutateOpcode", 0, Rule.ResultOpcode);
+ for (const std::int64_t Immediate : Rule.AppendedImmediates)
+ emitInstruction(Output, "AppendImmediate", 0, 0, "0", Immediate);
+ emitInstruction(Output, "Complete", 0);
+ }
+ Output << "}};\n\n";
+
+ Output << "constexpr std::array<GIMatchTableRule, " << Model.SelectionRules.size()
+ << "> GeneratedGlobalISelRules = {{\n";
+ std::size_t FirstInstruction = 0;
+ for (const NormalizedSelectionRule &Rule : Model.SelectionRules) {
+ const std::size_t Count = instructionCount(Rule);
+ Output << " {";
+ appendQuoted(Output, Rule.Symbol);
+ Output << ", " << Rule.Priority << ", " << FirstInstruction << ", " << Count << "},\n";
+ FirstInstruction += Count;
+ }
+ Output << "}};\n\n";
+ Output << "[[nodiscard]] constexpr GIMatchTable generatedGlobalISelMatchTable() noexcept {\n"
+ " return {GeneratedGlobalISelInstructions, GeneratedGlobalISelRules};\n"
+ "}\n\n";
+ Output << "#endif // GET_GLOBALISEL_MATCH_TABLE\n";
+ return Output.str();
+}
+
+} // namespace rcc::targetgen