diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-03 18:31:58 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-03 18:31:58 +0800 |
| commit | 6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56 (patch) | |
| tree | 3bea5331666575eb6a9cc7aa26842c7387cb372b /backend/include/rcc/CodeGen/MachineOperand.h | |
| parent | a8a9d7d926202450645deae872d4d9dc11d63215 (diff) | |
| download | rcc-project-6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56.tar.gz rcc-project-6580ac1c05bd1cbccd2dcd71fd9c2a384ae3db56.tar.xz | |
[CodeGen] Model complete MIR operands
Diffstat (limited to 'backend/include/rcc/CodeGen/MachineOperand.h')
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineOperand.h | 178 |
1 files changed, 174 insertions, 4 deletions
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 <string_view> #include <utility> #include <variant> +#include <vector> 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<IntegerImmediate> create(std::uint32_t BitWidth, + std::span<const std::uint64_t> Words); + [[nodiscard]] static Expected<IntegerImmediate> fromUnsigned(std::uint32_t BitWidth, + std::uint64_t Value); + [[nodiscard]] static Expected<IntegerImmediate> fromSigned(std::uint32_t BitWidth, + std::int64_t Value); + + [[nodiscard]] std::uint32_t bitWidth() const noexcept { + return BitWidth; + } + + [[nodiscard]] std::span<const std::uint64_t> words() const noexcept { + return Words; + } + + [[nodiscard]] bool isZero() const noexcept; + [[nodiscard]] bool isNegative() const noexcept; + [[nodiscard]] Expected<void> verify() const; + + friend bool operator==(const IntegerImmediate &Left, const IntegerImmediate &Right) = default; + +private: + IntegerImmediate(std::uint32_t BitWidth, std::vector<std::uint64_t> Words) + : BitWidth(BitWidth), Words(std::move(Words)) {} + + std::uint32_t BitWidth; + std::vector<std::uint64_t> 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<const RegisterMask> 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<IntegerPredicate>(Value); + } + + [[nodiscard]] const IntegerPredicate *integerPredicate() const noexcept { + return std::get_if<IntegerPredicate>(&Value); + } + + [[nodiscard]] const FloatingPredicate *floatingPredicate() const noexcept { + return std::get_if<FloatingPredicate>(&Value); + } + + [[nodiscard]] Expected<void> verify() const; + + friend bool operator==(const PredicateOperand &Left, const PredicateOperand &Right) = default; + +private: + std::variant<IntegerPredicate, FloatingPredicate> Value; +}; + +struct ShuffleMaskOperand final { + static constexpr std::int32_t Undef = -1; + + std::vector<std::int32_t> 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<MachineOperand> registerMask(std::shared_ptr<const RegisterMask> Mask, std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected<MachineOperand> + liveOutRegisterMask(std::shared_ptr<const RegisterMask> Mask, std::uint32_t TargetFlags = 0); [[nodiscard]] static Expected<MachineOperand> 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<MachineOperand> 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<MachineOperand> intrinsic(IntrinsicID ID, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected<MachineOperand> integerPredicate(IntegerPredicate Predicate, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected<MachineOperand> floatingPredicate(FloatingPredicate Predicate, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected<MachineOperand> shuffleMask(std::vector<std::int32_t> Elements, + std::uint32_t TargetFlags = 0); + [[nodiscard]] static Expected<MachineOperand> 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<Register, std::int64_t, FloatingImmediateOperand, BasicBlockOperand, - FrameIndexOperand, ConstantPoolOperand, JumpTableOperand, GlobalSymbolOperand, - ExternalSymbolOperand, BlockAddressOperand, RegisterMaskOperand, MetadataOperand, - TargetIndexOperand, MCSymbolOperand>; + std::variant<Register, std::int64_t, IntegerImmediateOperand, FloatingImmediateOperand, + BasicBlockOperand, FrameIndexOperand, ConstantPoolOperand, JumpTableOperand, + GlobalSymbolOperand, ExternalSymbolOperand, BlockAddressOperand, + RegisterMaskOperand, LiveOutRegisterMaskOperand, MetadataOperand, + TargetIndexOperand, MCSymbolOperand, CFIIndexOperand, IntrinsicOperand, + PredicateOperand, ShuffleMaskOperand, DebugInstrRefOperand, LaneMaskOperand>; MachineOperand(Kind OperandKind, OperandStorage Storage, std::uint32_t TargetFlags = 0) : OperandKind(OperandKind), Storage(std::move(Storage)), TargetFlags(TargetFlags) {} |
