First try of the post-inc operands handling... Not fully worked, though :(
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86386 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index b45690b..ac01bf8 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -43,6 +43,9 @@
static const bool ViewRMWDAGs = false;
#endif
+static cl::opt<bool>
+EnablePostIncOps("enable-msp430-post-inc-ops", cl::Hidden);
+
STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
@@ -148,6 +151,9 @@
void PreprocessForRMW();
SDNode *Select(SDValue Op);
SDNode *SelectIndexedLoad(SDValue Op);
+ SDNode *SelectIndexedBinOp(SDValue Op, SDValue N1, SDValue N2,
+ unsigned Opc8, unsigned Opc16);
+
bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
#ifndef NDEBUG
@@ -598,39 +604,85 @@
}
-SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+static bool isValidIndexedLoad(const LoadSDNode *LD) {
ISD::MemIndexedMode AM = LD->getAddressingMode();
if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
- return NULL;
+ return false;
EVT VT = LD->getMemoryVT();
- unsigned Opcode = 0;
switch (VT.getSimpleVT().SimpleTy) {
case MVT::i8:
// Sanity check
if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
- return NULL;
+ return false;
- Opcode = MSP430::MOV8rm_POST;
break;
case MVT::i16:
// Sanity check
if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
- return NULL;
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
+ LoadSDNode *LD = cast<LoadSDNode>(Op);
+ if (!isValidIndexedLoad(LD))
+ return NULL;
+
+ MVT VT = LD->getMemoryVT().getSimpleVT();
+
+ unsigned Opcode = 0;
+ switch (VT.SimpleTy) {
+ case MVT::i8:
+ Opcode = MSP430::MOV8rm_POST;
+ break;
+ case MVT::i16:
Opcode = MSP430::MOV16rm_POST;
break;
default:
return NULL;
}
- return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(),
- VT.getSimpleVT().SimpleTy, MVT::i16, MVT::Other,
- LD->getBasePtr(), LD->getChain());
+ return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(),
+ VT, MVT::i16, MVT::Other,
+ LD->getBasePtr(), LD->getChain());
}
+SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op,
+ SDValue N1, SDValue N2,
+ unsigned Opc8, unsigned Opc16) {
+ if (N1.getOpcode() == ISD::LOAD &&
+ N1.hasOneUse() &&
+ IsLegalAndProfitableToFold(N1.getNode(), Op.getNode(), Op.getNode())) {
+ LoadSDNode *LD = cast<LoadSDNode>(N1);
+ if (!isValidIndexedLoad(LD))
+ return NULL;
+
+ MVT VT = LD->getMemoryVT().getSimpleVT();
+ unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
+ MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
+ MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
+ SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
+ SDNode *ResNode =
+ CurDAG->SelectNodeTo(Op.getNode(), Opc,
+ VT, MVT::i16, MVT::Other,
+ Ops0, 3);
+ cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
+ ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 3));
+ return ResNode;
+ }
+
+ return NULL;
+}
+
+
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void MSP430DAGToDAGISel::InstructionSelect() {
@@ -693,6 +745,21 @@
return ResNode;
// Other cases are autogenerated.
break;
+ case ISD::ADD:
+ if (EnablePostIncOps) {
+ if (SDNode *ResNode =
+ SelectIndexedBinOp(Op,
+ Op.getOperand(0), Op.getOperand(1),
+ MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
+ return ResNode;
+ else if (SDNode *ResNode =
+ SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
+ return ResNode;
+ }
+
+ // Other cases are autogenerated.
+ break;
}
// Select the default instruction