// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_TARGETMIRTEXTINFO_H #define RCC_CODEGEN_TARGETMIRTEXTINFO_H #include "rcc/CodeGen/MachineFrameInfo.h" #include "rcc/CodeGen/MachineIRTypes.h" #include "rcc/CodeGen/Register.h" #include "rcc/CodeGen/RegisterMask.h" #include "rcc/Support/Error.h" #include #include #include #include #include #include #include #include #include #include namespace rcc { class TargetRegisterInfo; struct MIRRegisterMaskDesc final { std::string Name; std::shared_ptr Mask; }; struct MIRTargetIndexDesc final { std::string Name; TargetIndex Index; }; struct MIROperandFlagDesc final { std::string Name; std::uint32_t Value = 0; }; struct MIRMachineMemOperandFlagDesc final { std::string Name; std::uint16_t Value = 0; }; struct MIRVirtualRegisterFlagDesc final { std::string Name; std::uint8_t Value = 0; }; struct MIRIntrinsicDesc final { std::string Name; IntrinsicID ID; }; struct MIRCFIRegisterMappingDesc final { PhysicalRegister Register; std::uint32_t DwarfRegister = 0; bool IsCanonical = true; }; struct TargetMIRTextInfoDesc final { std::vector RegisterMasks; std::vector TargetIndices; std::uint32_t DirectOperandFlagMask = 0; std::vector DirectOperandFlags; std::vector BitmaskOperandFlags; std::vector MachineMemOperandFlags; std::vector VirtualRegisterFlags; std::vector Intrinsics; std::vector CFIRegisters; std::vector SupportedStackIDs{ StackID::defaultStack(), StackID::noAllocStack(), }; std::optional FunctionStateType; }; class TargetMIRTextInfo final { public: TargetMIRTextInfo(const TargetMIRTextInfo &) = delete; TargetMIRTextInfo &operator=(const TargetMIRTextInfo &) = delete; TargetMIRTextInfo(TargetMIRTextInfo &&) noexcept = default; TargetMIRTextInfo &operator=(TargetMIRTextInfo &&) noexcept = default; ~TargetMIRTextInfo() = default; [[nodiscard]] static Expected create(TargetMIRTextInfoDesc Description, const TargetRegisterInfo &Registers); [[nodiscard]] std::span registerMasks() const noexcept { return Description.RegisterMasks; } [[nodiscard]] std::span targetIndices() const noexcept { return Description.TargetIndices; } [[nodiscard]] std::span directOperandFlags() const noexcept { return Description.DirectOperandFlags; } [[nodiscard]] std::span bitmaskOperandFlags() const noexcept { return Description.BitmaskOperandFlags; } [[nodiscard]] std::span machineMemOperandFlags() const noexcept { return Description.MachineMemOperandFlags; } [[nodiscard]] std::span virtualRegisterFlags() const noexcept { return Description.VirtualRegisterFlags; } [[nodiscard]] std::span intrinsics() const noexcept { return Description.Intrinsics; } [[nodiscard]] std::shared_ptr registerMask(std::string_view Name) const noexcept; [[nodiscard]] std::optional registerMaskName(const RegisterMask &Mask) const noexcept; [[nodiscard]] std::optional targetIndex(std::string_view Name) const noexcept; [[nodiscard]] std::optional targetIndexName(TargetIndex Index) const noexcept; [[nodiscard]] std::optional directOperandFlag(std::string_view Name) const noexcept; [[nodiscard]] std::optional bitmaskOperandFlag(std::string_view Name) const noexcept; [[nodiscard]] Expected> operandFlagNames(std::uint32_t Flags) const; [[nodiscard]] Expected validateOperandFlags(std::uint32_t Flags) const; [[nodiscard]] std::optional machineMemOperandFlag(std::string_view Name) const noexcept; [[nodiscard]] Expected> machineMemOperandFlagNames(std::uint16_t Flags) const; [[nodiscard]] Expected validateMachineMemOperandFlags(std::uint16_t Flags) const; [[nodiscard]] std::optional virtualRegisterFlag(std::string_view Name) const noexcept; [[nodiscard]] Expected> virtualRegisterFlagNames(std::uint8_t Flags) const; [[nodiscard]] Expected validateVirtualRegisterFlags(std::uint8_t Flags) const; [[nodiscard]] std::optional intrinsic(std::string_view Name) const noexcept; [[nodiscard]] std::optional intrinsicName(IntrinsicID ID) const noexcept; [[nodiscard]] std::optional dwarfRegister(PhysicalRegister Register) const noexcept; [[nodiscard]] std::optional physicalRegister(std::uint32_t DwarfRegister) const noexcept; [[nodiscard]] std::span supportedStackIDs() const noexcept { return Description.SupportedStackIDs; } [[nodiscard]] bool supportsStackID(StackID ID) const noexcept { return SupportedStackIDs.contains(ID.value()); } [[nodiscard]] std::uint32_t directOperandFlagMask() const noexcept { return Description.DirectOperandFlagMask; } [[nodiscard]] std::uint32_t serializableOperandFlagMask() const noexcept { return SerializableOperandFlagMask; } [[nodiscard]] std::uint16_t serializableMachineMemOperandFlagMask() const noexcept { return SerializableMachineMemOperandFlagMask; } [[nodiscard]] std::uint8_t serializableVirtualRegisterFlagMask() const noexcept { return SerializableVirtualRegisterFlagMask; } [[nodiscard]] std::optional functionStateType() const noexcept { return Description.FunctionStateType; } private: explicit TargetMIRTextInfo(TargetMIRTextInfoDesc Description) : Description(std::move(Description)) {} TargetMIRTextInfoDesc Description; std::unordered_map RegisterMaskNameToIndex; std::unordered_map TargetIndexNameToIndex; std::unordered_map TargetIndexToIndex; std::unordered_map DirectOperandFlagNameToIndex; std::unordered_map DirectOperandFlagToIndex; std::unordered_map BitmaskOperandFlagNameToIndex; std::unordered_map MachineMemOperandFlagNameToIndex; std::unordered_map VirtualRegisterFlagNameToIndex; std::unordered_map IntrinsicNameToIndex; std::unordered_map IntrinsicToIndex; std::unordered_map RegisterToDwarf; std::unordered_map DwarfToRegister; std::unordered_set SupportedStackIDs; std::uint32_t SerializableOperandFlagMask = 0; std::uint16_t SerializableMachineMemOperandFlagMask = 0; std::uint8_t SerializableVirtualRegisterFlagMask = 0; }; } // namespace rcc #endif // RCC_CODEGEN_TARGETMIRTEXTINFO_H