diff options
Diffstat (limited to 'backend/utils/TableGen/GlobalISelEmitter.cpp')
| -rw-r--r-- | backend/utils/TableGen/GlobalISelEmitter.cpp | 96 |
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 |
