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/Common/CodeGenTarget.h | 245 ++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 backend/utils/TableGen/Common/CodeGenTarget.h (limited to 'backend/utils/TableGen/Common/CodeGenTarget.h') diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h new file mode 100644 index 0000000..cc2697c --- /dev/null +++ b/backend/utils/TableGen/Common/CodeGenTarget.h @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +// The private header follows the source-tree ownership of LLVM TableGen Common. +// NOLINTNEXTLINE(llvm-header-guard) +#ifndef RCC_UTILS_TABLEGEN_COMMON_CODEGENTARGET_H +#define RCC_UTILS_TABLEGEN_COMMON_CODEGENTARGET_H + +#include "rcc/TableGen/Record.h" + +#include +#include +#include +#include +#include +#include + +namespace rcc::targetgen { + +struct NormalizedRegisterUnitLane final { + std::uint32_t UnitID = 0; + std::uint64_t Lanes = 0; +}; + +struct NormalizedRegister final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t Encoding = 0; + std::uint32_t DwarfRegister = 0; + std::vector Units; + bool IsConstant = false; + bool IsArtificial = false; + bool IsReserved = false; + std::vector AlternativeNames; +}; + +struct NormalizedRegisterBank final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t MaximumSizeInBits = 0; + std::vector RegisterClasses; +}; + +struct NormalizedRegisterClass final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t BankID = 0; + std::uint32_t SizeInBits = 0; + std::uint32_t SpillSizeInBits = 0; + std::uint32_t SpillAlignmentInBits = 0; + std::uint64_t Lanes = 0; + std::vector Registers; + std::vector AllocationOrder; + bool Allocatable = true; + std::uint32_t CopyCost = 1; +}; + +struct NormalizedRegisterMask final { + std::string Name; + std::vector PreservedRegisters; +}; + +struct NormalizedCallingConvention final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t IntegerRegisterClass = 0; + std::uint32_t FloatingRegisterClass = 0; + std::vector IntegerArgumentRegisters; + std::vector FloatingArgumentRegisters; + std::vector IntegerReturnRegisters; + std::vector FloatingReturnRegisters; + std::string PreservedMaskName; + std::uint32_t StackAlignmentBytes = 0; + std::uint32_t StackArgumentAlignmentBytes = 0; + std::uint32_t ShadowSpaceBytes = 0; + bool SupportsVarArgs = false; + bool SupportsTailCalls = false; +}; + +struct NormalizedNamedOperand final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; +}; + +struct NormalizedImmediatePredicate final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + bool IsSigned = false; + std::uint32_t Bits = 0; + std::uint64_t Alignment = 1; + bool NonZero = false; + std::vector AllowedValues; +}; + +struct NormalizedSchedulingClass final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t MicroOps = 0; + std::uint32_t Latency = 0; +}; + +struct NormalizedEncodingCategory final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::uint32_t SizeInBytes = 0; +}; + +struct NormalizedAssemblyFormat final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; +}; + +struct NormalizedOperand final { + std::vector Kinds; + std::string RegisterRole; + std::optional RegisterClass; + std::optional RegisterBank; + std::optional ImmediatePredicate; + std::string MemoryRole; + std::optional DefaultTiedOperand; + bool EarlyClobber = false; + bool Optional = false; + bool VariadicGroup = false; + bool AllowSubReg = false; + std::optional Name; + std::uint32_t AllowedTargetFlags = 0; +}; + +struct NormalizedImplicitRegister final { + std::uint32_t Register = 0; + bool EarlyClobber = false; + bool Renamable = false; +}; + +struct NormalizedInstruction final { + std::uint32_t ID = 0; + std::string Symbol; + std::string Name; + std::string AssemblyMnemonic; + std::uint32_t BinaryEncoding = 0; + std::vector Operands; + std::uint32_t NumExplicitDefs = 0; + bool Variadic = false; + std::vector ImplicitDefs; + std::vector ImplicitUses; + bool AllowExtraImplicitOperands = false; + std::vector Flags; + std::uint32_t SchedulingClass = 0; + std::uint32_t EncodingCategory = 0; + std::uint32_t AssemblyFormat = 0; + bool RequiresMemoryOperands = false; + std::string Owner; + std::string Deadline; +}; + +struct NormalizedTargetModel final { + SourceTarget Target; + std::vector RegisterUnits; + std::vector Registers; + std::vector RegisterBanks; + std::vector RegisterClasses; + std::vector RegisterMasks; + SourceMIROperandFlags MIROperandFlags; + std::vector CallingConventions; + std::vector NamedOperands; + std::vector ImmediatePredicates; + std::vector SchedulingClasses; + std::vector EncodingCategories; + std::vector AssemblyFormats; + std::vector Instructions; +}; + +[[nodiscard]] std::optional +operandKindEnumerator(std::string_view Value) noexcept; +[[nodiscard]] std::optional +registerRoleEnumerator(std::string_view Value) noexcept; +[[nodiscard]] std::optional memoryRoleEnumerator(std::string_view Value) noexcept; +[[nodiscard]] std::optional +instructionFlagEnumerator(std::string_view Value) noexcept; +[[nodiscard]] std::optional +pseudoOwnerEnumerator(std::string_view Value) noexcept; +[[nodiscard]] std::optional +pipelineStageEnumerator(std::string_view Value) noexcept; +[[nodiscard]] bool isPowerOfTwo(std::uint64_t Value) noexcept; + +class CodeGenTarget final { +public: + CodeGenTarget(const DescriptionAST &Input, std::string SourceName); + [[nodiscard]] std::optional normalize(); + [[nodiscard]] std::vector takeDiagnostics(); + +private: + void fail(TextRange Range, std::string Message); + [[nodiscard]] bool validateTarget(); + [[nodiscard]] bool normalizeRegisterUnits(); + [[nodiscard]] bool normalizeRegisters(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeRegisterBanks(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeRegisterClasses(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeRegisterMasks(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeMIROperandFlags(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeCallingConventions(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeNamedOperands(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeImmediatePredicates(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeSchedulingClasses(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeEncodingCategories(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeAssemblyFormats(NormalizedTargetModel &Result); + [[nodiscard]] bool normalizeOperand(const SourceOperand &InputOperand, NormalizedOperand &Result); + [[nodiscard]] bool + normalizeImplicitRegisters(const std::vector &InputRegisters, bool IsDef, + std::vector &Result); + [[nodiscard]] bool normalizeInstructions(NormalizedTargetModel &Result); + + const DescriptionAST &Input; + std::string SourceName; + std::unordered_map UnitBySymbol; + std::unordered_map RegisterBySymbol; + std::unordered_map BankBySymbol; + std::unordered_map ClassBySymbol; + std::unordered_map NamedOperandBySymbol; + std::unordered_map ImmediatePredicateBySymbol; + std::unordered_map SchedulingClassBySymbol; + std::unordered_map EncodingCategoryBySymbol; + std::unordered_map AssemblyFormatBySymbol; + std::unordered_map CallingConventionBySymbol; + std::vector Diagnostics; +}; + +[[nodiscard]] const NormalizedRegister &findRegister(const NormalizedTargetModel &Model, + std::uint32_t ID); +[[nodiscard]] const SourceRegisterUnit &findRegisterUnit(const NormalizedTargetModel &Model, + std::uint32_t ID); +[[nodiscard]] const NormalizedRegisterBank &findRegisterBank(const NormalizedTargetModel &Model, + std::uint32_t ID); + +} // namespace rcc::targetgen + +#endif // RCC_UTILS_TABLEGEN_COMMON_CODEGENTARGET_H -- cgit v1.2.3