diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 03:43:19 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-19 03:43:19 +0800 |
| commit | 6a91664223881226e2b6186561c05ff378a19355 (patch) | |
| tree | 4798334e0a34158368c7310dd2fde89462c83502 /backend/lib/Target/RISCV | |
| parent | 219b315373ef34ca20cc78b89bf3c3d19442ffbd (diff) | |
| download | rcc-project-6a91664223881226e2b6186561c05ff378a19355.tar.gz rcc-project-6a91664223881226e2b6186561c05ff378a19355.tar.xz | |
[RISCV][GlobalISel] Generate integer store selection
Diffstat (limited to 'backend/lib/Target/RISCV')
| -rw-r--r-- | backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp | 80 | ||||
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVGISelAddressing.rccdesc | 76 |
2 files changed, 76 insertions, 80 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 18b986d..a4a2113 100644 --- a/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/backend/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -12,7 +12,6 @@ #include "rcc/CodeGen/MachineFunction.h" #include "rcc/CodeGen/MachineIRBuilder.h" #include "rcc/CodeGen/MachineInstr.h" -#include "rcc/CodeGen/MachineMemOperand.h" #include "rcc/CodeGen/MachineOperand.h" #include "rcc/CodeGen/MachineRegisterInfo.h" #include "rcc/CodeGen/TargetDescription.h" @@ -146,31 +145,6 @@ operandType(const MachineFunction &Function, const MachineInstr &Instruction, st return RegisterBankID::fromValue(static_cast<std::uint32_t>(RegisterBank::FPR)); } -[[nodiscard]] Expected<RegisterBankID> registerBank(const MachineFunction &Function, Register Reg) { - if (!Reg.isVirtual()) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V generic instruction requires a virtual register"); - } - auto Info = Function.registerInfo().virtualRegisterInfo(Reg); - if (!Info) - return std::unexpected(Info.error()); - if (!Info->get().Bank) { - return makeUnexpected(ErrorCode::VerificationError, - "RISC-V instruction selection requires an assigned register bank"); - } - return *Info->get().Bank; -} - -[[nodiscard]] std::optional<std::uint64_t> -memoryAccessBytes(const MachineInstr &Instruction) noexcept { - if (Instruction.memOperands().size() != 1) - return std::nullopt; - const MachineMemOperandDesc &Description = Instruction.memOperands().front()->description(); - if (!Description.Size.isKnown() || Description.Size.isScalable()) - return std::nullopt; - return Description.Size.minimumBytes(); -} - [[nodiscard]] Expected<void> appendImmediate(MachineInstr &Instruction, std::int64_t Value) { return Instruction.addOperand(MachineOperand::immediate(Value)); } @@ -617,7 +591,6 @@ public: return {}; case GenericOpcode::G_FPEXTLOAD: case GenericOpcode::G_FPTRUNCSTORE: - case GenericOpcode::G_STORE: return {}; case GenericOpcode::G_FCONSTANT: { const MachineOperand *Immediate = Instruction.operandAt(1); @@ -680,8 +653,6 @@ public: switch (Generic) { case GenericOpcode::G_FPEXTLOAD: return selectFloatExtLoad(Instruction, Function, Target); - case GenericOpcode::G_STORE: - return selectStore(Instruction, Function); case GenericOpcode::G_FPTRUNCSTORE: return selectFloatTruncStore(Instruction, Function, Target); case GenericOpcode::G_CONSTANT: @@ -1349,57 +1320,6 @@ private: return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSW)); } - [[nodiscard]] Expected<void> selectStore(MachineInstr &Instruction, - MachineFunction &Function) const { - const MachineOperand *Value = Instruction.operandAt(0); - const std::optional<LowLevelType> Type = - Value == nullptr ? std::nullopt : registerType(Function, *Value); - if (!Type) - return makeUnexpected(ErrorCode::VerificationError, - "store value has no virtual-register type"); - const auto Bytes = memoryAccessBytes(Instruction); - if (!Bytes) - return makeUnexpected(ErrorCode::Unsupported, - "RISC-V store size does not match its value type"); - const Register *ValueRegister = Value->getIf<Register>(); - if (ValueRegister == nullptr) - return makeUnexpected(ErrorCode::VerificationError, "RISC-V store has no value register"); - auto Bank = registerBank(Function, *ValueRegister); - if (!Bank) - return std::unexpected(Bank.error()); - if (Instruction.memOperands().front()->isAtomic()) { - if (*Bank == fprBank() || !isSupportedIntegerType(*Type) || (*Bytes != 4 && *Bytes != 8)) - return makeUnexpected(ErrorCode::Unsupported, - "RISC-V atomic store requires a 32-bit or 64-bit GPR value"); - auto Zero = physicalRegister(PhysicalRegisterID::X0); - if (!Zero) - return std::unexpected(Zero.error()); - auto Destination = insertPhysicalRegister(Instruction, 0, *Zero, RegisterOperandFlag::Define); - if (!Destination) - return std::unexpected(Destination.error()); - return Instruction.setOpcode(instructionOpcode(*Bytes == 4 ? InstructionOpcode::AMOSWAP_W - : InstructionOpcode::AMOSWAP_D)); - } - auto AppendOffset = appendImmediate(Instruction, 0); - if (!AppendOffset) - return std::unexpected(AppendOffset.error()); - if (*Bank != fprBank() && isSupportedIntegerType(*Type)) { - const InstructionOpcode Selected = *Bytes == 1 ? InstructionOpcode::SB - : *Bytes == 2 ? InstructionOpcode::SH - : *Bytes == 4 ? InstructionOpcode::SW - : *Bytes == 8 ? InstructionOpcode::SD - : InstructionOpcode::Invalid; - if (Selected == InstructionOpcode::Invalid) - return makeUnexpected(ErrorCode::Unsupported, "RISC-V integer store width is unsupported"); - return Instruction.setOpcode(instructionOpcode(Selected)); - } - if (*Bank == fprBank() && Type->scalarBitWidth() == 32 && *Bytes == 4) - return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSW)); - if (*Bank == fprBank() && Type->scalarBitWidth() == 64 && *Bytes == 8) - return Instruction.setOpcode(instructionOpcode(InstructionOpcode::FSD)); - return makeUnexpected(ErrorCode::Unsupported, "RISC-V cannot select this generic store type"); - } - [[nodiscard]] Expected<void> selectIntegerConstant(MachineInstr &Instruction, MachineFunction &Function, const TargetDescription &Target, diff --git a/backend/lib/Target/RISCV/RISCVGISelAddressing.rccdesc b/backend/lib/Target/RISCV/RISCVGISelAddressing.rccdesc index 1ff9593..1a1dd4d 100644 --- a/backend/lib/Target/RISCV/RISCVGISelAddressing.rccdesc +++ b/backend/lib/Target/RISCV/RISCVGISelAddressing.rccdesc @@ -192,6 +192,82 @@ selection_rules: - { complex: addr_reg_imm_base, operand: 1 } - { complex: addr_reg_imm_offset, operand: 1 } - + id: select_g_store_m8 + priority: 300 + match: + opcode: G_STORE + memory: { index: 0, bytes: 1 } + operand_types: + - { index: 1, kind: pointer, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: SB + root: true + operands: + - { operand: 0 } + - { complex: addr_reg_imm_base, operand: 1 } + - { complex: addr_reg_imm_offset, operand: 1 } + - + id: select_g_store_m16 + priority: 300 + match: + opcode: G_STORE + memory: { index: 0, bytes: 2 } + operand_types: + - { index: 1, kind: pointer, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: SH + root: true + operands: + - { operand: 0 } + - { complex: addr_reg_imm_base, operand: 1 } + - { complex: addr_reg_imm_offset, operand: 1 } + - + id: select_g_store_m32 + priority: 300 + match: + opcode: G_STORE + memory: { index: 0, bytes: 4 } + operand_types: + - { index: 1, kind: pointer, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: SW + root: true + operands: + - { operand: 0 } + - { complex: addr_reg_imm_base, operand: 1 } + - { complex: addr_reg_imm_offset, operand: 1 } + - + id: select_g_store_m64 + priority: 300 + match: + opcode: G_STORE + memory: { index: 0, bytes: 8 } + operand_types: + - { index: 1, kind: pointer, bits: 64 } + operand_banks: + - { index: 0, bank: GPR } + - { index: 1, bank: GPR } + apply: + instructions: + - opcode: SD + root: true + operands: + - { operand: 0 } + - { complex: addr_reg_imm_base, operand: 1 } + - { complex: addr_reg_imm_offset, operand: 1 } + - id: select_g_frame_index priority: 100 match: |
