aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/TableGen')
-rw-r--r--backend/include/rcc/TableGen/Parser.h24
-rw-r--r--backend/include/rcc/TableGen/Record.h470
2 files changed, 494 insertions, 0 deletions
diff --git a/backend/include/rcc/TableGen/Parser.h b/backend/include/rcc/TableGen/Parser.h
new file mode 100644
index 0000000..ff10aa7
--- /dev/null
+++ b/backend/include/rcc/TableGen/Parser.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TABLEGEN_PARSER_H
+#define RCC_TABLEGEN_PARSER_H
+
+#include "rcc/TableGen/Record.h"
+
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace rcc::targetgen {
+
+struct DescriptionParseResult final {
+ std::optional<DescriptionAST> Records;
+ std::vector<TextDiagnostic> Diagnostics;
+};
+
+[[nodiscard]] DescriptionParseResult parseDescription(std::string SourceName,
+ std::string SourceText);
+
+} // namespace rcc::targetgen
+
+#endif // RCC_TABLEGEN_PARSER_H
diff --git a/backend/include/rcc/TableGen/Record.h b/backend/include/rcc/TableGen/Record.h
new file mode 100644
index 0000000..525d63f
--- /dev/null
+++ b/backend/include/rcc/TableGen/Record.h
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#ifndef RCC_TABLEGEN_RECORD_H
+#define RCC_TABLEGEN_RECORD_H
+
+#include "rcc/Support/TextDiagnostic.h"
+
+#include <cstdint>
+#include <optional>
+#include <ostream>
+#include <string>
+#include <string_view>
+#include <vector>
+
+namespace rcc::targetgen {
+
+struct SourceTarget final {
+ std::string Namespace;
+ std::string Name;
+ std::string Triple;
+ std::string CPU;
+ std::string ABI;
+ std::string DataLayout;
+ std::vector<std::string> Features;
+ TextRange Range;
+};
+
+struct SourceRegisterUnit final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ TextRange Range;
+};
+
+struct SourceRegisterUnitLane final {
+ std::string UnitSymbol;
+ std::uint64_t Lanes = 0;
+ TextRange Range;
+};
+
+struct SourceRegister final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::uint32_t Encoding = 0;
+ std::uint32_t DwarfRegister = 0;
+ std::vector<SourceRegisterUnitLane> Units;
+ bool IsConstant = false;
+ bool IsArtificial = false;
+ bool IsReserved = false;
+ std::vector<std::string> AlternativeNames;
+ TextRange Range;
+};
+
+struct SourceRegisterBank final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::uint32_t MaximumSizeInBits = 0;
+ TextRange Range;
+};
+
+struct SourceRegisterClass final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::string BankSymbol;
+ std::uint32_t SizeInBits = 0;
+ std::uint32_t SpillSizeInBits = 0;
+ std::uint32_t SpillAlignmentInBits = 0;
+ std::uint64_t Lanes = 0;
+ std::vector<std::string> RegisterSymbols;
+ std::vector<std::string> AllocationOrderSymbols;
+ std::vector<std::string> SuperClassSymbols;
+ bool Allocatable = true;
+ std::uint32_t CopyCost = 1;
+ TextRange Range;
+};
+
+struct SourceRegisterMask final {
+ std::string Name;
+ std::vector<std::string> PreservedRegisterSymbols;
+ TextRange Range;
+};
+
+struct SourceMIROperandFlag final {
+ std::string Name;
+ std::uint32_t Value = 0;
+ TextRange Range;
+};
+
+struct SourceMIROperandFlags final {
+ std::uint32_t DirectMask = 0;
+ std::vector<SourceMIROperandFlag> Direct;
+ std::vector<SourceMIROperandFlag> Bitmask;
+ TextRange Range;
+};
+
+struct SourceCallingConvention final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::string IntegerRegisterClassSymbol;
+ std::string FloatingRegisterClassSymbol;
+ std::vector<std::string> IntegerArgumentRegisterSymbols;
+ std::vector<std::string> FloatingArgumentRegisterSymbols;
+ std::vector<std::string> IntegerReturnRegisterSymbols;
+ std::vector<std::string> FloatingReturnRegisterSymbols;
+ std::string PreservedMaskName;
+ std::uint32_t StackAlignmentBytes = 0;
+ std::uint32_t StackArgumentAlignmentBytes = 0;
+ std::uint32_t ShadowSpaceBytes = 0;
+ bool SupportsVarArgs = false;
+ bool SupportsTailCalls = false;
+ TextRange Range;
+};
+
+struct SourceNamedOperand final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ TextRange Range;
+};
+
+struct SourceImmediatePredicate final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::string Kind;
+ std::uint32_t Bits = 0;
+ std::uint64_t Alignment = 1;
+ bool NonZero = false;
+ std::vector<std::int64_t> AllowedValues;
+ TextRange Range;
+};
+
+struct SourceSchedulingClass final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::uint32_t MicroOps = 0;
+ std::uint32_t Latency = 0;
+ TextRange Range;
+};
+
+struct SourceMacroFusionOpcodePair final {
+ std::string FirstOpcodeSymbol;
+ std::string SecondOpcodeSymbol;
+ TextRange Range;
+};
+
+struct SourceMacroFusionImmediatePredicate final {
+ std::string Instruction;
+ std::uint32_t OperandIndex = 0;
+ std::int64_t Minimum = 0;
+ std::int64_t Maximum = 0;
+ TextRange Range;
+};
+
+struct SourceMacroFusionRegisterInequality final {
+ std::string Instruction;
+ std::uint32_t LeftOperand = 0;
+ std::uint32_t RightOperand = 0;
+ TextRange Range;
+};
+
+struct SourceMacroFusionImmediateRelation final {
+ std::string Kind;
+ std::uint32_t FirstOperand = 0;
+ std::uint32_t SecondOperand = 0;
+ TextRange Range;
+};
+
+struct SourceMacroFusionRule final {
+ std::string Symbol;
+ std::string Feature;
+ std::vector<std::string> FirstOpcodeSymbols;
+ std::vector<std::string> SecondOpcodeSymbols;
+ std::vector<SourceMacroFusionOpcodePair> OpcodePairs;
+ std::vector<SourceMacroFusionImmediatePredicate> ImmediatePredicates;
+ std::vector<SourceMacroFusionRegisterInequality> RegisterInequalities;
+ std::vector<SourceMacroFusionImmediateRelation> ImmediateRelations;
+ std::uint32_t FirstDefinitionOperand = 0;
+ std::uint32_t SecondUseOperand = 0;
+ std::uint32_t SecondDefinitionOperand = 0;
+ std::optional<std::uint32_t> CommutableSecondUseOperand;
+ bool RequireSingleNonDebugUse = false;
+ bool RequireSecondDestinationTie = false;
+ TextRange Range;
+};
+
+struct SourceMCPseudoOperand final {
+ std::optional<std::uint32_t> SourceOperandIndex;
+ std::string RegisterSymbol;
+ std::optional<std::int64_t> Immediate;
+ TextRange Range;
+};
+
+struct SourceMCPseudoExpansion final {
+ std::string PseudoOpcodeSymbol;
+ std::string ResultOpcodeSymbol;
+ std::vector<SourceMCPseudoOperand> Operands;
+ TextRange Range;
+};
+
+struct SourceEncodingCategory final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::uint32_t SizeInBytes = 0;
+ TextRange Range;
+};
+
+struct SourceAssemblyFormat final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ TextRange Range;
+};
+
+struct SourceOperand final {
+ std::vector<std::string> Kinds;
+ std::string RegisterRole = "none";
+ std::optional<std::string> RegisterClassSymbol;
+ std::optional<std::string> RegisterBankSymbol;
+ std::optional<std::string> ImmediatePredicateSymbol;
+ std::string MemoryRole = "none";
+ std::optional<std::uint32_t> DefaultTiedOperand;
+ bool EarlyClobber = false;
+ bool Optional = false;
+ bool VariadicGroup = false;
+ bool AllowSubReg = false;
+ std::optional<std::string> NameSymbol;
+ std::optional<std::uint16_t> TypeIndex;
+ std::uint32_t AllowedTargetFlags = 0;
+ TextRange Range;
+};
+
+struct SourceImplicitRegister final {
+ std::string RegisterSymbol;
+ bool EarlyClobber = false;
+ bool Renamable = false;
+ TextRange Range;
+};
+
+struct SourceInstruction final {
+ std::uint32_t ID = 0;
+ std::string Symbol;
+ std::string Name;
+ std::string AssemblyMnemonic;
+ std::optional<std::uint32_t> BinaryEncoding;
+ std::vector<SourceOperand> Operands;
+ std::uint32_t NumExplicitDefs = 0;
+ bool Variadic = false;
+ std::vector<SourceImplicitRegister> ImplicitDefs;
+ std::vector<SourceImplicitRegister> ImplicitUses;
+ bool AllowExtraImplicitOperands = false;
+ std::vector<std::string> Flags;
+ std::string SchedulingClassSymbol;
+ std::string EncodingCategorySymbol;
+ std::uint32_t SizeInBytes = 0;
+ std::string AssemblyFormatSymbol;
+ bool RequiresMemoryOperands = false;
+ std::string Owner = "none";
+ std::string Deadline = "emission";
+ TextRange Range;
+};
+
+struct SourceSelectionTypePredicate final {
+ std::string Kind;
+ std::uint32_t Bits = 0;
+ TextRange Range;
+};
+
+struct SourceSelectionOperandTypePredicate final {
+ std::uint32_t OperandIndex = 0;
+ SourceSelectionTypePredicate Type;
+ TextRange Range;
+};
+
+struct SourceSelectionOperandBankPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::string BankSymbol;
+ TextRange Range;
+};
+
+struct SourceSelectionOperandClassPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::string ClassSymbol;
+ TextRange Range;
+};
+
+struct SourceSelectionIntegerPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::string Predicate;
+ TextRange Range;
+};
+
+struct SourceSelectionFloatingPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::string Predicate;
+ TextRange Range;
+};
+
+struct SourceSelectionTargetPredicate final {
+ std::string Symbol;
+ TextRange Range;
+};
+
+struct SourceSelectionMemoryPredicate final {
+ std::uint32_t MemoryOperandIndex = 0;
+ std::uint32_t Bytes = 0;
+ TextRange Range;
+};
+
+struct SourceSelectionConstantRange final {
+ std::int64_t Minimum = 0;
+ std::int64_t Maximum = 0;
+ TextRange SourceRange;
+};
+
+struct SourceSelectionOperandImmediatePredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::vector<SourceSelectionConstantRange> Ranges;
+ TextRange Range;
+};
+
+struct SourceSelectionOperandDefConstantPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::vector<SourceSelectionConstantRange> Ranges;
+ TextRange Range;
+};
+
+struct SourceSelectionDefUseCapture final {
+ std::string Symbol;
+ std::uint32_t OperandIndex = 0;
+ TextRange Range;
+};
+
+struct SourceSelectionDefUsePredicate final {
+ std::uint32_t RootOperandIndex = 0;
+ std::string OpcodeSymbol;
+ std::optional<SourceSelectionIntegerPredicate> IntegerPredicate;
+ std::vector<SourceSelectionDefUseCapture> Captures;
+ std::vector<SourceSelectionOperandDefConstantPredicate> OperandDefConstants;
+ TextRange Range;
+};
+
+struct SourceSelectionTemporary final {
+ std::string Symbol;
+ std::optional<std::uint32_t> TypeFromOperand;
+ std::optional<SourceSelectionTypePredicate> Type;
+ TextRange Range;
+};
+
+struct SourceSelectionOperandRenderer final {
+ std::optional<std::uint32_t> OperandIndex;
+ std::optional<std::uint32_t> ComplexOperandIndex;
+ std::string PhysicalRegisterSymbol;
+ std::string ComplexRendererSymbol;
+ std::string TemporarySymbol;
+ std::string CapturedOperandSymbol;
+ std::optional<std::uint32_t> CapturedImmediateOperand;
+ std::optional<std::int64_t> Immediate;
+ std::string ImmediateTransform;
+ std::vector<std::string> Flags;
+ TextRange Range;
+};
+
+struct SourceSelectionAction final {
+ std::string ResultOpcodeSymbol;
+ bool ReplacesRoot = false;
+ std::vector<SourceSelectionOperandRenderer> OperandRenderers;
+ TextRange Range;
+};
+
+struct SourceSelectionRule final {
+ std::string Symbol;
+ std::uint32_t Priority = 0;
+ std::string MatchOpcodeSymbol;
+ std::optional<SourceSelectionTypePredicate> ResultType;
+ std::optional<SourceSelectionIntegerPredicate> IntegerPredicate;
+ std::optional<SourceSelectionFloatingPredicate> FloatingPredicate;
+ std::optional<SourceSelectionMemoryPredicate> MemoryPredicate;
+ std::vector<SourceSelectionTargetPredicate> TargetPredicates;
+ std::vector<SourceSelectionOperandTypePredicate> OperandTypes;
+ std::vector<SourceSelectionOperandBankPredicate> OperandBanks;
+ std::vector<SourceSelectionOperandClassPredicate> OperandClasses;
+ std::vector<SourceSelectionOperandImmediatePredicate> OperandImmediates;
+ std::vector<SourceSelectionOperandDefConstantPredicate> OperandDefConstants;
+ std::vector<SourceSelectionDefUsePredicate> DefUsePredicates;
+ std::vector<SourceSelectionTemporary> Temporaries;
+ std::vector<SourceSelectionAction> Actions;
+ std::vector<std::uint32_t> EraseOperandDefinitions;
+ TextRange Range;
+};
+
+struct SourceCombinerOperandRenderer final {
+ enum class Kind : std::uint8_t {
+ RootOperand,
+ CapturedOperand,
+ CapturedTypeBits,
+ Immediate,
+ };
+
+ Kind SourceKind = Kind::RootOperand;
+ std::uint32_t OperandIndex = 0;
+ std::string CaptureSymbol;
+ std::int64_t Immediate = 0;
+ TextRange Range;
+};
+
+enum class SourceCombinerActionKind : std::uint8_t {
+ ReplaceRootWithCapturedOperand,
+ MutateRoot,
+};
+
+struct SourceCombinerAction final {
+ SourceCombinerActionKind Kind = SourceCombinerActionKind::ReplaceRootWithCapturedOperand;
+ std::string CapturedOperandSymbol;
+ std::string ResultOpcodeSymbol;
+ std::vector<SourceCombinerOperandRenderer> OperandRenderers;
+ std::vector<std::string> ClearInstructionFlags;
+ TextRange Range;
+};
+
+struct SourceCombinerRule final {
+ std::string Symbol;
+ std::uint32_t Priority = 0;
+ std::string MatchOpcodeSymbol;
+ std::optional<SourceSelectionTypePredicate> ResultType;
+ std::vector<SourceSelectionOperandTypePredicate> OperandTypes;
+ std::vector<SourceSelectionTargetPredicate> TargetPredicates;
+ std::vector<std::string> InstructionFlags;
+ std::vector<SourceSelectionDefUsePredicate> DefUsePredicates;
+ SourceCombinerAction Action;
+ std::vector<std::uint32_t> EraseOperandDefinitions;
+ TextRange Range;
+};
+
+struct DescriptionAST final {
+ SourceTarget Target;
+ std::vector<SourceRegisterUnit> RegisterUnits;
+ std::vector<SourceRegister> Registers;
+ std::vector<SourceRegisterBank> RegisterBanks;
+ std::vector<SourceRegisterClass> RegisterClasses;
+ std::vector<SourceRegisterMask> RegisterMasks;
+ SourceMIROperandFlags MIROperandFlags;
+ std::vector<SourceCallingConvention> CallingConventions;
+ std::vector<SourceNamedOperand> NamedOperands;
+ std::vector<SourceImmediatePredicate> ImmediatePredicates;
+ std::vector<SourceSchedulingClass> SchedulingClasses;
+ std::vector<SourceEncodingCategory> EncodingCategories;
+ std::vector<SourceAssemblyFormat> AssemblyFormats;
+ std::vector<SourceInstruction> Instructions;
+ std::vector<SourceSelectionRule> SelectionRules;
+ std::vector<SourceCombinerRule> CombinerRules;
+ std::vector<SourceMacroFusionRule> MacroFusionRules;
+ std::vector<SourceMCPseudoExpansion> MCPseudoExpansions;
+};
+
+[[nodiscard]] std::string lowerASCII(std::string_view Value);
+[[nodiscard]] bool isIdentifier(std::string_view Value) noexcept;
+[[nodiscard]] bool isAssemblyMnemonic(std::string_view Value) noexcept;
+[[nodiscard]] std::string upperIdentifier(std::string_view Value);
+void appendQuoted(std::ostream &Output, std::string_view Value);
+
+} // namespace rcc::targetgen
+
+#endif // RCC_TABLEGEN_RECORD_H