From 444db30751380e8fe459bfeae4c5bb2a93c596eb Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Thu, 13 Aug 2026 13:10:47 +0800 Subject: [TableGen] Split the target description generator --- backend/utils/TableGen/RegisterInfoEmitter.cpp | 158 +++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 backend/utils/TableGen/RegisterInfoEmitter.cpp (limited to 'backend/utils/TableGen/RegisterInfoEmitter.cpp') diff --git a/backend/utils/TableGen/RegisterInfoEmitter.cpp b/backend/utils/TableGen/RegisterInfoEmitter.cpp new file mode 100644 index 0000000..a4caa69 --- /dev/null +++ b/backend/utils/TableGen/RegisterInfoEmitter.cpp @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "TableGenBackends.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace rcc::targetgen { +namespace { + +void emitRegisterIDList(std::ostream &Output, const NormalizedTargetModel &Model, + std::span IDs) { + for (const std::uint32_t ID : IDs) + Output << "PhysicalRegisterID::" << findRegister(Model, ID).Symbol << ", "; +} + +} // namespace + +[[nodiscard]] std::string emitRegisterHeader(const NormalizedTargetModel &Model, + std::string_view SourceName) { + const std::string Guard = "RCC_TARGET_" + upperIdentifier(Model.Target.Namespace) + "_" + + upperIdentifier(Model.Target.Name) + "REGISTERS_H"; + 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 << "#ifndef " << Guard << "\n#define " << Guard << "\n\n"; + Output << "#include \n#include \n\n"; + Output << "namespace rcc::" << Model.Target.Namespace << " {\n\n"; + Output << "inline constexpr std::string_view TargetName = "; + appendQuoted(Output, Model.Target.Name); + Output << ";\ninline constexpr std::string_view TargetTriple = "; + appendQuoted(Output, Model.Target.Triple); + Output << ";\ninline constexpr std::string_view TargetCPU = "; + appendQuoted(Output, Model.Target.CPU); + Output << ";\ninline constexpr std::string_view TargetABI = "; + appendQuoted(Output, Model.Target.ABI); + Output << ";\ninline constexpr std::string_view TargetDataLayout = "; + appendQuoted(Output, Model.Target.DataLayout); + Output << ";\n\ninline constexpr std::string_view TargetFeatures[] = {\n"; + for (const std::string &Feature : Model.Target.Features) { + Output << " "; + appendQuoted(Output, Feature); + Output << ",\n"; + } + Output << "};\n\n"; + + Output << "enum class PhysicalRegisterID : std::uint32_t {\n NoRegister = 0,\n"; + for (const NormalizedRegister &Register : Model.Registers) + Output << " " << Register.Symbol << " = " << Register.ID << ",\n"; + Output << "};\n\n"; + Output << "enum class RegisterUnit : std::uint32_t {\n"; + for (const SourceRegisterUnit &Unit : Model.RegisterUnits) + Output << " " << Unit.Symbol << " = " << Unit.ID << ",\n"; + Output << "};\n\n"; + Output << "enum class RegisterBank : std::uint32_t {\n"; + for (const NormalizedRegisterBank &Bank : Model.RegisterBanks) + Output << " " << Bank.Symbol << " = " << Bank.ID << ",\n"; + Output << "};\n\n"; + Output << "enum class RegisterClass : std::uint32_t {\n"; + for (const NormalizedRegisterClass &Class : Model.RegisterClasses) + Output << " " << Class.Symbol << " = " << Class.ID << ",\n"; + Output << "};\n\n"; + Output << "} // namespace rcc::" << Model.Target.Namespace << "\n\n"; + Output << "#endif // " << Guard << "\n"; + return Output.str(); +} + +std::string emitRegisterInfo(const NormalizedTargetModel &Model, std::string_view SourceName) { + 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 << "void appendGeneratedRegisterInfo(TargetRegisterInfoDesc &Description) {\n"; + Output << " Description.RegisterUnits = {\n"; + for (const SourceRegisterUnit &Unit : Model.RegisterUnits) { + Output << " {RegisterUnitID::fromValue(" << Unit.ID << "), "; + appendQuoted(Output, Unit.Name); + Output << "},\n"; + } + Output << " };\n\n Description.PhysicalRegisters = {\n"; + for (const NormalizedRegister &Register : Model.Registers) { + Output << " {physical(PhysicalRegisterID::" << Register.Symbol << "), "; + appendQuoted(Output, Register.Name); + Output << ", " << Register.Encoding << ", {"; + for (const NormalizedRegisterUnitLane &Unit : Register.Units) { + Output << "unitLane(RegisterUnit::" << findRegisterUnit(Model, Unit.UnitID).Symbol << ", " + << Unit.Lanes << "), "; + } + Output << "}, " << (Register.IsConstant ? "true" : "false") << ", " + << (Register.IsArtificial ? "true" : "false") << ", " + << (Register.IsReserved ? "true" : "false") << ", {"; + for (const std::string &Alias : Register.AlternativeNames) { + appendQuoted(Output, Alias); + Output << ", "; + } + Output << "}},\n"; + } + Output << " };\n\n Description.RegisterBanks = {\n"; + Output << emitRegisterBanks(Model); + Output << " };\n\n Description.RegisterClasses = {\n"; + for (const NormalizedRegisterClass &Class : Model.RegisterClasses) { + Output << " registerClass(RegisterClass::" << Class.Symbol << ", "; + appendQuoted(Output, Class.Name); + Output << ", {"; + emitRegisterIDList(Output, Model, Class.Registers); + Output << "}, {"; + emitRegisterIDList(Output, Model, Class.AllocationOrder); + Output << "}, RegisterBank::" << findRegisterBank(Model, Class.BankID).Symbol << ", " + << Class.SizeInBits << ", " << Class.SpillSizeInBits << ", " + << Class.SpillAlignmentInBits << ", " << Class.Lanes << ", " + << (Class.Allocatable ? "true" : "false") << ", " << Class.CopyCost << "),\n"; + } + Output << " };\n}\n\n"; + Output << "void appendGeneratedMIRTextInfo(TargetMIRTextInfoDesc &Description) {\n"; + Output << " Description.DirectOperandFlagMask = " << Model.MIROperandFlags.DirectMask + << ";\n Description.DirectOperandFlags = {\n"; + for (const SourceMIROperandFlag &Flag : Model.MIROperandFlags.Direct) { + Output << " {"; + appendQuoted(Output, Flag.Name); + Output << ", " << Flag.Value << "},\n"; + } + Output << " };\n Description.BitmaskOperandFlags = {\n"; + for (const SourceMIROperandFlag &Flag : Model.MIROperandFlags.Bitmask) { + Output << " {"; + appendQuoted(Output, Flag.Name); + Output << ", " << Flag.Value << "},\n"; + } + Output << " };\n"; + Output << " Description.RegisterMasks = {\n"; + for (const NormalizedRegisterMask &Mask : Model.RegisterMasks) { + Output << " {"; + appendQuoted(Output, Mask.Name); + Output << ", makePreservedMask({"; + emitRegisterIDList(Output, Model, Mask.PreservedRegisters); + Output << "})},\n"; + } + Output << " };\n Description.CFIRegisters = {\n"; + std::unordered_set CanonicalDwarfRegisters; + for (const NormalizedRegister &Register : Model.Registers) { + const bool IsCanonical = CanonicalDwarfRegisters.insert(Register.DwarfRegister).second; + Output << " {physical(PhysicalRegisterID::" << Register.Symbol << "), " + << Register.DwarfRegister << ", " << (IsCanonical ? "true" : "false") << "},\n"; + } + Output << " };\n}\n\n"; + + return Output.str(); +} + +} // namespace rcc::targetgen -- cgit v1.2.3