// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_GLOBALISEL_LEGALIZERHELPER_H #define RCC_CODEGEN_GLOBALISEL_LEGALIZERHELPER_H #include "rcc/CodeGen/GenericOpcodes.h" #include "rcc/CodeGen/GlobalISel/LegalizerInfo.h" #include "rcc/CodeGen/MachineIRBuilder.h" #include "rcc/Support/Error.h" #include namespace rcc { class MachineFunction; class MachineInstr; class GISelChangeObserver; class LegalizerHelper final { public: MachineIRBuilder &MIRBuilder; GISelChangeObserver &Observer; LegalizerHelper(MachineFunction &Function, const LegalizerInfo &Info, GISelChangeObserver &Observer, MachineIRBuilder &MIRBuilder); [[nodiscard]] Expected legalize(MachineInstr &Instruction, const LegalizationDecision &Decision); [[nodiscard]] Expected lower(MachineInstr &Instruction, const LegalizationDecision &Decision); [[nodiscard]] Expected lowerAbsToAddXor(MachineInstr &Instruction); [[nodiscard]] Expected lowerAbsDiffToSelect(MachineInstr &Instruction); [[nodiscard]] Expected lowerAbsDiffToMinMax(MachineInstr &Instruction); [[nodiscard]] Expected lowerMinMax(MachineInstr &Instruction); [[nodiscard]] Expected lowerThreewayCompare(MachineInstr &Instruction); [[nodiscard]] Expected lowerVAArg(MachineInstr &Instruction); [[nodiscard]] Expected widenScalar(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType WideType); [[nodiscard]] Expected widenScalarSrc(MachineInstr &Instruction, LowLevelType WideType, std::size_t OperandIndex, GenericOpcode ExtensionOpcode); [[nodiscard]] Expected narrowScalarSrc(MachineInstr &Instruction, LowLevelType NarrowType, std::size_t OperandIndex); [[nodiscard]] Expected narrowScalarDst(MachineInstr &Instruction, LowLevelType NarrowType, std::size_t OperandIndex, GenericOpcode ExtensionOpcode); [[nodiscard]] Expected widenScalarDst(MachineInstr &Instruction, LowLevelType WideType, std::size_t OperandIndex = 0, GenericOpcode TruncOpcode = GenericOpcode::G_TRUNC); [[nodiscard]] Expected narrowScalar(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); private: [[nodiscard]] Expected widenScalarMergeValues(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType WideType); [[nodiscard]] Expected widenScalarUnmergeValues(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType WideType); [[nodiscard]] Expected insertParts(Register Destination, LowLevelType ResultType, LowLevelType PartType, const std::vector &PartRegisters, LowLevelType LeftoverType = {}, const std::vector &LeftoverRegisters = {}); [[nodiscard]] Expected extractGCDType(std::vector &Parts, LowLevelType GCDType, Register Source); [[nodiscard]] Expected extractGCDType(std::vector &Parts, LowLevelType DestinationType, LowLevelType NarrowType, Register Source); [[nodiscard]] Expected buildLCMMergePieces(LowLevelType DestinationType, LowLevelType NarrowType, LowLevelType GCDType, std::vector &Registers, GenericOpcode PadStrategy = GenericOpcode::G_ANYEXT); [[nodiscard]] Expected buildWidenedRemergeToDst(Register Destination, LowLevelType LCMType, const std::vector &RemergeRegisters); [[nodiscard]] Expected narrowScalarAddSub(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarBasic(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarExt(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarSelect(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarShift(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType NarrowType); [[nodiscard]] Expected narrowScalarShiftByConstant(MachineInstr &Instruction, const APInt &Amount, LowLevelType HalfType, LowLevelType AmountType); [[nodiscard]] Expected narrowScalarShiftMultiway(MachineInstr &Instruction, LowLevelType TargetType); [[nodiscard]] Expected narrowScalarShiftByConstantMultiway(MachineInstr &Instruction, const APInt &Amount, LowLevelType TargetType, LowLevelType AmountType); struct ShiftParameters final { Register WordShift; Register BitShift; Register InverseBitShift; Register Zero; Register SignBit; }; [[nodiscard]] Expected buildConstantShiftPart(GenericOpcode Generic, std::size_t PartIndex, std::size_t PartCount, const std::vector &SourceParts, const ShiftParameters &Parameters, LowLevelType TargetType); [[nodiscard]] Expected buildVariableShiftPart(GenericOpcode Generic, Register MainOperand, Register ShiftAmount, LowLevelType TargetType, Register CarryOperand = {}); [[nodiscard]] Expected widenScalarAddSubOverflow(MachineInstr &Instruction, std::size_t TypeIndex, LowLevelType WideType); [[nodiscard]] Expected lowerSignedAddSubOverflow(MachineInstr &Instruction); MachineFunction &Function; MachineRegisterInfo &MRI; const LegalizerInfo &Info; }; } // namespace rcc #endif // RCC_CODEGEN_GLOBALISEL_LEGALIZERHELPER_H