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/MachineCFIInfo.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/MachineCFIInfo.h')
| -rw-r--r-- | backend/include/rcc/CodeGen/MachineCFIInfo.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/MachineCFIInfo.h b/backend/include/rcc/CodeGen/MachineCFIInfo.h new file mode 100644 index 0000000..1819daf --- /dev/null +++ b/backend/include/rcc/CodeGen/MachineCFIInfo.h @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_CODEGEN_MACHINECFIINFO_H +#define RCC_CODEGEN_MACHINECFIINFO_H + +#include "rcc/CodeGen/MachineIRTypes.h" +#include "rcc/Support/Error.h" + +#include <cstdint> +#include <span> +#include <string> +#include <utility> +#include <variant> +#include <vector> + +namespace rcc { + +class DwarfRegisterNumber final { +public: + constexpr DwarfRegisterNumber() noexcept = default; + + [[nodiscard]] static constexpr DwarfRegisterNumber fromValue(std::uint32_t Value) noexcept { + return DwarfRegisterNumber(Value); + } + + [[nodiscard]] constexpr std::uint32_t value() const noexcept { + return Value; + } + + friend constexpr bool operator==(DwarfRegisterNumber Left, + DwarfRegisterNumber Right) noexcept = default; + +private: + explicit constexpr DwarfRegisterNumber(std::uint32_t Value) noexcept : Value(Value) {} + + std::uint32_t Value = 0; +}; + +enum class MachineCFIOperation : std::uint8_t { + SameValue, + RememberState, + RestoreState, + Offset, + LLVMDefAddressSpaceCFA, + DefCFARegister, + DefCFAOffset, + DefCFA, + RelativeOffset, + AdjustCFAOffset, + Escape, + Restore, + Undefined, + Register, + WindowSave, + NegateReturnAddressState, + NegateReturnAddressStateWithPC, + GNUArgsSize, + Label, + ValueOffset, + LLVMRegisterPair, + LLVMVectorRegisters, + LLVMVectorOffset, + LLVMVectorRegisterMask, + Count, +}; + +struct MachineCFINoOperands final { + friend constexpr bool operator==(MachineCFINoOperands Left, + MachineCFINoOperands Right) noexcept = default; +}; + +struct MachineCFIRegisterRule final { + DwarfRegisterNumber Register; + + friend constexpr bool operator==(MachineCFIRegisterRule Left, + MachineCFIRegisterRule Right) noexcept = default; +}; + +struct MachineCFIOffsetRule final { + std::int64_t Offset = 0; + + friend constexpr bool operator==(MachineCFIOffsetRule Left, + MachineCFIOffsetRule Right) noexcept = default; +}; + +struct MachineCFIRegisterOffsetRule final { + DwarfRegisterNumber Register; + std::int64_t Offset = 0; + + friend constexpr bool operator==(MachineCFIRegisterOffsetRule Left, + MachineCFIRegisterOffsetRule Right) noexcept = default; +}; + +struct MachineCFIRegisterRegisterRule final { + DwarfRegisterNumber Register; + DwarfRegisterNumber SourceRegister; + + friend constexpr bool operator==(MachineCFIRegisterRegisterRule Left, + MachineCFIRegisterRegisterRule Right) noexcept = default; +}; + +struct MachineCFIAddressSpaceCFARule final { + DwarfRegisterNumber Register; + std::int64_t Offset = 0; + std::uint32_t AddressSpace = 0; + + friend constexpr bool operator==(MachineCFIAddressSpaceCFARule Left, + MachineCFIAddressSpaceCFARule Right) noexcept = default; +}; + +struct MachineCFIEscapeRule final { + std::vector<std::uint8_t> Bytes; + + friend bool operator==(const MachineCFIEscapeRule &Left, + const MachineCFIEscapeRule &Right) = default; +}; + +struct MachineCFILabelRule final { + std::string Symbol; + + friend bool operator==(const MachineCFILabelRule &Left, + const MachineCFILabelRule &Right) = default; +}; + +struct MachineCFIRegisterPairRule final { + DwarfRegisterNumber Register; + DwarfRegisterNumber FirstRegister; + std::uint32_t FirstSizeInBits = 0; + DwarfRegisterNumber SecondRegister; + std::uint32_t SecondSizeInBits = 0; + + friend constexpr bool operator==(MachineCFIRegisterPairRule Left, + MachineCFIRegisterPairRule Right) noexcept = default; +}; + +struct MachineCFIVectorRegisterLane final { + DwarfRegisterNumber Register; + std::uint32_t Lane = 0; + std::uint32_t SizeInBits = 0; + + friend constexpr bool operator==(MachineCFIVectorRegisterLane Left, + MachineCFIVectorRegisterLane Right) noexcept = default; +}; + +struct MachineCFIVectorRegistersRule final { + DwarfRegisterNumber Register; + std::vector<MachineCFIVectorRegisterLane> VectorRegisters; + + friend bool operator==(const MachineCFIVectorRegistersRule &Left, + const MachineCFIVectorRegistersRule &Right) = default; +}; + +struct MachineCFIVectorOffsetRule final { + DwarfRegisterNumber Register; + std::uint32_t RegisterSizeInBits = 0; + DwarfRegisterNumber MaskRegister; + std::uint32_t MaskRegisterSizeInBits = 0; + std::int64_t Offset = 0; + + friend constexpr bool operator==(MachineCFIVectorOffsetRule Left, + MachineCFIVectorOffsetRule Right) noexcept = default; +}; + +struct MachineCFIVectorRegisterMaskRule final { + DwarfRegisterNumber Register; + DwarfRegisterNumber SpillRegister; + std::uint32_t SpillRegisterLaneSizeInBits = 0; + DwarfRegisterNumber MaskRegister; + std::uint32_t MaskRegisterSizeInBits = 0; + + friend constexpr bool operator==(MachineCFIVectorRegisterMaskRule Left, + MachineCFIVectorRegisterMaskRule Right) noexcept = default; +}; + +class MachineCFIInstruction final { +public: + using Payload = + std::variant<MachineCFINoOperands, MachineCFIRegisterRule, MachineCFIOffsetRule, + MachineCFIRegisterOffsetRule, MachineCFIRegisterRegisterRule, + MachineCFIAddressSpaceCFARule, MachineCFIEscapeRule, MachineCFILabelRule, + MachineCFIRegisterPairRule, MachineCFIVectorRegistersRule, + MachineCFIVectorOffsetRule, MachineCFIVectorRegisterMaskRule>; + + [[nodiscard]] static MachineCFIInstruction sameValue(DwarfRegisterNumber Register); + [[nodiscard]] static MachineCFIInstruction rememberState(); + [[nodiscard]] static MachineCFIInstruction restoreState(); + [[nodiscard]] static MachineCFIInstruction offset(DwarfRegisterNumber Register, + std::int64_t Offset); + [[nodiscard]] static MachineCFIInstruction llvmDefAddressSpaceCFA(DwarfRegisterNumber Register, + std::int64_t Offset, + std::uint32_t AddressSpace); + [[nodiscard]] static MachineCFIInstruction defCFARegister(DwarfRegisterNumber Register); + [[nodiscard]] static MachineCFIInstruction defCFAOffset(std::int64_t Offset); + [[nodiscard]] static MachineCFIInstruction defCFA(DwarfRegisterNumber Register, + std::int64_t Offset); + [[nodiscard]] static MachineCFIInstruction relativeOffset(DwarfRegisterNumber Register, + std::int64_t Offset); + [[nodiscard]] static MachineCFIInstruction adjustCFAOffset(std::int64_t Offset); + [[nodiscard]] static Expected<MachineCFIInstruction> escape(std::vector<std::uint8_t> Bytes); + [[nodiscard]] static MachineCFIInstruction restore(DwarfRegisterNumber Register); + [[nodiscard]] static MachineCFIInstruction undefined(DwarfRegisterNumber Register); + [[nodiscard]] static MachineCFIInstruction registerRule(DwarfRegisterNumber Register, + DwarfRegisterNumber SourceRegister); + [[nodiscard]] static MachineCFIInstruction windowSave(); + [[nodiscard]] static MachineCFIInstruction negateReturnAddressState(); + [[nodiscard]] static MachineCFIInstruction negateReturnAddressStateWithPC(); + [[nodiscard]] static MachineCFIInstruction gnuArgsSize(std::int64_t Size); + [[nodiscard]] static Expected<MachineCFIInstruction> label(std::string Symbol); + [[nodiscard]] static MachineCFIInstruction valueOffset(DwarfRegisterNumber Register, + std::int64_t Offset); + [[nodiscard]] static MachineCFIInstruction llvmRegisterPair(MachineCFIRegisterPairRule Rule); + [[nodiscard]] static Expected<MachineCFIInstruction> + llvmVectorRegisters(MachineCFIVectorRegistersRule Rule); + [[nodiscard]] static MachineCFIInstruction llvmVectorOffset(MachineCFIVectorOffsetRule Rule); + [[nodiscard]] static MachineCFIInstruction + llvmVectorRegisterMask(MachineCFIVectorRegisterMaskRule Rule); + + [[nodiscard]] MachineCFIOperation operation() const noexcept { + return Operation; + } + + template <typename PayloadT> [[nodiscard]] const PayloadT *getIf() const noexcept { + return std::get_if<PayloadT>(&Data); + } + + [[nodiscard]] Expected<void> verify() const; + + friend bool operator==(const MachineCFIInstruction &Left, + const MachineCFIInstruction &Right) = default; + +private: + MachineCFIInstruction(MachineCFIOperation Operation, Payload Data) + : Operation(Operation), Data(std::move(Data)) {} + + MachineCFIOperation Operation; + Payload Data; +}; + +class MachineCFIInfo final { +public: + MachineCFIInfo() = default; + MachineCFIInfo(const MachineCFIInfo &) = delete; + MachineCFIInfo &operator=(const MachineCFIInfo &) = delete; + MachineCFIInfo(MachineCFIInfo &&) noexcept = default; + MachineCFIInfo &operator=(MachineCFIInfo &&) noexcept = default; + ~MachineCFIInfo() = default; + + [[nodiscard]] Expected<CFIInstructionIndex> addInstruction(MachineCFIInstruction Instruction); + + [[nodiscard]] const MachineCFIInstruction *instruction(CFIInstructionIndex Index) const noexcept; + + [[nodiscard]] std::span<const MachineCFIInstruction> instructions() const noexcept { + return Instructions; + } + + [[nodiscard]] Expected<void> verify() const; + [[nodiscard]] Expected<MachineCFIInfo> clone() const; + + friend bool operator==(const MachineCFIInfo &Left, const MachineCFIInfo &Right) { + return Left.Instructions == Right.Instructions; + } + +private: + std::vector<MachineCFIInstruction> Instructions; +}; + +} // namespace rcc + +#endif // RCC_CODEGEN_MACHINECFIINFO_H |
