diff options
Diffstat (limited to 'backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp')
| -rw-r--r-- | backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 97 |
1 files changed, 2 insertions, 95 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index f98f2e5..6486f5c 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -348,6 +348,8 @@ public: [[nodiscard]] Expected<bool> matchesTargetPredicate(std::string_view Name, const MachineInstr &, const MachineFunction &, const TargetDescription &) const override { + if (Name == "a") + return Subtarget.features().has(RISCVExtension::A); if (Name == "zba") return Subtarget.features().has(RISCVExtension::Zba); return makeUnexpected(ErrorCode::VerificationError, @@ -603,17 +605,6 @@ public: return Instruction.setOpcode(opcode(GenericOpcode::COPY)); case GenericOpcode::G_FCMP: return selectFloatingCompare(Instruction, Function, Target); - case GenericOpcode::G_ATOMICRMW_XCHG: - case GenericOpcode::G_ATOMICRMW_ADD: - case GenericOpcode::G_ATOMICRMW_SUB: - case GenericOpcode::G_ATOMICRMW_AND: - case GenericOpcode::G_ATOMICRMW_OR: - case GenericOpcode::G_ATOMICRMW_XOR: - case GenericOpcode::G_ATOMICRMW_MAX: - case GenericOpcode::G_ATOMICRMW_MIN: - case GenericOpcode::G_ATOMICRMW_UMAX: - case GenericOpcode::G_ATOMICRMW_UMIN: - return selectAtomicRMW(Instruction, Function, Target, Type, Generic); case GenericOpcode::G_FENCE: return selectFence(Instruction); case GenericOpcode::G_GLOBAL_VALUE: @@ -962,90 +953,6 @@ private: return *Built; } - [[nodiscard]] Expected<void> selectAtomicRMW(MachineInstr &Instruction, MachineFunction &Function, - const TargetDescription &Target, - std::optional<LowLevelType> Type, - GenericOpcode Generic) const { - const MachineOperand *AddressOperand = Instruction.operandAt(1); - const MachineOperand *ValueOperand = Instruction.operandAt(2); - const Register *Address = - AddressOperand == nullptr ? nullptr : AddressOperand->getIf<Register>(); - const Register *Value = ValueOperand == nullptr ? nullptr : ValueOperand->getIf<Register>(); - if (!Type || Address == nullptr || Value == nullptr) - return makeUnexpected(ErrorCode::VerificationError, "RISC-V atomic RMW has invalid operands"); - Register SelectedValue = *Value; - const bool IsWord = Type->scalarBitWidth() == 32; - if (Generic == GenericOpcode::G_ATOMICRMW_SUB) { - auto Negated = createTemporary(Function, *Type, Target); - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Negated || !Zero) - return std::unexpected(!Negated ? Negated.error() : Zero.error()); - MachineIRBuilder Builder(Function, Target); - auto Point = Builder.setInsertPointBefore(Instruction); - if (!Point) - return std::unexpected(Point.error()); - auto RegisterConstraints = constrainBuilderRegisters(Function, Target, {*Negated, *Value}); - if (!RegisterConstraints) - return std::unexpected(RegisterConstraints.error()); - auto Pending = Builder.buildInstr( - instructionOpcode(IsWord ? InstructionOpcode::SUBW : InstructionOpcode::SUB)); - if (!Pending) - return std::unexpected(Pending.error()); - auto Def = Pending->addDef(*Negated); - if (!Def) - return std::unexpected(Def.error()); - auto Left = Pending->addUse(Register::fromPhysical(*Zero)); - if (!Left) - return std::unexpected(Left.error()); - auto Right = Pending->addUse(*Value); - if (!Right) - return std::unexpected(Right.error()); - auto Built = Pending->build(); - if (!Built) - return std::unexpected(Built.error()); - auto Constraint = constrainSelectedInstruction(**Built, Function, Target); - if (!Constraint) - return std::unexpected(Constraint.error()); - SelectedValue = *Negated; - } - const auto SelectOpcode = [Generic, IsWord]() -> InstructionOpcode { - switch (Generic) { - case GenericOpcode::G_ATOMICRMW_XCHG: - return IsWord ? InstructionOpcode::AMOSWAP_W : InstructionOpcode::AMOSWAP_D; - case GenericOpcode::G_ATOMICRMW_ADD: - case GenericOpcode::G_ATOMICRMW_SUB: - return IsWord ? InstructionOpcode::AMOADD_W : InstructionOpcode::AMOADD_D; - case GenericOpcode::G_ATOMICRMW_AND: - return IsWord ? InstructionOpcode::AMOAND_W : InstructionOpcode::AMOAND_D; - case GenericOpcode::G_ATOMICRMW_OR: - return IsWord ? InstructionOpcode::AMOOR_W : InstructionOpcode::AMOOR_D; - case GenericOpcode::G_ATOMICRMW_XOR: - return IsWord ? InstructionOpcode::AMOXOR_W : InstructionOpcode::AMOXOR_D; - case GenericOpcode::G_ATOMICRMW_MAX: - return IsWord ? InstructionOpcode::AMOMAX_W : InstructionOpcode::AMOMAX_D; - case GenericOpcode::G_ATOMICRMW_MIN: - return IsWord ? InstructionOpcode::AMOMIN_W : InstructionOpcode::AMOMIN_D; - case GenericOpcode::G_ATOMICRMW_UMAX: - return IsWord ? InstructionOpcode::AMOMAXU_W : InstructionOpcode::AMOMAXU_D; - case GenericOpcode::G_ATOMICRMW_UMIN: - return IsWord ? InstructionOpcode::AMOMINU_W : InstructionOpcode::AMOMINU_D; - default: - return InstructionOpcode::Invalid; - } - }; - const InstructionOpcode Selected = SelectOpcode(); - if (Selected == InstructionOpcode::Invalid) - return makeUnexpected(ErrorCode::InternalError, - "RISC-V atomic RMW selection reached an unhandled opcode"); - auto SetValue = Instruction.operandAt(1)->setRegister(SelectedValue); - if (!SetValue) - return std::unexpected(SetValue.error()); - auto SetAddress = Instruction.operandAt(2)->setRegister(*Address); - if (!SetAddress) - return std::unexpected(SetAddress.error()); - return Instruction.setOpcode(instructionOpcode(Selected)); - } - [[nodiscard]] Expected<void> selectFloatingCompare(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target) const { |
