From 6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Mon, 3 Aug 2026 18:31:58 +0800 Subject: [CodeGen] Model complete MIR operands --- backend/include/rcc/CodeGen/MachineOperand.h | 178 ++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 4 deletions(-) (limited to 'backend/include/rcc/CodeGen/MachineOperand.h') diff --git a/backend/include/rcc/CodeGen/MachineOperand.h b/backend/include/rcc/CodeGen/MachineOperand.h index ce5eb60..7344932 100644 --- a/backend/include/rcc/CodeGen/MachineOperand.h +++ b/backend/include/rcc/CodeGen/MachineOperand.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace rcc { @@ -58,6 +59,39 @@ private: std::uint8_t WordCount; }; +class IntegerImmediate final { +public: + static constexpr std::uint32_t MaxBitWidth = std::uint32_t{1} << 23U; + + [[nodiscard]] static Expected create(std::uint32_t BitWidth, + std::span Words); + [[nodiscard]] static Expected fromUnsigned(std::uint32_t BitWidth, + std::uint64_t Value); + [[nodiscard]] static Expected fromSigned(std::uint32_t BitWidth, + std::int64_t Value); + + [[nodiscard]] std::uint32_t bitWidth() const noexcept { + return BitWidth; + } + + [[nodiscard]] std::span words() const noexcept { + return Words; + } + + [[nodiscard]] bool isZero() const noexcept; + [[nodiscard]] bool isNegative() const noexcept; + [[nodiscard]] Expected verify() const; + + friend bool operator==(const IntegerImmediate &Left, const IntegerImmediate &Right) = default; + +private: + IntegerImmediate(std::uint32_t BitWidth, std::vector Words) + : BitWidth(BitWidth), Words(std::move(Words)) {} + + std::uint32_t BitWidth; + std::vector Words; +}; + enum class RegisterOperandFlag : std::uint8_t { Define, Use, @@ -115,6 +149,13 @@ struct FloatingImmediateOperand final { const FloatingImmediateOperand &Right) = default; }; +struct IntegerImmediateOperand final { + IntegerImmediate Value; + + friend bool operator==(const IntegerImmediateOperand &Left, + const IntegerImmediateOperand &Right) = default; +}; + struct BasicBlockOperand final { MachineBasicBlock *Block = nullptr; @@ -176,6 +217,13 @@ struct RegisterMaskOperand final { const RegisterMaskOperand &Right) = default; }; +struct LiveOutRegisterMaskOperand final { + std::shared_ptr Mask; + + friend bool operator==(const LiveOutRegisterMaskOperand &Left, + const LiveOutRegisterMaskOperand &Right) = default; +}; + struct MetadataOperand final { MachineMetadataValue Value; @@ -197,11 +245,106 @@ struct MCSymbolOperand final { friend bool operator==(const MCSymbolOperand &Left, const MCSymbolOperand &Right) = default; }; +struct CFIIndexOperand final { + CFIInstructionIndex Index; + + friend constexpr bool operator==(CFIIndexOperand Left, CFIIndexOperand Right) noexcept = default; +}; + +struct IntrinsicOperand final { + IntrinsicID ID; + + friend constexpr bool operator==(IntrinsicOperand Left, + IntrinsicOperand Right) noexcept = default; +}; + +enum class IntegerPredicate : std::uint8_t { + Equal, + NotEqual, + SignedGreaterThan, + SignedGreaterEqual, + SignedLessThan, + SignedLessEqual, + UnsignedGreaterThan, + UnsignedGreaterEqual, + UnsignedLessThan, + UnsignedLessEqual, + Count, +}; + +enum class FloatingPredicate : std::uint8_t { + AlwaysFalse, + OrderedEqual, + OrderedGreaterThan, + OrderedGreaterEqual, + OrderedLessThan, + OrderedLessEqual, + OrderedNotEqual, + Ordered, + Unordered, + UnorderedEqual, + UnorderedGreaterThan, + UnorderedGreaterEqual, + UnorderedLessThan, + UnorderedLessEqual, + UnorderedNotEqual, + AlwaysTrue, + Count, +}; + +class PredicateOperand final { +public: + explicit PredicateOperand(IntegerPredicate Predicate) : Value(Predicate) {} + explicit PredicateOperand(FloatingPredicate Predicate) : Value(Predicate) {} + + [[nodiscard]] bool isInteger() const noexcept { + return std::holds_alternative(Value); + } + + [[nodiscard]] const IntegerPredicate *integerPredicate() const noexcept { + return std::get_if(&Value); + } + + [[nodiscard]] const FloatingPredicate *floatingPredicate() const noexcept { + return std::get_if(&Value); + } + + [[nodiscard]] Expected verify() const; + + friend bool operator==(const PredicateOperand &Left, const PredicateOperand &Right) = default; + +private: + std::variant Value; +}; + +struct ShuffleMaskOperand final { + static constexpr std::int32_t Undef = -1; + + std::vector Elements; + + friend bool operator==(const ShuffleMaskOperand &Left, const ShuffleMaskOperand &Right) = default; +}; + +struct DebugInstrRefOperand final { + std::uint32_t InstructionNumber = 0; + std::uint32_t OperandNumber = 0; + + friend constexpr bool operator==(DebugInstrRefOperand Left, + DebugInstrRefOperand Right) noexcept = default; +}; + +struct LaneMaskOperand final { + LaneMask Mask; + + friend constexpr bool operator==(LaneMaskOperand Left, LaneMaskOperand Right) noexcept = default; +}; + class MachineOperand final { public: enum class Kind : std::uint8_t { Register, Immediate, + IntegerImmediate, FloatingImmediate, BasicBlock, FrameIndex, @@ -211,9 +354,16 @@ public: ExternalSymbol, BlockAddress, RegisterMask, + LiveOutRegisterMask, Metadata, TargetIndex, MCSymbol, + CFIIndex, + Intrinsic, + Predicate, + ShuffleMask, + DebugInstrRef, + LaneMask, Count, }; @@ -228,6 +378,8 @@ public: SubRegIndex SubReg = {}, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand immediate(std::int64_t Value, std::uint32_t TargetFlags = 0); + [[nodiscard]] static MachineOperand integerImmediate(IntegerImmediate Value, + std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand floatingImmediate(FloatingPointBits Bits, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand basicBlock(MachineBasicBlock &Block, @@ -248,12 +400,28 @@ public: std::uint32_t TargetFlags = 0); [[nodiscard]] static Expected registerMask(std::shared_ptr Mask, std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected + liveOutRegisterMask(std::shared_ptr Mask, std::uint32_t TargetFlags = 0); [[nodiscard]] static Expected metadata(MachineMetadataValue Value, std::uint32_t TargetFlags = 0); [[nodiscard]] static MachineOperand targetIndex(TargetIndex Index, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); [[nodiscard]] static Expected mcSymbol(std::string Name, std::int64_t Offset = 0, std::uint32_t TargetFlags = 0); + [[nodiscard]] static MachineOperand cfiIndex(CFIInstructionIndex Index, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected intrinsic(IntrinsicID ID, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected integerPredicate(IntegerPredicate Predicate, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected floatingPredicate(FloatingPredicate Predicate, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected shuffleMask(std::vector Elements, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected debugInstrRef(std::uint64_t InstructionNumber, + std::uint64_t OperandNumber, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static MachineOperand laneMask(LaneMask Mask, std::uint32_t TargetFlags = 0); [[nodiscard]] Kind kind() const noexcept { return OperandKind; @@ -307,10 +475,12 @@ public: private: using OperandStorage = - std::variant; + std::variant; MachineOperand(Kind OperandKind, OperandStorage Storage, std::uint32_t TargetFlags = 0) : OperandKind(OperandKind), Storage(std::move(Storage)), TargetFlags(TargetFlags) {} -- cgit v1.2.3