131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//
333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//                     The LLVM Compiler Infrastructure
433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//
533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source
633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details.
733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//
833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===//
933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//
1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the MSP430 implementation of TargetFrameLowering class.
1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//
1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===//
1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "MSP430FrameLowering.h"
1533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MSP430InstrInfo.h"
1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MSP430MachineFunctionInfo.h"
1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
1833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h"
2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h"
2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm;
2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
2916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
30d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  const MachineFrameInfo *MFI = MF.getFrameInfo();
31d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
328a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky  return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
33d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov          MF.getFrameInfo()->hasVarSizedObjects() ||
34d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov          MFI->isFrameAddressTaken());
35d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov}
36d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
3716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
38d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  return !MF.getFrameInfo()->hasVarSizedObjects();
39d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov}
40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov
4116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MSP430FrameLowering::emitPrologue(MachineFunction &MF) const {
4233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  const MSP430InstrInfo &TII =
4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  MachineBasicBlock::iterator MBBI = MBB.begin();
4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // Get the number of bytes to allocate from the FrameInfo.
5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  uint64_t StackSize = MFI->getStackSize();
5333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
5433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  uint64_t NumBytes = 0;
55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (hasFP(MF)) {
5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Calculate required stack adjustment
5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    uint64_t FrameSize = StackSize - 2;
5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Get the offset of the stack slot for the EBP register... which is
6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Update the frame offset adjustment.
6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    MFI->setOffsetAdjustment(-NumBytes);
6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Save FPW into the appropriate stack slot...
6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      .addReg(MSP430::FPW, RegState::Kill);
6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Update FPW with the new base value...
7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW)
7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      .addReg(MSP430::SPW);
7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Mark the FramePtr as live-in in every block except the entry.
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov         I != E; ++I)
7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      I->addLiveIn(MSP430::FPW);
7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  } else
7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // Skip the callee-saved push instructions.
8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    ++MBBI;
8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
8533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  if (MBBI != MBB.end())
8633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    DL = MBBI->getDebugLoc();
8733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
8833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  if (NumBytes) { // adjust stack pointer: SPW -= numbytes
8933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // If there is an SUB16ri of SPW immediately before this instruction, merge
9033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // the two.
9133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
9233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // If there is an ADD16ri or SUB16ri of SPW immediately after this
9333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // instruction, merge the two instructions.
9433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
9633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    if (NumBytes) {
9733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MachineInstr *MI =
9833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW)
9933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        .addReg(MSP430::SPW).addImm(NumBytes);
10033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      // The SRW implicit def is dead.
10133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MI->getOperand(3).setIsDead();
10233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    }
10333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  }
10433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov}
10533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
10616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
10716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                                       MachineBasicBlock &MBB) const {
10833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  const MachineFrameInfo *MFI = MF.getFrameInfo();
10933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
11033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  const MSP430InstrInfo &TII =
11133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
11233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
1134f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
11433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  unsigned RetOpcode = MBBI->getOpcode();
11533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  DebugLoc DL = MBBI->getDebugLoc();
11633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
11733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  switch (RetOpcode) {
11833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  case MSP430::RET:
11933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  case MSP430::RETI: break;  // These are ok
12033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  default:
12133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    llvm_unreachable("Can only insert epilog into returning blocks");
12233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  }
12333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
12433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // Get the number of bytes to allocate from the FrameInfo
12533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  uint64_t StackSize = MFI->getStackSize();
12633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
12733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  uint64_t NumBytes = 0;
12833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
129d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov  if (hasFP(MF)) {
13033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // Calculate required stack adjustment
13133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    uint64_t FrameSize = StackSize - 2;
13233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    NumBytes = FrameSize - CSSize;
13333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
13433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // pop FPW.
13533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
13633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  } else
13733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    NumBytes = StackSize - CSSize;
13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // Skip the callee-saved pop instructions.
14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  while (MBBI != MBB.begin()) {
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MachineBasicBlock::iterator PI = std::prev(MBBI);
14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    unsigned Opc = PI->getOpcode();
1435a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (Opc != MSP430::POP16r && !PI->isTerminator())
14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      break;
14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    --MBBI;
14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  }
14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  DL = MBBI->getDebugLoc();
14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // If there is an ADD16ri or SUB16ri of SPW immediately before this
15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  // instruction, merge the two instructions.
15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  //if (NumBytes || MFI->hasVarSizedObjects())
15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  //  mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov
15533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  if (MFI->hasVarSizedObjects()) {
15633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    BuildMI(MBB, MBBI, DL,
15733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov            TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW);
15833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    if (CSSize) {
15933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MachineInstr *MI =
16033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        BuildMI(MBB, MBBI, DL,
16133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov                TII.get(MSP430::SUB16ri), MSP430::SPW)
16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        .addReg(MSP430::SPW).addImm(CSSize);
16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      // The SRW implicit def is dead.
16433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MI->getOperand(3).setIsDead();
16533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    }
16633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  } else {
16733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    // adjust stack pointer back: SPW += numbytes
16833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    if (NumBytes) {
16933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MachineInstr *MI =
17033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
17133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov        .addReg(MSP430::SPW).addImm(NumBytes);
17233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      // The SRW implicit def is dead.
17333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov      MI->getOperand(3).setIsDead();
17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov    }
17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov  }
17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov}
177cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
178cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov// FIXME: Can we eleminate these in favour of generic code?
179cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikovbool
18016c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovMSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
181cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                           MachineBasicBlock::iterator MI,
182cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const std::vector<CalleeSavedInfo> &CSI,
183cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const TargetRegisterInfo *TRI) const {
184cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  if (CSI.empty())
185cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    return false;
186cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
187cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  DebugLoc DL;
188cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  if (MI != MBB.end()) DL = MI->getDebugLoc();
189cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
190cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  MachineFunction &MF = *MBB.getParent();
191cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
192cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
193cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  MFI->setCalleeSavedFrameSize(CSI.size() * 2);
194cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
195cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  for (unsigned i = CSI.size(); i != 0; --i) {
196cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    unsigned Reg = CSI[i-1].getReg();
197cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    // Add the callee-saved register as live-in. It's killed at the spill.
198cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    MBB.addLiveIn(Reg);
199cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
200cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov      .addReg(Reg, RegState::Kill);
201cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  }
202cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  return true;
203cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov}
204cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
205cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikovbool
20616c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovMSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
20716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov                                                 MachineBasicBlock::iterator MI,
208cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const std::vector<CalleeSavedInfo> &CSI,
209cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov                                        const TargetRegisterInfo *TRI) const {
210cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  if (CSI.empty())
211cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    return false;
212cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
213cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  DebugLoc DL;
214cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  if (MI != MBB.end()) DL = MI->getDebugLoc();
215cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
216cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  MachineFunction &MF = *MBB.getParent();
217cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
218cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
219cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
220cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov    BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
221cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov
222cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov  return true;
223cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov}
224e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov
225700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid MSP430FrameLowering::
226700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
227700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky                              MachineBasicBlock::iterator I) const {
228700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  const MSP430InstrInfo &TII =
229700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
230700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  unsigned StackAlign = getStackAlignment();
231700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
232700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  if (!hasReservedCallFrame(MF)) {
233700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // If the stack pointer can be changed after prologue, turn the
234700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // adjcallstackup instruction into a 'sub SPW, <amt>' and the
235700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // adjcallstackdown instruction into 'add SPW, <amt>'
236700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // TODO: consider using push / pop instead of sub + store / add
237700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    MachineInstr *Old = I;
238700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    uint64_t Amount = Old->getOperand(0).getImm();
239700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    if (Amount != 0) {
240700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      // We need to keep the stack aligned properly.  To do this, we round the
241700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      // amount of space needed for the outgoing arguments up to the next
242700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      // alignment boundary.
243700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
244700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      MachineInstr *New = nullptr;
246700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
247700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        New = BuildMI(MF, Old->getDebugLoc(),
248700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky                      TII.get(MSP430::SUB16ri), MSP430::SPW)
249700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky          .addReg(MSP430::SPW).addImm(Amount);
250700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      } else {
251700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
252700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        // factor out the amount the callee already popped.
253700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        uint64_t CalleeAmt = Old->getOperand(1).getImm();
254700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        Amount -= CalleeAmt;
255700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        if (Amount)
256700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky          New = BuildMI(MF, Old->getDebugLoc(),
257700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky                        TII.get(MSP430::ADD16ri), MSP430::SPW)
258700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky            .addReg(MSP430::SPW).addImm(Amount);
259700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      }
260700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
261700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      if (New) {
262700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        // The SRW implicit def is dead.
263700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        New->getOperand(3).setIsDead();
264700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
265700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        // Replace the pseudo instruction with a new instruction...
266700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        MBB.insert(I, New);
267700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      }
268700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    }
269700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
270700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // If we are performing frame pointer elimination and if the callee pops
271700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    // something off the stack pointer, add it back.
272700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
273700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      MachineInstr *Old = I;
274700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      MachineInstr *New =
275700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky        BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
276700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky                MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
277700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      // The SRW implicit def is dead.
278700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      New->getOperand(3).setIsDead();
279700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
280700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky      MBB.insert(I, New);
281700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky    }
282700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  }
283700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
284700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  MBB.erase(I);
285700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky}
286700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
287e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikovvoid
2883080d23fde4981835d8a7faf46c152441fadb11fHal FinkelMSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
2893080d23fde4981835d8a7faf46c152441fadb11fHal Finkel                                                         RegScavenger *) const {
290e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov  // Create a frame entry for the FPW register that must be saved.
291700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  if (hasFP(MF)) {
292e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov    int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
293e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov    (void)FrameIdx;
294e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov    assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
295e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov           "Slot for FPW register must be last in order to be found!");
296e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov  }
297e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov}
298