diff options
Diffstat (limited to 'backend/lib/Target')
| -rw-r--r-- | backend/lib/Target/RISCV/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 185 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc | 513 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc (renamed from backend/lib/Target/RISCV/RISCVGISel.rccdesc) | 0 |
4 files changed, 518 insertions, 183 deletions
diff --git a/backend/lib/Target/RISCV/CMakeLists.txt b/backend/lib/Target/RISCV/CMakeLists.txt index bd6bf3d..8c84398 100644 --- a/backend/lib/Target/RISCV/CMakeLists.txt +++ b/backend/lib/Target/RISCV/CMakeLists.txt @@ -14,7 +14,8 @@ set( "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfoC.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfoZb.rccdesc" "${CMAKE_CURRENT_SOURCE_DIR}/RISCVInstrInfoPseudo.rccdesc" - "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISel.rccdesc" + "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelInteger.rccdesc" + "${CMAKE_CURRENT_SOURCE_DIR}/RISCVGISelFloating.rccdesc" ) set(RCCBackendRISCVTableGenArguments) foreach(RCCBackendRISCVDescriptionSource IN LISTS RCCBackendRISCVDescriptionSources) diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 38ef1af..edf0b40 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -117,14 +117,6 @@ memoryAccessBytes(const MachineInstr &Instruction) noexcept { return Instruction.insertOperand(Index, std::move(*Operand)); } -[[nodiscard]] Expected<void> insertVirtualUse(MachineInstr &Instruction, std::size_t Index, - Register Reg) { - auto Operand = MachineOperand::registerOperand(Reg, {RegisterOperandFlag::Use}); - if (!Operand) - return std::unexpected(Operand.error()); - return Instruction.insertOperand(Index, std::move(*Operand)); -} - [[nodiscard]] Expected<std::int64_t> signedImmediate(const MachineOperand &Operand) { if (const std::int64_t *Value = Operand.getIf<std::int64_t>()) return *Value; @@ -234,14 +226,6 @@ public: case GenericOpcode::G_BR: case GenericOpcode::G_BRCOND: return {}; - case GenericOpcode::G_FADD: - case GenericOpcode::G_FSUB: - case GenericOpcode::G_FMUL: - case GenericOpcode::G_FDIV: - case GenericOpcode::G_FMA: - case GenericOpcode::G_FSQRT: - case GenericOpcode::G_FNEG: - case GenericOpcode::G_FABS: case GenericOpcode::G_FCOPYSIGN: if (!Float()) return makeUnexpected(ErrorCode::Unsupported, @@ -269,14 +253,6 @@ public: case GenericOpcode::G_SEXT_INREG: case GenericOpcode::G_ZEXT: case GenericOpcode::G_FCMP: - case GenericOpcode::G_FPEXT: - case GenericOpcode::G_FPTRUNC: - case GenericOpcode::G_FPTOSI: - case GenericOpcode::G_FPTOUI: - case GenericOpcode::G_SITOFP: - case GenericOpcode::G_UITOFP: - case GenericOpcode::G_FMINNUM: - case GenericOpcode::G_FMAXNUM: case GenericOpcode::G_SDIVREM: case GenericOpcode::G_UDIVREM: case GenericOpcode::G_SMULH: @@ -441,30 +417,6 @@ public: case GenericOpcode::G_PTRTOINT: case GenericOpcode::G_INTTOPTR: return Instruction.setOpcode(opcode(GenericOpcode::COPY)); - case GenericOpcode::G_FADD: - return selectRoundingBinary(Instruction, Type, InstructionOpcode::FADD_S, - InstructionOpcode::FADD_D); - case GenericOpcode::G_FSUB: - return selectRoundingBinary(Instruction, Type, InstructionOpcode::FSUB_S, - InstructionOpcode::FSUB_D); - case GenericOpcode::G_FMUL: - return selectRoundingBinary(Instruction, Type, InstructionOpcode::FMUL_S, - InstructionOpcode::FMUL_D); - case GenericOpcode::G_FDIV: - return selectRoundingBinary(Instruction, Type, InstructionOpcode::FDIV_S, - InstructionOpcode::FDIV_D); - case GenericOpcode::G_FMA: - return selectRoundingTernary(Instruction, Type, InstructionOpcode::FMADD_S, - InstructionOpcode::FMADD_D); - case GenericOpcode::G_FSQRT: - return selectRoundingUnary(Instruction, Type, InstructionOpcode::FSQRT_S, - InstructionOpcode::FSQRT_D); - case GenericOpcode::G_FNEG: - return selectSignInjection(Instruction, Type, InstructionOpcode::FSGNJN_S, - InstructionOpcode::FSGNJN_D); - case GenericOpcode::G_FABS: - return selectSignInjection(Instruction, Type, InstructionOpcode::FSGNJX_S, - InstructionOpcode::FSGNJX_D); case GenericOpcode::G_FCOPYSIGN: return selectCopySign(Instruction, Function, Target, Type); case GenericOpcode::G_ANYEXT: @@ -477,25 +429,6 @@ public: return selectSignExtendInRegister(Instruction, Function, Target, Type); case GenericOpcode::G_FCMP: return selectFloatingCompare(Instruction, Function, Target); - case GenericOpcode::G_FPEXT: - return selectRoundingUnary(Instruction, Type, InstructionOpcode::FCVT_D_S, - InstructionOpcode::FCVT_D_S); - case GenericOpcode::G_FPTRUNC: - return selectRoundingUnary(Instruction, Type, InstructionOpcode::FCVT_S_D, - InstructionOpcode::FCVT_S_D); - case GenericOpcode::G_FPTOSI: - case GenericOpcode::G_FPTOUI: - return selectFloatToInteger(Instruction, Function, Type, Generic == GenericOpcode::G_FPTOUI); - case GenericOpcode::G_SITOFP: - case GenericOpcode::G_UITOFP: - return selectIntegerToFloat(Instruction, Function, Target, Type, - Generic == GenericOpcode::G_UITOFP); - case GenericOpcode::G_FMINNUM: - return selectFloatingMinMax(Instruction, Type, InstructionOpcode::FMIN_S, - InstructionOpcode::FMIN_D); - case GenericOpcode::G_FMAXNUM: - return selectFloatingMinMax(Instruction, Type, InstructionOpcode::FMAX_S, - InstructionOpcode::FMAX_D); case GenericOpcode::G_SMULH: return selectMultiplyHigh(Instruction, Function, Target, Type, true); case GenericOpcode::G_UMULH: @@ -746,8 +679,9 @@ private: Register Source, LowLevelType Type, bool Signed) const { if (!isSupportedIntegerType(Type)) - return makeUnexpected(ErrorCode::Unsupported, - "RISC-V integer normalization requires an integer scalar or a 64-bit pointer"); + return makeUnexpected( + ErrorCode::Unsupported, + "RISC-V integer normalization requires an integer scalar or a 64-bit pointer"); const std::uint32_t Bits = Type.scalarBitWidth(); if (Bits == 64) return Source; @@ -1921,73 +1855,6 @@ private: "RISC-V floating comparison predicate is invalid"); } - [[nodiscard]] Expected<void> selectFloatToInteger(MachineInstr &Instruction, - MachineFunction &Function, - std::optional<LowLevelType> Type, - bool Unsigned) const { - const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1); - if (!Type || !Source) - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V floating-to-integer conversion has invalid types"); - auto Rounding = appendImmediate(Instruction, 1); - if (!Rounding) - return std::unexpected(Rounding.error()); - const bool IsWord = Type->scalarBitWidth() <= 32; - if (Source->scalarBitWidth() == 32) { - return Instruction.setOpcode(instructionOpcode( - IsWord ? (Unsigned ? InstructionOpcode::FCVT_WU_S : InstructionOpcode::FCVT_W_S) - : (Unsigned ? InstructionOpcode::FCVT_LU_S : InstructionOpcode::FCVT_L_S))); - } - return Instruction.setOpcode(instructionOpcode( - IsWord ? (Unsigned ? InstructionOpcode::FCVT_WU_D : InstructionOpcode::FCVT_W_D) - : (Unsigned ? InstructionOpcode::FCVT_LU_D : InstructionOpcode::FCVT_L_D))); - } - - [[nodiscard]] Expected<void> selectIntegerToFloat(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target, - std::optional<LowLevelType> Type, - bool Unsigned) const { - const std::optional<LowLevelType> Source = operandType(Function, Instruction, 1); - const MachineOperand *SourceOperand = Instruction.operandAt(1); - const Register *SourceRegister = - SourceOperand == nullptr ? nullptr : SourceOperand->getIf<Register>(); - if (!Type || !Source || SourceRegister == nullptr) - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V integer-to-floating conversion has invalid types"); - auto Normalized = - normalizeIntegerBefore(Instruction, Function, Target, *SourceRegister, *Source, !Unsigned); - if (!Normalized) - return std::unexpected(Normalized.error()); - auto SetSource = Instruction.operandAt(1)->setRegister(*Normalized); - if (!SetSource) - return std::unexpected(SetSource.error()); - auto Rounding = appendImmediate(Instruction, 0); - if (!Rounding) - return std::unexpected(Rounding.error()); - const bool IsWord = Source->scalarBitWidth() <= 32; - if (Type->scalarBitWidth() == 32) { - return Instruction.setOpcode(instructionOpcode( - IsWord ? (Unsigned ? InstructionOpcode::FCVT_S_WU : InstructionOpcode::FCVT_S_W) - : (Unsigned ? InstructionOpcode::FCVT_S_LU : InstructionOpcode::FCVT_S_L))); - } - return Instruction.setOpcode(instructionOpcode( - IsWord ? (Unsigned ? InstructionOpcode::FCVT_D_WU : InstructionOpcode::FCVT_D_W) - : (Unsigned ? InstructionOpcode::FCVT_D_LU : InstructionOpcode::FCVT_D_L))); - } - - [[nodiscard]] Expected<void> selectFloatingMinMax(MachineInstr &Instruction, - std::optional<LowLevelType> Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 32) - return Instruction.setOpcode(instructionOpcode(Single)); - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 64) - return Instruction.setOpcode(instructionOpcode(Double)); - return makeUnexpected(ErrorCode::Unsupported, - "RISC-V cannot select this floating min/max type"); - } - [[nodiscard]] Expected<void> selectCopySign(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, std::optional<LowLevelType> Type) const { @@ -2648,52 +2515,6 @@ private: return {}; } - [[nodiscard]] Expected<void> selectRoundingBinary(MachineInstr &Instruction, - std::optional<LowLevelType> Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - auto RoundingMode = appendImmediate(Instruction, 0); - if (!RoundingMode) - return std::unexpected(RoundingMode.error()); - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 32) - return Instruction.setOpcode(instructionOpcode(Single)); - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 64) - return Instruction.setOpcode(instructionOpcode(Double)); - return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this floating binary type"); - } - - [[nodiscard]] Expected<void> selectRoundingTernary(MachineInstr &Instruction, - std::optional<LowLevelType> Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - return selectRoundingBinary(Instruction, Type, Single, Double); - } - - [[nodiscard]] Expected<void> selectRoundingUnary(MachineInstr &Instruction, - std::optional<LowLevelType> Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - return selectRoundingBinary(Instruction, Type, Single, Double); - } - - [[nodiscard]] Expected<void> selectSignInjection(MachineInstr &Instruction, - std::optional<LowLevelType> Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - const MachineOperand *Source = Instruction.operandAt(1); - const Register *SourceReg = Source == nullptr ? nullptr : Source->getIf<Register>(); - if (SourceReg == nullptr) - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V floating sign operation requires a register source"); - auto Duplicate = insertVirtualUse(Instruction, 2, *SourceReg); - if (!Duplicate) - return std::unexpected(Duplicate.error()); - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 32) - return Instruction.setOpcode(instructionOpcode(Single)); - if (Type && Type->isCategoryNeutralScalar() && Type->scalarBitWidth() == 64) - return Instruction.setOpcode(instructionOpcode(Double)); - return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this floating unary type"); - } const RISCVSubtarget &Subtarget; const RISCVRegisterBankInfo &RegisterBanks; }; diff --git a/backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc b/backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc new file mode 100644 index 0000000..ff8c613 --- /dev/null +++ b/backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc @@ -0,0 +1,513 @@ +selection_rules: + - + id: select_g_fadd_s32 + priority: 100 + match: + opcode: G_FADD + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FADD_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fadd_s64 + priority: 100 + match: + opcode: G_FADD + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FADD_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fsub_s32 + priority: 100 + match: + opcode: G_FSUB + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FSUB_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fsub_s64 + priority: 100 + match: + opcode: G_FSUB + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FSUB_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fmul_s32 + priority: 100 + match: + opcode: G_FMUL + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMUL_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fmul_s64 + priority: 100 + match: + opcode: G_FMUL + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMUL_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fdiv_s32 + priority: 100 + match: + opcode: G_FDIV + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FDIV_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fdiv_s64 + priority: 100 + match: + opcode: G_FDIV + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FDIV_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { immediate: 7 }] + - + id: select_g_fma_s32 + priority: 100 + match: + opcode: G_FMA + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + - { index: 3, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + - { index: 3, bank: FPR } + apply: + instructions: + - opcode: FMADD_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { operand: 3 }, { immediate: 7 }] + - + id: select_g_fma_s64 + priority: 100 + match: + opcode: G_FMA + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + - { index: 3, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + - { index: 3, bank: FPR } + apply: + instructions: + - opcode: FMADD_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }, { operand: 3 }, { immediate: 7 }] + - + id: select_g_fsqrt_s32 + priority: 100 + match: + opcode: G_FSQRT + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSQRT_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_fsqrt_s64 + priority: 100 + match: + opcode: G_FSQRT + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSQRT_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_fneg_s32 + priority: 100 + match: + opcode: G_FNEG + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSGNJN_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 1 }] + - + id: select_g_fneg_s64 + priority: 100 + match: + opcode: G_FNEG + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSGNJN_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 1 }] + - + id: select_g_fabs_s32 + priority: 100 + match: + opcode: G_FABS + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSGNJX_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 1 }] + - + id: select_g_fabs_s64 + priority: 100 + match: + opcode: G_FABS + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FSGNJX_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 1 }] + - + id: select_g_fminnum_s32 + priority: 100 + match: + opcode: G_FMINNUM + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMIN_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fminnum_s64 + priority: 100 + match: + opcode: G_FMINNUM + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMIN_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fmaxnum_s32 + priority: 100 + match: + opcode: G_FMAXNUM + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + - { index: 2, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMAX_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fmaxnum_s64 + priority: 100 + match: + opcode: G_FMAXNUM + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + - { index: 2, bank: FPR } + apply: + instructions: + - opcode: FMAX_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fpext_s32_to_s64 + priority: 100 + match: + opcode: G_FPEXT + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_D_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 0 }] + - + id: select_g_fptrunc_s64_to_s32 + priority: 100 + match: + opcode: G_FPTRUNC + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_S_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_fptosi_s32 + priority: 100 + match: + opcode: G_FPTOSI + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_L_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 1 }] + - + id: select_g_fptosi_s64 + priority: 100 + match: + opcode: G_FPTOSI + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_L_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 1 }] + - + id: select_g_fptoui_s32 + priority: 100 + match: + opcode: G_FPTOUI + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 32 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_LU_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 1 }] + - + id: select_g_fptoui_s64 + priority: 100 + match: + opcode: G_FPTOUI + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: FPR } + apply: + instructions: + - opcode: FCVT_LU_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 1 }] + - + id: select_g_sitofp_s32 + priority: 100 + match: + opcode: G_SITOFP + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: FCVT_S_L + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_sitofp_s64 + priority: 100 + match: + opcode: G_SITOFP + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: FCVT_D_L + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_uitofp_s32 + priority: 100 + match: + opcode: G_UITOFP + result_type: { kind: scalar, bits: 32 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: FCVT_S_LU + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] + - + id: select_g_uitofp_s64 + priority: 100 + match: + opcode: G_UITOFP + result_type: { kind: scalar, bits: 64 } + operand_types: + - { index: 1, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: FPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: FCVT_D_LU + root: true + operands: [{ operand: 0 }, { operand: 1 }, { immediate: 7 }] diff --git a/backend/lib/Target/RISCV/RISCVGISel.rccdesc b/backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc index d8b0a42..d8b0a42 100644 --- a/backend/lib/Target/RISCV/RISCVGISel.rccdesc +++ b/backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc |
