diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index ff2f7756ad7..040dc7814a7 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -293,20 +293,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(), 1 << ShiftAmount) != 0) + return false; + } Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy); @@ -392,17 +397,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 +472,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. |

