MSP430FrameLowering.cpp revision 4f28c1c71450c711e96aa283de53739d8b4504cd
1//======-- MSP430FrameLowering.cpp - MSP430 Frame Information -------=========//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the MSP430 implementation of TargetFrameLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "MSP430FrameLowering.h"
15#include "MSP430InstrInfo.h"
16#include "MSP430MachineFunctionInfo.h"
17#include "llvm/Function.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineFunction.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineModuleInfo.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/Target/TargetData.h"
24#include "llvm/Target/TargetOptions.h"
25#include "llvm/Support/CommandLine.h"
26
27using namespace llvm;
28
29bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
30  const MachineFrameInfo *MFI = MF.getFrameInfo();
31
32  return (DisableFramePointerElim(MF) ||
33          MF.getFrameInfo()->hasVarSizedObjects() ||
34          MFI->isFrameAddressTaken());
35}
36
37bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
38  return !MF.getFrameInfo()->hasVarSizedObjects();
39}
40
41void MSP430FrameLowering::emitPrologue(MachineFunction &MF) const {
42  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
43  MachineFrameInfo *MFI = MF.getFrameInfo();
44  MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
45  const MSP430InstrInfo &TII =
46    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
47
48  MachineBasicBlock::iterator MBBI = MBB.begin();
49  DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
50
51  // Get the number of bytes to allocate from the FrameInfo.
52  uint64_t StackSize = MFI->getStackSize();
53
54  uint64_t NumBytes = 0;
55  if (hasFP(MF)) {
56    // Calculate required stack adjustment
57    uint64_t FrameSize = StackSize - 2;
58    NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
59
60    // Get the offset of the stack slot for the EBP register... which is
61    // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
62    // Update the frame offset adjustment.
63    MFI->setOffsetAdjustment(-NumBytes);
64
65    // Save FPW into the appropriate stack slot...
66    BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
67      .addReg(MSP430::FPW, RegState::Kill);
68
69    // Update FPW with the new base value...
70    BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW)
71      .addReg(MSP430::SPW);
72
73    // Mark the FramePtr as live-in in every block except the entry.
74    for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
75         I != E; ++I)
76      I->addLiveIn(MSP430::FPW);
77
78  } else
79    NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
80
81  // Skip the callee-saved push instructions.
82  while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
83    ++MBBI;
84
85  if (MBBI != MBB.end())
86    DL = MBBI->getDebugLoc();
87
88  if (NumBytes) { // adjust stack pointer: SPW -= numbytes
89    // If there is an SUB16ri of SPW immediately before this instruction, merge
90    // the two.
91    //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
92    // If there is an ADD16ri or SUB16ri of SPW immediately after this
93    // instruction, merge the two instructions.
94    // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
95
96    if (NumBytes) {
97      MachineInstr *MI =
98        BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW)
99        .addReg(MSP430::SPW).addImm(NumBytes);
100      // The SRW implicit def is dead.
101      MI->getOperand(3).setIsDead();
102    }
103  }
104}
105
106void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
107                                       MachineBasicBlock &MBB) const {
108  const MachineFrameInfo *MFI = MF.getFrameInfo();
109  MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
110  const MSP430InstrInfo &TII =
111    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
112
113  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
114  unsigned RetOpcode = MBBI->getOpcode();
115  DebugLoc DL = MBBI->getDebugLoc();
116
117  switch (RetOpcode) {
118  case MSP430::RET:
119  case MSP430::RETI: break;  // These are ok
120  default:
121    llvm_unreachable("Can only insert epilog into returning blocks");
122  }
123
124  // Get the number of bytes to allocate from the FrameInfo
125  uint64_t StackSize = MFI->getStackSize();
126  unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
127  uint64_t NumBytes = 0;
128
129  if (hasFP(MF)) {
130    // Calculate required stack adjustment
131    uint64_t FrameSize = StackSize - 2;
132    NumBytes = FrameSize - CSSize;
133
134    // pop FPW.
135    BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
136  } else
137    NumBytes = StackSize - CSSize;
138
139  // Skip the callee-saved pop instructions.
140  while (MBBI != MBB.begin()) {
141    MachineBasicBlock::iterator PI = prior(MBBI);
142    unsigned Opc = PI->getOpcode();
143    if (Opc != MSP430::POP16r && !PI->getDesc().isTerminator())
144      break;
145    --MBBI;
146  }
147
148  DL = MBBI->getDebugLoc();
149
150  // If there is an ADD16ri or SUB16ri of SPW immediately before this
151  // instruction, merge the two instructions.
152  //if (NumBytes || MFI->hasVarSizedObjects())
153  //  mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
154
155  if (MFI->hasVarSizedObjects()) {
156    BuildMI(MBB, MBBI, DL,
157            TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW);
158    if (CSSize) {
159      MachineInstr *MI =
160        BuildMI(MBB, MBBI, DL,
161                TII.get(MSP430::SUB16ri), MSP430::SPW)
162        .addReg(MSP430::SPW).addImm(CSSize);
163      // The SRW implicit def is dead.
164      MI->getOperand(3).setIsDead();
165    }
166  } else {
167    // adjust stack pointer back: SPW += numbytes
168    if (NumBytes) {
169      MachineInstr *MI =
170        BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
171        .addReg(MSP430::SPW).addImm(NumBytes);
172      // The SRW implicit def is dead.
173      MI->getOperand(3).setIsDead();
174    }
175  }
176}
177
178// FIXME: Can we eleminate these in favour of generic code?
179bool
180MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
181                                           MachineBasicBlock::iterator MI,
182                                        const std::vector<CalleeSavedInfo> &CSI,
183                                        const TargetRegisterInfo *TRI) const {
184  if (CSI.empty())
185    return false;
186
187  DebugLoc DL;
188  if (MI != MBB.end()) DL = MI->getDebugLoc();
189
190  MachineFunction &MF = *MBB.getParent();
191  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
192  MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
193  MFI->setCalleeSavedFrameSize(CSI.size() * 2);
194
195  for (unsigned i = CSI.size(); i != 0; --i) {
196    unsigned Reg = CSI[i-1].getReg();
197    // Add the callee-saved register as live-in. It's killed at the spill.
198    MBB.addLiveIn(Reg);
199    BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
200      .addReg(Reg, RegState::Kill);
201  }
202  return true;
203}
204
205bool
206MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
207                                                 MachineBasicBlock::iterator MI,
208                                        const std::vector<CalleeSavedInfo> &CSI,
209                                        const TargetRegisterInfo *TRI) const {
210  if (CSI.empty())
211    return false;
212
213  DebugLoc DL;
214  if (MI != MBB.end()) DL = MI->getDebugLoc();
215
216  MachineFunction &MF = *MBB.getParent();
217  const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
218
219  for (unsigned i = 0, e = CSI.size(); i != e; ++i)
220    BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
221
222  return true;
223}
224