From 6c7422accb0964d37bb826e3fb798f2d86ca3b42 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sun, 16 Aug 2026 18:00:32 +0800 Subject: [RISCV][GlobalISel] Generate floating-point selections --- backend/lib/Target/RISCV/CMakeLists.txt | 3 +- .../RISCV/GISel/RISCVInstructionSelector.cpp | 185 +---- backend/lib/Target/RISCV/RISCVGISel.rccdesc | 792 --------------------- .../lib/Target/RISCV/RISCVGISelFloating.rccdesc | 513 +++++++++++++ backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc | 792 +++++++++++++++++++++ 5 files changed, 1310 insertions(+), 975 deletions(-) delete mode 100644 backend/lib/Target/RISCV/RISCVGISel.rccdesc create mode 100644 backend/lib/Target/RISCV/RISCVGISelFloating.rccdesc create mode 100644 backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc (limited to 'backend/lib') 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 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 signedImmediate(const MachineOperand &Operand) { if (const std::int64_t *Value = Operand.getIf()) 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 selectFloatToInteger(MachineInstr &Instruction, - MachineFunction &Function, - std::optional Type, - bool Unsigned) const { - const std::optional 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 selectIntegerToFloat(MachineInstr &Instruction, - MachineFunction &Function, - const TargetDescription &Target, - std::optional Type, - bool Unsigned) const { - const std::optional Source = operandType(Function, Instruction, 1); - const MachineOperand *SourceOperand = Instruction.operandAt(1); - const Register *SourceRegister = - SourceOperand == nullptr ? nullptr : SourceOperand->getIf(); - 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 selectFloatingMinMax(MachineInstr &Instruction, - std::optional 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 selectCopySign(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, std::optional Type) const { @@ -2648,52 +2515,6 @@ private: return {}; } - [[nodiscard]] Expected selectRoundingBinary(MachineInstr &Instruction, - std::optional 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 selectRoundingTernary(MachineInstr &Instruction, - std::optional Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - return selectRoundingBinary(Instruction, Type, Single, Double); - } - - [[nodiscard]] Expected selectRoundingUnary(MachineInstr &Instruction, - std::optional Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - return selectRoundingBinary(Instruction, Type, Single, Double); - } - - [[nodiscard]] Expected selectSignInjection(MachineInstr &Instruction, - std::optional Type, - InstructionOpcode Single, - InstructionOpcode Double) const { - const MachineOperand *Source = Instruction.operandAt(1); - const Register *SourceReg = Source == nullptr ? nullptr : Source->getIf(); - 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/RISCVGISel.rccdesc b/backend/lib/Target/RISCV/RISCVGISel.rccdesc deleted file mode 100644 index d8b0a42..0000000 --- a/backend/lib/Target/RISCV/RISCVGISel.rccdesc +++ /dev/null @@ -1,792 +0,0 @@ -selection_rules: - - - id: select_g_sllw - priority: 100 - match: - opcode: G_SLLW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: SLLW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_sraw - priority: 100 - match: - opcode: G_SRAW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: SRAW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_srlw - priority: 100 - match: - opcode: G_SRLW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: SRLW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_divw - priority: 100 - match: - opcode: G_DIVW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: DIVW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_divuw - priority: 100 - match: - opcode: G_DIVUW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: DIVUW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_remuw - priority: 100 - match: - opcode: G_REMUW - 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: GPR } - - { index: 1, bank: GPR } - - { index: 2, bank: GPR } - apply: - instructions: - - opcode: REMUW - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_fcvt_w_rv64_s32 - priority: 100 - match: - opcode: G_FCVT_W_RV64 - 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_W_S - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_fcvt_w_rv64_s64 - priority: 100 - match: - opcode: G_FCVT_W_RV64 - 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_W_D - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_fcvt_wu_rv64_s32 - priority: 100 - match: - opcode: G_FCVT_WU_RV64 - 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_WU_S - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_fcvt_wu_rv64_s64 - priority: 100 - match: - opcode: G_FCVT_WU_RV64 - 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_WU_D - root: true - operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] - - - id: select_g_fclass_s32 - priority: 100 - match: - opcode: G_FCLASS - 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: FCLASS_S - root: true - operands: [{ operand: 0 }, { operand: 1 }] - - - id: select_g_fclass_s64 - priority: 100 - match: - opcode: G_FCLASS - 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: FCLASS_D - root: true - operands: [{ operand: 0 }, { operand: 1 }] - - - id: select_g_icmp_eq_zero - priority: 500 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: eq } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: 0, max: 0 }] - apply: - instructions: - - opcode: SLTIU - root: true - operands: [{ operand: 0 }, { operand: 2 }, { immediate: 1 }] - erase_operand_definitions: [3] - - - id: select_g_icmp_ne_zero - priority: 500 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ne } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: 0, max: 0 }] - apply: - instructions: - - opcode: SLTU - root: true - operands: - - { operand: 0 } - - { physical_register: X0, flags: [use] } - - { operand: 2 } - erase_operand_definitions: [3] - - - id: select_g_icmp_ult_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ult } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2048, max: 2047 }] - apply: - instructions: - - opcode: SLTIU - root: true - operands: - - { operand: 0 } - - { operand: 2 } - - { captured_immediate: 3 } - erase_operand_definitions: [3] - - - id: select_g_icmp_slt_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: slt } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2048, max: 2047 }] - apply: - instructions: - - opcode: SLTI - root: true - operands: - - { operand: 0 } - - { operand: 2 } - - { captured_immediate: 3 } - erase_operand_definitions: [3] - - - id: select_g_icmp_ugt_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ugt } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: - - { min: -2049, max: -2 } - - { min: 1, max: 2046 } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTIU - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3, transform: plus_one } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - erase_operand_definitions: [3] - - - id: select_g_icmp_sgt_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sgt } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: - - { min: -2049, max: -1 } - - { min: 1, max: 2046 } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTI - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3, transform: plus_one } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - erase_operand_definitions: [3] - - - id: select_g_icmp_eq_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: eq } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2047, max: 2048 }] - apply: - temporaries: - - { id: difference, type_from_operand: 2 } - instructions: - - opcode: ADDI - root: true - operands: - - { temporary: difference, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3, transform: negate } - - opcode: SLTIU - root: false - operands: - - { operand: 0 } - - { temporary: difference, flags: [use] } - - { immediate: 1 } - erase_operand_definitions: [3] - - - id: select_g_icmp_ne_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ne } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2047, max: 2048 }] - apply: - temporaries: - - { id: difference, type_from_operand: 2 } - instructions: - - opcode: ADDI - root: true - operands: - - { temporary: difference, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3, transform: negate } - - opcode: SLTU - root: false - operands: - - { operand: 0 } - - { physical_register: X0, flags: [use] } - - { temporary: difference, flags: [use] } - erase_operand_definitions: [3] - - - id: select_g_icmp_ule_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ule } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: - - { min: -2049, max: -2 } - - { min: 1, max: 2046 } - apply: - instructions: - - opcode: SLTIU - root: true - operands: - - { operand: 0 } - - { operand: 2 } - - { captured_immediate: 3, transform: plus_one } - erase_operand_definitions: [3] - - - id: select_g_icmp_sle_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sle } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: - - { min: -2049, max: -1 } - - { min: 1, max: 2046 } - apply: - instructions: - - opcode: SLTI - root: true - operands: - - { operand: 0 } - - { operand: 2 } - - { captured_immediate: 3, transform: plus_one } - erase_operand_definitions: [3] - - - id: select_g_icmp_uge_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: uge } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2048, max: 2047 }] - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTIU - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - erase_operand_definitions: [3] - - - id: select_g_icmp_sge_immediate - priority: 400 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sge } - operand_types: - - { index: 2, kind: scalar, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - operand_def_constants: - - index: 3 - ranges: [{ min: -2048, max: 2047 }] - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTI - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { captured_immediate: 3 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - erase_operand_definitions: [3] - - - id: select_g_icmp_ult_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ult } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - instructions: - - opcode: SLTU - root: true - operands: [{ operand: 0 }, { operand: 2 }, { operand: 3 }] - - - id: select_g_icmp_slt_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: slt } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - instructions: - - opcode: SLT - root: true - operands: [{ operand: 0 }, { operand: 2 }, { operand: 3 }] - - - id: select_g_icmp_ugt_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ugt } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - instructions: - - opcode: SLTU - root: true - operands: [{ operand: 0 }, { operand: 3 }, { operand: 2 }] - - - id: select_g_icmp_sgt_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sgt } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - instructions: - - opcode: SLT - root: true - operands: [{ operand: 0 }, { operand: 3 }, { operand: 2 }] - - - id: select_g_icmp_eq_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: eq } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: difference, type_from_operand: 2 } - instructions: - - opcode: XOR - root: true - operands: - - { temporary: difference, flags: [define] } - - { operand: 2 } - - { operand: 3 } - - opcode: SLTIU - root: false - operands: - - { operand: 0 } - - { temporary: difference, flags: [use] } - - { immediate: 1 } - - - id: select_g_icmp_ne_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ne } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: difference, type_from_operand: 2 } - instructions: - - opcode: XOR - root: true - operands: - - { temporary: difference, flags: [define] } - - { operand: 2 } - - { operand: 3 } - - opcode: SLTU - root: false - operands: - - { operand: 0 } - - { physical_register: X0, flags: [use] } - - { temporary: difference, flags: [use] } - - - id: select_g_icmp_ule_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: ule } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTU - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 3 } - - { operand: 2 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - - - id: select_g_icmp_sle_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sle } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLT - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 3 } - - { operand: 2 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - - - id: select_g_icmp_uge_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: uge } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLTU - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { operand: 3 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } - - - id: select_g_icmp_sge_register - priority: 100 - match: - opcode: G_ICMP - result_type: { kind: scalar, bits: 64 } - integer_predicate: { index: 1, value: sge } - operand_types: - - { index: 2, kind: any, bits: 64 } - operand_banks: - - { index: 0, bank: GPR } - - { index: 2, bank: GPR } - - { index: 3, bank: GPR } - apply: - temporaries: - - { id: compare, type_from_operand: 2 } - instructions: - - opcode: SLT - root: true - operands: - - { temporary: compare, flags: [define] } - - { operand: 2 } - - { operand: 3 } - - opcode: XORI - root: false - operands: - - { operand: 0 } - - { temporary: compare, flags: [use] } - - { immediate: 1 } 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/RISCVGISelInteger.rccdesc b/backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc new file mode 100644 index 0000000..d8b0a42 --- /dev/null +++ b/backend/lib/Target/RISCV/RISCVGISelInteger.rccdesc @@ -0,0 +1,792 @@ +selection_rules: + - + id: select_g_sllw + priority: 100 + match: + opcode: G_SLLW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: SLLW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_sraw + priority: 100 + match: + opcode: G_SRAW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: SRAW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_srlw + priority: 100 + match: + opcode: G_SRLW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: SRLW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_divw + priority: 100 + match: + opcode: G_DIVW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: DIVW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_divuw + priority: 100 + match: + opcode: G_DIVUW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: DIVUW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_remuw + priority: 100 + match: + opcode: G_REMUW + 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: GPR } + - { index: 1, bank: GPR } + - { index: 2, bank: GPR } + apply: + instructions: + - opcode: REMUW + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fcvt_w_rv64_s32 + priority: 100 + match: + opcode: G_FCVT_W_RV64 + 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_W_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fcvt_w_rv64_s64 + priority: 100 + match: + opcode: G_FCVT_W_RV64 + 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_W_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fcvt_wu_rv64_s32 + priority: 100 + match: + opcode: G_FCVT_WU_RV64 + 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_WU_S + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fcvt_wu_rv64_s64 + priority: 100 + match: + opcode: G_FCVT_WU_RV64 + 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_WU_D + root: true + operands: [{ operand: 0 }, { operand: 1 }, { operand: 2 }] + - + id: select_g_fclass_s32 + priority: 100 + match: + opcode: G_FCLASS + 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: FCLASS_S + root: true + operands: [{ operand: 0 }, { operand: 1 }] + - + id: select_g_fclass_s64 + priority: 100 + match: + opcode: G_FCLASS + 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: FCLASS_D + root: true + operands: [{ operand: 0 }, { operand: 1 }] + - + id: select_g_icmp_eq_zero + priority: 500 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: eq } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: 0, max: 0 }] + apply: + instructions: + - opcode: SLTIU + root: true + operands: [{ operand: 0 }, { operand: 2 }, { immediate: 1 }] + erase_operand_definitions: [3] + - + id: select_g_icmp_ne_zero + priority: 500 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ne } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: 0, max: 0 }] + apply: + instructions: + - opcode: SLTU + root: true + operands: + - { operand: 0 } + - { physical_register: X0, flags: [use] } + - { operand: 2 } + erase_operand_definitions: [3] + - + id: select_g_icmp_ult_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ult } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2048, max: 2047 }] + apply: + instructions: + - opcode: SLTIU + root: true + operands: + - { operand: 0 } + - { operand: 2 } + - { captured_immediate: 3 } + erase_operand_definitions: [3] + - + id: select_g_icmp_slt_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: slt } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2048, max: 2047 }] + apply: + instructions: + - opcode: SLTI + root: true + operands: + - { operand: 0 } + - { operand: 2 } + - { captured_immediate: 3 } + erase_operand_definitions: [3] + - + id: select_g_icmp_ugt_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ugt } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: + - { min: -2049, max: -2 } + - { min: 1, max: 2046 } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTIU + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3, transform: plus_one } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + erase_operand_definitions: [3] + - + id: select_g_icmp_sgt_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sgt } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: + - { min: -2049, max: -1 } + - { min: 1, max: 2046 } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTI + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3, transform: plus_one } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + erase_operand_definitions: [3] + - + id: select_g_icmp_eq_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: eq } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2047, max: 2048 }] + apply: + temporaries: + - { id: difference, type_from_operand: 2 } + instructions: + - opcode: ADDI + root: true + operands: + - { temporary: difference, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3, transform: negate } + - opcode: SLTIU + root: false + operands: + - { operand: 0 } + - { temporary: difference, flags: [use] } + - { immediate: 1 } + erase_operand_definitions: [3] + - + id: select_g_icmp_ne_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ne } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2047, max: 2048 }] + apply: + temporaries: + - { id: difference, type_from_operand: 2 } + instructions: + - opcode: ADDI + root: true + operands: + - { temporary: difference, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3, transform: negate } + - opcode: SLTU + root: false + operands: + - { operand: 0 } + - { physical_register: X0, flags: [use] } + - { temporary: difference, flags: [use] } + erase_operand_definitions: [3] + - + id: select_g_icmp_ule_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ule } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: + - { min: -2049, max: -2 } + - { min: 1, max: 2046 } + apply: + instructions: + - opcode: SLTIU + root: true + operands: + - { operand: 0 } + - { operand: 2 } + - { captured_immediate: 3, transform: plus_one } + erase_operand_definitions: [3] + - + id: select_g_icmp_sle_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sle } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: + - { min: -2049, max: -1 } + - { min: 1, max: 2046 } + apply: + instructions: + - opcode: SLTI + root: true + operands: + - { operand: 0 } + - { operand: 2 } + - { captured_immediate: 3, transform: plus_one } + erase_operand_definitions: [3] + - + id: select_g_icmp_uge_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: uge } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2048, max: 2047 }] + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTIU + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + erase_operand_definitions: [3] + - + id: select_g_icmp_sge_immediate + priority: 400 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sge } + operand_types: + - { index: 2, kind: scalar, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + operand_def_constants: + - index: 3 + ranges: [{ min: -2048, max: 2047 }] + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTI + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { captured_immediate: 3 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + erase_operand_definitions: [3] + - + id: select_g_icmp_ult_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ult } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + instructions: + - opcode: SLTU + root: true + operands: [{ operand: 0 }, { operand: 2 }, { operand: 3 }] + - + id: select_g_icmp_slt_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: slt } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + instructions: + - opcode: SLT + root: true + operands: [{ operand: 0 }, { operand: 2 }, { operand: 3 }] + - + id: select_g_icmp_ugt_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ugt } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + instructions: + - opcode: SLTU + root: true + operands: [{ operand: 0 }, { operand: 3 }, { operand: 2 }] + - + id: select_g_icmp_sgt_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sgt } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + instructions: + - opcode: SLT + root: true + operands: [{ operand: 0 }, { operand: 3 }, { operand: 2 }] + - + id: select_g_icmp_eq_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: eq } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: difference, type_from_operand: 2 } + instructions: + - opcode: XOR + root: true + operands: + - { temporary: difference, flags: [define] } + - { operand: 2 } + - { operand: 3 } + - opcode: SLTIU + root: false + operands: + - { operand: 0 } + - { temporary: difference, flags: [use] } + - { immediate: 1 } + - + id: select_g_icmp_ne_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ne } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: difference, type_from_operand: 2 } + instructions: + - opcode: XOR + root: true + operands: + - { temporary: difference, flags: [define] } + - { operand: 2 } + - { operand: 3 } + - opcode: SLTU + root: false + operands: + - { operand: 0 } + - { physical_register: X0, flags: [use] } + - { temporary: difference, flags: [use] } + - + id: select_g_icmp_ule_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: ule } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTU + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 3 } + - { operand: 2 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + - + id: select_g_icmp_sle_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sle } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLT + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 3 } + - { operand: 2 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + - + id: select_g_icmp_uge_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: uge } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLTU + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { operand: 3 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } + - + id: select_g_icmp_sge_register + priority: 100 + match: + opcode: G_ICMP + result_type: { kind: scalar, bits: 64 } + integer_predicate: { index: 1, value: sge } + operand_types: + - { index: 2, kind: any, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 2, bank: GPR } + - { index: 3, bank: GPR } + apply: + temporaries: + - { id: compare, type_from_operand: 2 } + instructions: + - opcode: SLT + root: true + operands: + - { temporary: compare, flags: [define] } + - { operand: 2 } + - { operand: 3 } + - opcode: XORI + root: false + operands: + - { operand: 0 } + - { temporary: compare, flags: [use] } + - { immediate: 1 } -- cgit v1.2.3