summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp74
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.
OpenPOWER on IntegriCloud