aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/include/rcc/CodeGen')
-rw-r--r--backend/include/rcc/CodeGen/InstructionDescriptor.h49
1 files changed, 49 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/InstructionDescriptor.h b/backend/include/rcc/CodeGen/InstructionDescriptor.h
index 06e37d3..7cf598d 100644
--- a/backend/include/rcc/CodeGen/InstructionDescriptor.h
+++ b/backend/include/rcc/CodeGen/InstructionDescriptor.h
@@ -3,6 +3,7 @@
#ifndef RCC_CODEGEN_INSTRUCTIONDESCRIPTOR_H
#define RCC_CODEGEN_INSTRUCTIONDESCRIPTOR_H
+#include "rcc/CodeGen/LowLevelType.h"
#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/MachineOperand.h"
#include "rcc/CodeGen/Register.h"
@@ -26,6 +27,11 @@ class MachineInstr;
class MachineMemOperand;
class MachineRegisterInfo;
+using ExplicitOperandVerifier = Expected<void> (*)(Opcode, std::span<const MachineOperand>,
+ const MachineRegisterInfo &);
+using InstructionSemanticVerifier = Expected<void> (*)(const MachineInstr &,
+ const MachineRegisterInfo &);
+
class OperandKindSet final {
public:
static_assert(static_cast<std::uint32_t>(MachineOperand::Kind::Count) <= 32);
@@ -61,11 +67,45 @@ private:
std::uint32_t Mask = 0;
};
+class LLTKindSet final {
+public:
+ static_assert(static_cast<std::uint32_t>(LLT::Kind::VectorPointer) < 16);
+
+ constexpr LLTKindSet() noexcept = default;
+
+ LLTKindSet(std::initializer_list<LLT::Kind> Kinds) noexcept;
+
+ [[nodiscard]] constexpr bool empty() const noexcept {
+ return Mask == 0;
+ }
+
+ [[nodiscard]] constexpr bool contains(LLT::Kind Kind) const noexcept {
+ const auto Index = static_cast<std::uint32_t>(Kind);
+ return Index < 16 && (Mask & (std::uint16_t{1} << Index)) != 0;
+ }
+
+ constexpr void add(LLT::Kind Kind) noexcept {
+ const auto Index = static_cast<std::uint32_t>(Kind);
+ if (Index < 16)
+ Mask |= std::uint16_t{1} << Index;
+ }
+
+ [[nodiscard]] constexpr std::uint16_t rawValue() const noexcept {
+ return Mask;
+ }
+
+ friend constexpr bool operator==(LLTKindSet Left, LLTKindSet Right) noexcept = default;
+
+private:
+ std::uint16_t Mask = 0;
+};
+
enum class RegisterOperandRole : std::uint8_t {
None,
Def,
Use,
DefUse,
+ Any,
};
enum class MemoryOperandRole : std::uint8_t {
@@ -76,6 +116,11 @@ enum class MemoryOperandRole : std::uint8_t {
Ordering,
};
+struct OperandTypeConstraint final {
+ LLTKindSet Kinds;
+ std::optional<std::uint16_t> EqualityGroup;
+};
+
enum class InstructionFlag : std::uint8_t {
Terminator,
Branch,
@@ -184,6 +229,7 @@ struct OperandDescriptor final {
std::optional<NamedOperandID> Name;
std::optional<TargetOperandTypeID> TargetOperandType;
std::uint32_t AllowedTargetFlags = 0;
+ std::optional<OperandTypeConstraint> TypeConstraint;
};
struct ImplicitRegisterDescriptor final {
@@ -201,6 +247,7 @@ struct InstructionDescriptor final {
std::vector<OperandDescriptor> Operands;
std::size_t NumExplicitDefs = 0;
bool Variadic = false;
+ std::size_t MinimumVariadicRepetitions = 0;
std::vector<ImplicitRegisterDescriptor> ImplicitDefs;
std::vector<ImplicitRegisterDescriptor> ImplicitUses;
bool AllowExtraImplicitOperands = false;
@@ -211,6 +258,8 @@ struct InstructionDescriptor final {
bool RequiresMemoryOperands = false;
PseudoOwner Owner = PseudoOwner::None;
PipelineStage Deadline = PipelineStage::Emission;
+ ExplicitOperandVerifier VerifyExplicitOperands = nullptr;
+ InstructionSemanticVerifier VerifyInstructionSemantics = nullptr;
};
struct ImmediatePredicate final {