diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index e355b208a75..b1539461f00 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "RISCV.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "RISCV.h" #include "RISCVTargetMachine.h" +#include "Utils/RISCVMatInt.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Support/Debug.h" @@ -63,6 +64,27 @@ void RISCVDAGToDAGISel::PostprocessISelDAG() { doPeepholeLoadStoreADDI(); } +static SDNode *selectImm(SelectionDAG *CurDAG, const SDLoc &DL, int64_t Imm, + MVT XLenVT) { + RISCVMatInt::InstSeq Seq; + RISCVMatInt::generateInstSeq(Imm, XLenVT == MVT::i64, Seq); + + SDNode *Result; + SDValue SrcReg = CurDAG->getRegister(RISCV::X0, XLenVT); + for (RISCVMatInt::Inst &Inst : Seq) { + SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, XLenVT); + if (Inst.Opc == RISCV::LUI) + Result = CurDAG->getMachineNode(RISCV::LUI, DL, XLenVT, SDImm); + else + Result = CurDAG->getMachineNode(Inst.Opc, DL, XLenVT, SrcReg, SDImm); + + // Only the first instruction has X0 as its source. + SrcReg = SDValue(Result, 0); + } + + return Result; +} + void RISCVDAGToDAGISel::Select(SDNode *Node) { // If we have a custom node, we have already selected. if (Node->isMachineOpcode()) { @@ -87,6 +109,11 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { ReplaceNode(Node, New.getNode()); return; } + int64_t Imm = ConstNode->getSExtValue(); + if (XLenVT == MVT::i64) { + ReplaceNode(Node, selectImm(CurDAG, SDLoc(Node), Imm, XLenVT)); + return; + } break; } case ISD::FrameIndex: { |