Basic support for mem=>reg moves

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70723 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 0ad8752..3b28668 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -57,6 +57,7 @@
 
   private:
     SDNode *Select(SDValue Op);
+    bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Disp, SDValue &Base);
 
   #ifndef NDEBUG
     unsigned Indent;
@@ -71,6 +72,38 @@
   return new MSP430DAGToDAGISel(TM);
 }
 
+bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue Addr,
+                                    SDValue &Disp, SDValue &Base) {
+  // We don't support frame index stuff yet.
+  if (isa<FrameIndexSDNode>(Addr))
+    return false;
+
+  // Operand is a result from ADD with constant operand which fits into i16.
+  if (Addr.getOpcode() == ISD::ADD) {
+    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+      uint64_t CVal = CN->getZExtValue();
+      // Offset should fit into 16 bits.
+      if (((CVal << 48) >> 48) == CVal) {
+        // We don't support frame index stuff yet.
+        if (isa<FrameIndexSDNode>(Addr.getOperand(0)))
+          return false;
+
+        Base = Addr.getOperand(0);
+        Disp = CurDAG->getTargetConstant(CVal, MVT::i16);
+
+        return true;
+      }
+    }
+  }
+
+  Base = Addr;
+  Disp = CurDAG->getTargetConstant(0, MVT::i16);
+
+  return true;
+}
+
+
+
 /// InstructionSelect - This callback is invoked by
 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
 void MSP430DAGToDAGISel::InstructionSelect() {