aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-16 18:00:32 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-16 18:00:32 +0800
commit6c7422accb0964d37bb826e3fb798f2d86ca3b42 (patch)
tree357a80d93c943b2c9bc8dc20e522650afaa45c61 /backend/lib
parent864a29abbdce86353ec91c3587757711d3a42f10 (diff)
downloadrcc-project-6c7422accb0964d37bb826e3fb798f2d86ca3b42.tar.gz
rcc-project-6c7422accb0964d37bb826e3fb798f2d86ca3b42.tar.xz
[RISCV][GlobalISel] Generate floating-point selections
Diffstat (limited to 'backend/lib')
-rw-r--r--backend/lib/Target/RISCV/CMakeLists.txt3
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp185
-rw-r--r--backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc513
-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