diff options
| author | Alex Bradbury <asb@lowrisc.org> | 2018-04-17 21:56:40 +0000 |
|---|---|---|
| committer | Alex Bradbury <asb@lowrisc.org> | 2018-04-17 21:56:40 +0000 |
| commit | 480b7bc906865fdde915844210ff1efbd88d3103 (patch) | |
| tree | 9596618bdd12b96b42b4937d3c3c627b17ed6597 /llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | |
| parent | 09e0e2e656dfc92e93d575abaa0eb470f9954fc5 (diff) | |
| download | bcm5719-llvm-480b7bc906865fdde915844210ff1efbd88d3103.tar.gz bcm5719-llvm-480b7bc906865fdde915844210ff1efbd88d3103.zip | |
[RISCV] implement li pseudo instruction
The implementation follows the MIPS backend and expands the
pseudo instruction directly during asm parsing. As the result, only
real MC instructions are emitted to the MCStreamer. Additionally,
PseudoLI instructions are emitted during codegen. The actual
expansion to real instructions is performed during MI to MC lowering
and is similar to the expansion performed by the GNU Assembler.
Differential Revision: https://reviews.llvm.org/D41949
Patch by Mario Werner.
llvm-svn: 330224
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 630439bb53c..8fdf18efb58 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -179,41 +179,62 @@ void RISCVDAGToDAGISel::doPeepholeLoadStoreADDI() { SDValue Base = N->getOperand(BaseOpIdx); - // If the base is an ADDI, we can merge it in to the load/store. - if (!Base.isMachineOpcode() || Base.getMachineOpcode() != RISCV::ADDI) + // If the base is an ADDI or PseudoLI, we can either merge it or at least + // sink the lowest 12 bits into the load/store. + if (!Base.isMachineOpcode() || (Base.getMachineOpcode() != RISCV::ADDI && + Base.getMachineOpcode() != RISCV::PseudoLI)) continue; - SDValue ImmOperand = Base.getOperand(1); - - if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) { - ImmOperand = CurDAG->getTargetConstant( - Const->getSExtValue(), SDLoc(ImmOperand), ImmOperand.getValueType()); - } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) { - ImmOperand = CurDAG->getTargetGlobalAddress( - GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(), - GA->getOffset(), GA->getTargetFlags()); + SDValue ImmOperand; + SDValue Parent; + if (Base.getMachineOpcode() == RISCV::PseudoLI) { + ImmOperand = Base.getOperand(0); + auto Const = dyn_cast<ConstantSDNode>(ImmOperand); + if (!Const || (Const->getSExtValue() & 0xFFF) == 0) + continue; + + int64_t Hi52 = (Const->getSExtValue() + 0x800) & ~0xFFF; + SDValue HiVal = CurDAG->getTargetConstant(Hi52, SDLoc(ImmOperand), + ImmOperand.getValueType()); + Parent = + SDValue(CurDAG->getMachineNode(RISCV::PseudoLI, SDLoc(ImmOperand), + ImmOperand.getValueType(), HiVal), + 0); + + int64_t Lo12 = SignExtend64<12>(Const->getSExtValue()); + ImmOperand = CurDAG->getTargetConstant(Lo12, SDLoc(ImmOperand), + ImmOperand.getValueType()); } else { - continue; + Parent = Base.getOperand(0); + ImmOperand = Base.getOperand(1); + + if (auto Const = dyn_cast<ConstantSDNode>(ImmOperand)) { + ImmOperand = + CurDAG->getTargetConstant(Const->getSExtValue(), SDLoc(ImmOperand), + ImmOperand.getValueType()); + } else if (auto GA = dyn_cast<GlobalAddressSDNode>(ImmOperand)) { + ImmOperand = CurDAG->getTargetGlobalAddress( + GA->getGlobal(), SDLoc(ImmOperand), ImmOperand.getValueType(), + GA->getOffset(), GA->getTargetFlags()); + } else { + continue; + } } - DEBUG(dbgs() << "Folding add-immediate into mem-op:\nBase: "); - DEBUG(Base->dump(CurDAG)); + DEBUG(dbgs() << "Folding add-immediate or PseudoLI into mem-op:\nBase: "); + DEBUG(Base.dump(CurDAG)); DEBUG(dbgs() << "\nN: "); DEBUG(N->dump(CurDAG)); DEBUG(dbgs() << "\n"); // Modify the offset operand of the load/store. if (BaseOpIdx == 0) // Load - CurDAG->UpdateNodeOperands(N, Base.getOperand(0), ImmOperand, - N->getOperand(2)); + CurDAG->UpdateNodeOperands(N, Parent, ImmOperand, N->getOperand(2)); else // Store - CurDAG->UpdateNodeOperands(N, N->getOperand(0), Base.getOperand(0), - ImmOperand, N->getOperand(3)); - - // The add-immediate may now be dead, in which case remove it. - if (Base.getNode()->use_empty()) - CurDAG->RemoveDeadNode(Base.getNode()); + CurDAG->UpdateNodeOperands(N, N->getOperand(0), Parent, ImmOperand, + N->getOperand(3)); } + CurDAG->RemoveDeadNodes(); } // Remove redundant BuildPairF64+SplitF64 pairs. i.e. cases where an f64 is |

