From 40477317f39dccfd5c9c139feabda1becc6bd49c Mon Sep 17 00:00:00 2001
From: Anton Korobeynikov <asl@math.spbu.ru>
Date: Sun, 3 May 2009 13:10:26 +0000
Subject: [PATCH] Proper handle loading of effective address of stack slot
 stuff

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70737 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Target/MSP430/MSP430ISelDAGToDAG.cpp | 24 +++++++++++-------
 lib/Target/MSP430/MSP430InstrInfo.td     |  3 +--
 lib/Target/MSP430/MSP430RegisterInfo.cpp | 31 +++++++++++++++++++++---
 3 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index a049413975c..522e170d60a 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -132,6 +132,7 @@ void MSP430DAGToDAGISel::InstructionSelect() {
 
 SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
   SDNode *Node = Op.getNode();
+  DebugLoc dl = Op.getDebugLoc();
 
   // Dump information about the Node being selected
   #ifndef NDEBUG
@@ -152,15 +153,20 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
     return NULL;
   }
 
-  // Instruction Selection not handled by the auto-generated tablegen selection
-  // should be handled here.
-  // Something like this:
-  //   unsigned Opcode = Node->getOpcode();
-  //   switch (Opcode) {
-  //   default: break;
-  //   case ISD::Foo:
-  //    return SelectFoo(Node)
-  //  }
+  // Few custom selection stuff.
+  switch (Node->getOpcode()) {
+  default: break;
+  case ISD::FrameIndex: {
+    assert(Op.getValueType() == MVT::i16);
+    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
+    SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
+    if (Node->hasOneUse())
+      return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
+                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
+    return CurDAG->getTargetNode(MSP430::ADD16ri, dl, MVT::i16,
+                                 TFI, CurDAG->getTargetConstant(0, MVT::i16));
+  }
+  }
 
   // Select the default instruction
   SDNode *ResNode = SelectCode(Op);
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index a0a94403ebd..3afab5b0ac3 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -60,7 +60,6 @@ def memdst : Operand<i16> {
   let MIOperandInfo = (ops GR16, i16imm);
 }
 
-
 //===----------------------------------------------------------------------===//
 // MSP430 Complex Pattern Definitions.
 //===----------------------------------------------------------------------===//
@@ -614,7 +613,7 @@ def : Pat<(i8 (trunc GR16:$src)),
           (EXTRACT_SUBREG GR16:$src, subreg_8bit)>;
 
 // GlobalAddress
-def : Pat<(i16 (MSP430Wrapper tglobaladdr :$dst)), (MOV16ri tglobaladdr :$dst)>;
+def : Pat<(i16 (MSP430Wrapper tglobaladdr:$dst)), (MOV16ri tglobaladdr:$dst)>;
 
 def : Pat<(add GR16:$src1, (MSP430Wrapper tglobaladdr :$src2)),
           (ADD16ri GR16:$src1, tglobaladdr:$src2)>;
diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp
index be187fa8e66..264736bc830 100644
--- a/lib/Target/MSP430/MSP430RegisterInfo.cpp
+++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp
@@ -152,7 +152,9 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
 
   unsigned i = 0;
   MachineInstr &MI = *II;
-  MachineFunction &MF = *MI.getParent()->getParent();
+  MachineBasicBlock &MBB = *MI.getParent();
+  MachineFunction &MF = *MBB.getParent();
+  DebugLoc dl = MI.getDebugLoc();
   while (!MI.getOperand(i).isFI()) {
     ++i;
     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
@@ -169,10 +171,33 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
   // Skip the saved PC
   Offset += 2;
 
-  MI.getOperand(i).ChangeToRegister(BasePtr, false);
-
   // Fold imm into offset
   Offset += MI.getOperand(i+1).getImm();
+
+  if (MI.getOpcode() == MSP430::ADD16ri) {
+    // This is actually "load effective address" of the stack slot
+    // instruction. We have only two-address instructions, thus we need to
+    // expand it into mov + add
+
+    MI.setDesc(TII.get(MSP430::MOV16rr));
+    MI.getOperand(i).ChangeToRegister(BasePtr, false);
+
+    if (Offset == 0)
+      return;
+
+    // We need to materialize the offset via add instruction.
+    unsigned DstReg = MI.getOperand(0).getReg();
+    if (Offset < 0)
+      BuildMI(MBB, next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
+        .addReg(DstReg).addImm(-Offset);
+    else
+      BuildMI(MBB, next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
+        .addReg(DstReg).addImm(Offset);
+
+    return;
+  }
+
+  MI.getOperand(i).ChangeToRegister(BasePtr, false);
   MI.getOperand(i+1).ChangeToImmediate(Offset);
 }