aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 02:50:30 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-19 02:50:30 +0800
commit6c97d54954112be9a5badacaec8efa1d05bd7d15 (patch)
tree9eb4d5db7f05218759e6f6d49cf90ca65f1e53f8 /backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
parentf5c592905e6e1ef4b78337d76c8215e543607b8d (diff)
downloadrcc-project-6c97d54954112be9a5badacaec8efa1d05bd7d15.tar.gz
rcc-project-6c97d54954112be9a5badacaec8efa1d05bd7d15.tar.xz
[RISCV][GlobalISel] Generate indirect branch selection
Diffstat (limited to 'backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp')
-rw-r--r--backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
index b9cdb48..df3e5ad 100644
--- a/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
+++ b/backend/lib/Target/RISCV/RISCVPseudoExpansion.cpp
@@ -544,6 +544,51 @@ copyRegisters(const MachineInstr &Instruction) {
return true;
}
+[[nodiscard]] Expected<bool> expandIndirectBranch(MachineInstr &Instruction,
+ MachineFunction &Function,
+ const TargetDescription &Target) {
+ const MachineOperand *Address = Instruction.operandAt(0);
+ const MachineOperand *Offset = Instruction.operandAt(1);
+ if (Address == nullptr || Address->getIf<Register>() == nullptr || Offset == nullptr ||
+ Offset->getIf<std::int64_t>() == nullptr) {
+ return makeUnexpected(ErrorCode::VerificationError,
+ "RISC-V PseudoBRIND has malformed operands");
+ }
+
+ auto Zero = physicalRegister(PhysicalRegisterID::X0);
+ if (!Zero)
+ return std::unexpected(Zero.error());
+ MachineIRBuilder Builder(Function, Target);
+ auto Point = Builder.setInsertPointBefore(Instruction);
+ if (!Point)
+ return std::unexpected(Point.error());
+ auto Pending = Builder.buildInstr(instructionOpcode(InstructionOpcode::JALR));
+ if (!Pending)
+ return std::unexpected(Pending.error());
+ auto Added = Pending->addDef(Register::fromPhysical(*Zero));
+ if (!Added)
+ return std::unexpected(Added.error());
+ Added = Pending->addOperand(Address->cloneDetached());
+ if (!Added)
+ return std::unexpected(Added.error());
+ Added = Pending->addOperand(Offset->cloneDetached());
+ if (!Added)
+ return std::unexpected(Added.error());
+ auto Implicit = copyExtraImplicitOperands(Instruction, 2, *Pending, std::nullopt, std::nullopt);
+ if (!Implicit)
+ return std::unexpected(Implicit.error());
+ auto Replacement = Pending->build();
+ if (!Replacement)
+ return std::unexpected(Replacement.error());
+ auto Decoration = copyCommonDecoration(Instruction, **Replacement, true, true, true);
+ if (!Decoration)
+ return std::unexpected(Decoration.error());
+ auto Removed = removeOldInstruction(Instruction);
+ if (!Removed)
+ return std::unexpected(Removed.error());
+ return true;
+}
+
class RISCVPseudoExpansionInfo final : public TargetPseudoExpansionInfo {
public:
[[nodiscard]] Expected<bool> preparePostRAPseudo(MachineInstr &Instruction,
@@ -571,6 +616,8 @@ public:
return expandReturn(Instruction, Function, Target);
if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBR))
return expandBranch(Instruction, Function, Target);
+ if (Instruction.opcode() == instructionOpcode(InstructionOpcode::PseudoBRIND))
+ return expandIndirectBranch(Instruction, Function, Target);
if (Instruction.opcode() == instructionOpcode(InstructionOpcode::ReadFFLAGS))
return expandFFLAGSAccess(Instruction, Function, Target, true);
if (Instruction.opcode() == instructionOpcode(InstructionOpcode::WriteFFLAGS))