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/CodeGen/MachineFrameInfo.h"
18#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineModuleInfo.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Function.h"
24#include "llvm/Support/CommandLine.h"
25#include "llvm/Target/TargetOptions.h"
26
27using namespace llvm;
28
29bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
30  const MachineFrameInfo *MFI = MF.getFrameInfo();
31
32  return (MF.getTarget().Options.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 = std::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 = std::prev(MBBI);
142    unsigned Opc = PI->getOpcode();
143    if (Opc != MSP430::POP16r && !PI->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
225void MSP430FrameLowering::
226eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
227                              MachineBasicBlock::iterator I) const {
228  const MSP430InstrInfo &TII =
229    *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
230  unsigned StackAlign = getStackAlignment();
231
232  if (!hasReservedCallFrame(MF)) {
233    // If the stack pointer can be changed after prologue, turn the
234    // adjcallstackup instruction into a 'sub SPW, <amt>' and the
235    // adjcallstackdown instruction into 'add SPW, <amt>'
236    // TODO: consider using push / pop instead of sub + store / add
237    MachineInstr *Old = I;
238    uint64_t Amount = Old->getOperand(0).getImm();
239    if (Amount != 0) {
240      // We need to keep the stack aligned properly.  To do this, we round the
241      // amount of space needed for the outgoing arguments up to the next
242      // alignment boundary.
243      Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
244
245      MachineInstr *New = nullptr;
246      if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
247        New = BuildMI(MF, Old->getDebugLoc(),
248                      TII.get(MSP430::SUB16ri), MSP430::SPW)
249          .addReg(MSP430::SPW).addImm(Amount);
250      } else {
251        assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
252        // factor out the amount the callee already popped.
253        uint64_t CalleeAmt = Old->getOperand(1).getImm();
254        Amount -= CalleeAmt;
255        if (Amount)
256          New = BuildMI(MF, Old->getDebugLoc(),
257                        TII.get(MSP430::ADD16ri), MSP430::SPW)
258            .addReg(MSP430::SPW).addImm(Amount);
259      }
260
261      if (New) {
262        // The SRW implicit def is dead.
263        New->getOperand(3).setIsDead();
264
265        // Replace the pseudo instruction with a new instruction...
266        MBB.insert(I, New);
267      }
268    }
269  } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
270    // If we are performing frame pointer elimination and if the callee pops
271    // something off the stack pointer, add it back.
272    if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
273      MachineInstr *Old = I;
274      MachineInstr *New =
275        BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
276                MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
277      // The SRW implicit def is dead.
278      New->getOperand(3).setIsDead();
279
280      MBB.insert(I, New);
281    }
282  }
283
284  MBB.erase(I);
285}
286
287void
288MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
289                                                         RegScavenger *) const {
290  // Create a frame entry for the FPW register that must be saved.
291  if (hasFP(MF)) {
292    int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
293    (void)FrameIdx;
294    assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
295           "Slot for FPW register must be last in order to be found!");
296  }
297}
298