diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 84 |
1 files changed, 59 insertions, 25 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index d9528da..92d3c00 100644 --- a/contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/contrib/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -28,6 +28,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" +#include "llvm/IR/Dominators.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -43,6 +44,11 @@ bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { return MipsDAGToDAGISel::runOnMachineFunction(MF); } +void MipsSEDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<DominatorTreeWrapperPass>(); + SelectionDAGISel::getAnalysisUsage(AU); +} + void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, MachineFunction &MF) { MachineInstrBuilder MIB(MF, &MI); @@ -293,20 +299,25 @@ bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base, } /// Match frameindex+offset and frameindex|offset -bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(SDValue Addr, SDValue &Base, - SDValue &Offset, - unsigned OffsetBits) const { +bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset( + SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits, + unsigned ShiftAmount = 0) const { if (CurDAG->isBaseWithConstantOffset(Addr)) { ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); - if (isIntN(OffsetBits, CN->getSExtValue())) { + if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) { EVT ValTy = Addr.getValueType(); // If the first operand is a FI, get the TargetFI Node - if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> - (Addr.getOperand(0))) + if (FrameIndexSDNode *FIN = + dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); - else + else { Base = Addr.getOperand(0); + // If base is a FI, additional offset calculation is done in + // eliminateFrameIndex, otherwise we need to check the alignment + if (OffsetToAlignment(CN->getZExtValue(), 1ull << ShiftAmount) != 0) + return false; + } Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy); @@ -392,17 +403,6 @@ bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base, return false; } -bool MipsSEDAGToDAGISel::selectAddrRegImm10(SDValue Addr, SDValue &Base, - SDValue &Offset) const { - if (selectAddrFrameIndex(Addr, Base, Offset)) - return true; - - if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) - return true; - - return false; -} - /// Used on microMIPS LWC2, LDC2, SWC2 and SDC2 instructions (11-bit offset) bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base, SDValue &Offset) const { @@ -478,15 +478,49 @@ bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, return selectAddrDefault(Addr, Base, Offset); } -bool MipsSEDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base, - SDValue &Offset) const { - if (selectAddrRegImm10(Addr, Base, Offset)) +bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + + if (selectAddrFrameIndex(Addr, Base, Offset)) return true; - if (selectAddrDefault(Addr, Base, Offset)) + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) return true; - return false; + return selectAddrDefault(Addr, Base, Offset); +} + +bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1)) + return true; + + return selectAddrDefault(Addr, Base, Offset); +} + +bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2)) + return true; + + return selectAddrDefault(Addr, Base, Offset); +} + +bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3)) + return true; + + return selectAddrDefault(Addr, Base, Offset); } // Select constant vector splats. @@ -771,13 +805,13 @@ bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) { case ISD::Constant: { const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); + int64_t Imm = CN->getSExtValue(); unsigned Size = CN->getValueSizeInBits(0); - if (Size == 32) + if (isInt<32>(Imm)) break; MipsAnalyzeImmediate AnalyzeImm; - int64_t Imm = CN->getSExtValue(); const MipsAnalyzeImmediate::InstSeq &Seq = AnalyzeImm.Analyze(Imm, Size, false); |