xref: /aosp_15_r20/external/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the MSP430 implementation of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "MSP430FrameLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "MSP430InstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "MSP430MachineFunctionInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "MSP430Subtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker 
hasFP(const MachineFunction & MF) const29*9880d681SAndroid Build Coastguard Worker bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
30*9880d681SAndroid Build Coastguard Worker   const MachineFrameInfo *MFI = MF.getFrameInfo();
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker   return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
33*9880d681SAndroid Build Coastguard Worker           MF.getFrameInfo()->hasVarSizedObjects() ||
34*9880d681SAndroid Build Coastguard Worker           MFI->isFrameAddressTaken());
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker 
hasReservedCallFrame(const MachineFunction & MF) const37*9880d681SAndroid Build Coastguard Worker bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
38*9880d681SAndroid Build Coastguard Worker   return !MF.getFrameInfo()->hasVarSizedObjects();
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker 
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const41*9880d681SAndroid Build Coastguard Worker void MSP430FrameLowering::emitPrologue(MachineFunction &MF,
42*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock &MBB) const {
43*9880d681SAndroid Build Coastguard Worker   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
44*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
45*9880d681SAndroid Build Coastguard Worker   MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
46*9880d681SAndroid Build Coastguard Worker   const MSP430InstrInfo &TII =
47*9880d681SAndroid Build Coastguard Worker       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator MBBI = MBB.begin();
50*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker   // Get the number of bytes to allocate from the FrameInfo.
53*9880d681SAndroid Build Coastguard Worker   uint64_t StackSize = MFI->getStackSize();
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   uint64_t NumBytes = 0;
56*9880d681SAndroid Build Coastguard Worker   if (hasFP(MF)) {
57*9880d681SAndroid Build Coastguard Worker     // Calculate required stack adjustment
58*9880d681SAndroid Build Coastguard Worker     uint64_t FrameSize = StackSize - 2;
59*9880d681SAndroid Build Coastguard Worker     NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker     // Get the offset of the stack slot for the EBP register... which is
62*9880d681SAndroid Build Coastguard Worker     // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
63*9880d681SAndroid Build Coastguard Worker     // Update the frame offset adjustment.
64*9880d681SAndroid Build Coastguard Worker     MFI->setOffsetAdjustment(-NumBytes);
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker     // Save FP into the appropriate stack slot...
67*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
68*9880d681SAndroid Build Coastguard Worker       .addReg(MSP430::FP, RegState::Kill);
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker     // Update FP with the new base value...
71*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP)
72*9880d681SAndroid Build Coastguard Worker       .addReg(MSP430::SP);
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker     // Mark the FramePtr as live-in in every block except the entry.
75*9880d681SAndroid Build Coastguard Worker     for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
76*9880d681SAndroid Build Coastguard Worker          I != E; ++I)
77*9880d681SAndroid Build Coastguard Worker       I->addLiveIn(MSP430::FP);
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   } else
80*9880d681SAndroid Build Coastguard Worker     NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   // Skip the callee-saved push instructions.
83*9880d681SAndroid Build Coastguard Worker   while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
84*9880d681SAndroid Build Coastguard Worker     ++MBBI;
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   if (MBBI != MBB.end())
87*9880d681SAndroid Build Coastguard Worker     DL = MBBI->getDebugLoc();
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   if (NumBytes) { // adjust stack pointer: SP -= numbytes
90*9880d681SAndroid Build Coastguard Worker     // If there is an SUB16ri of SP immediately before this instruction, merge
91*9880d681SAndroid Build Coastguard Worker     // the two.
92*9880d681SAndroid Build Coastguard Worker     //NumBytes -= mergeSPUpdates(MBB, MBBI, true);
93*9880d681SAndroid Build Coastguard Worker     // If there is an ADD16ri or SUB16ri of SP immediately after this
94*9880d681SAndroid Build Coastguard Worker     // instruction, merge the two instructions.
95*9880d681SAndroid Build Coastguard Worker     // mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker     if (NumBytes) {
98*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI =
99*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP)
100*9880d681SAndroid Build Coastguard Worker         .addReg(MSP430::SP).addImm(NumBytes);
101*9880d681SAndroid Build Coastguard Worker       // The SRW implicit def is dead.
102*9880d681SAndroid Build Coastguard Worker       MI->getOperand(3).setIsDead();
103*9880d681SAndroid Build Coastguard Worker     }
104*9880d681SAndroid Build Coastguard Worker   }
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker 
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const107*9880d681SAndroid Build Coastguard Worker void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
108*9880d681SAndroid Build Coastguard Worker                                        MachineBasicBlock &MBB) const {
109*9880d681SAndroid Build Coastguard Worker   const MachineFrameInfo *MFI = MF.getFrameInfo();
110*9880d681SAndroid Build Coastguard Worker   MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
111*9880d681SAndroid Build Coastguard Worker   const MSP430InstrInfo &TII =
112*9880d681SAndroid Build Coastguard Worker       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
115*9880d681SAndroid Build Coastguard Worker   unsigned RetOpcode = MBBI->getOpcode();
116*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MBBI->getDebugLoc();
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   switch (RetOpcode) {
119*9880d681SAndroid Build Coastguard Worker   case MSP430::RET:
120*9880d681SAndroid Build Coastguard Worker   case MSP430::RETI: break;  // These are ok
121*9880d681SAndroid Build Coastguard Worker   default:
122*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Can only insert epilog into returning blocks");
123*9880d681SAndroid Build Coastguard Worker   }
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   // Get the number of bytes to allocate from the FrameInfo
126*9880d681SAndroid Build Coastguard Worker   uint64_t StackSize = MFI->getStackSize();
127*9880d681SAndroid Build Coastguard Worker   unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
128*9880d681SAndroid Build Coastguard Worker   uint64_t NumBytes = 0;
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker   if (hasFP(MF)) {
131*9880d681SAndroid Build Coastguard Worker     // Calculate required stack adjustment
132*9880d681SAndroid Build Coastguard Worker     uint64_t FrameSize = StackSize - 2;
133*9880d681SAndroid Build Coastguard Worker     NumBytes = FrameSize - CSSize;
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker     // pop FP.
136*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP);
137*9880d681SAndroid Build Coastguard Worker   } else
138*9880d681SAndroid Build Coastguard Worker     NumBytes = StackSize - CSSize;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   // Skip the callee-saved pop instructions.
141*9880d681SAndroid Build Coastguard Worker   while (MBBI != MBB.begin()) {
142*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator PI = std::prev(MBBI);
143*9880d681SAndroid Build Coastguard Worker     unsigned Opc = PI->getOpcode();
144*9880d681SAndroid Build Coastguard Worker     if (Opc != MSP430::POP16r && !PI->isTerminator())
145*9880d681SAndroid Build Coastguard Worker       break;
146*9880d681SAndroid Build Coastguard Worker     --MBBI;
147*9880d681SAndroid Build Coastguard Worker   }
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   DL = MBBI->getDebugLoc();
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   // If there is an ADD16ri or SUB16ri of SP immediately before this
152*9880d681SAndroid Build Coastguard Worker   // instruction, merge the two instructions.
153*9880d681SAndroid Build Coastguard Worker   //if (NumBytes || MFI->hasVarSizedObjects())
154*9880d681SAndroid Build Coastguard Worker   //  mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker   if (MFI->hasVarSizedObjects()) {
157*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MBBI, DL,
158*9880d681SAndroid Build Coastguard Worker             TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::FP);
159*9880d681SAndroid Build Coastguard Worker     if (CSSize) {
160*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI =
161*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, MBBI, DL,
162*9880d681SAndroid Build Coastguard Worker                 TII.get(MSP430::SUB16ri), MSP430::SP)
163*9880d681SAndroid Build Coastguard Worker         .addReg(MSP430::SP).addImm(CSSize);
164*9880d681SAndroid Build Coastguard Worker       // The SRW implicit def is dead.
165*9880d681SAndroid Build Coastguard Worker       MI->getOperand(3).setIsDead();
166*9880d681SAndroid Build Coastguard Worker     }
167*9880d681SAndroid Build Coastguard Worker   } else {
168*9880d681SAndroid Build Coastguard Worker     // adjust stack pointer back: SP += numbytes
169*9880d681SAndroid Build Coastguard Worker     if (NumBytes) {
170*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI =
171*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP)
172*9880d681SAndroid Build Coastguard Worker         .addReg(MSP430::SP).addImm(NumBytes);
173*9880d681SAndroid Build Coastguard Worker       // The SRW implicit def is dead.
174*9880d681SAndroid Build Coastguard Worker       MI->getOperand(3).setIsDead();
175*9880d681SAndroid Build Coastguard Worker     }
176*9880d681SAndroid Build Coastguard Worker   }
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker // FIXME: Can we eleminate these in favour of generic code?
180*9880d681SAndroid Build Coastguard Worker bool
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const181*9880d681SAndroid Build Coastguard Worker MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
182*9880d681SAndroid Build Coastguard Worker                                            MachineBasicBlock::iterator MI,
183*9880d681SAndroid Build Coastguard Worker                                         const std::vector<CalleeSavedInfo> &CSI,
184*9880d681SAndroid Build Coastguard Worker                                         const TargetRegisterInfo *TRI) const {
185*9880d681SAndroid Build Coastguard Worker   if (CSI.empty())
186*9880d681SAndroid Build Coastguard Worker     return false;
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
189*9880d681SAndroid Build Coastguard Worker   if (MI != MBB.end()) DL = MI->getDebugLoc();
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
192*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
193*9880d681SAndroid Build Coastguard Worker   MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>();
194*9880d681SAndroid Build Coastguard Worker   MFI->setCalleeSavedFrameSize(CSI.size() * 2);
195*9880d681SAndroid Build Coastguard Worker 
196*9880d681SAndroid Build Coastguard Worker   for (unsigned i = CSI.size(); i != 0; --i) {
197*9880d681SAndroid Build Coastguard Worker     unsigned Reg = CSI[i-1].getReg();
198*9880d681SAndroid Build Coastguard Worker     // Add the callee-saved register as live-in. It's killed at the spill.
199*9880d681SAndroid Build Coastguard Worker     MBB.addLiveIn(Reg);
200*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r))
201*9880d681SAndroid Build Coastguard Worker       .addReg(Reg, RegState::Kill);
202*9880d681SAndroid Build Coastguard Worker   }
203*9880d681SAndroid Build Coastguard Worker   return true;
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker bool
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const207*9880d681SAndroid Build Coastguard Worker MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
208*9880d681SAndroid Build Coastguard Worker                                                  MachineBasicBlock::iterator MI,
209*9880d681SAndroid Build Coastguard Worker                                         const std::vector<CalleeSavedInfo> &CSI,
210*9880d681SAndroid Build Coastguard Worker                                         const TargetRegisterInfo *TRI) const {
211*9880d681SAndroid Build Coastguard Worker   if (CSI.empty())
212*9880d681SAndroid Build Coastguard Worker     return false;
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
215*9880d681SAndroid Build Coastguard Worker   if (MI != MBB.end()) DL = MI->getDebugLoc();
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
218*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CSI.size(); i != e; ++i)
221*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg());
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker   return true;
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const226*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr(
227*9880d681SAndroid Build Coastguard Worker     MachineFunction &MF, MachineBasicBlock &MBB,
228*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator I) const {
229*9880d681SAndroid Build Coastguard Worker   const MSP430InstrInfo &TII =
230*9880d681SAndroid Build Coastguard Worker       *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo());
231*9880d681SAndroid Build Coastguard Worker   unsigned StackAlign = getStackAlignment();
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker   if (!hasReservedCallFrame(MF)) {
234*9880d681SAndroid Build Coastguard Worker     // If the stack pointer can be changed after prologue, turn the
235*9880d681SAndroid Build Coastguard Worker     // adjcallstackup instruction into a 'sub SP, <amt>' and the
236*9880d681SAndroid Build Coastguard Worker     // adjcallstackdown instruction into 'add SP, <amt>'
237*9880d681SAndroid Build Coastguard Worker     // TODO: consider using push / pop instead of sub + store / add
238*9880d681SAndroid Build Coastguard Worker     MachineInstr &Old = *I;
239*9880d681SAndroid Build Coastguard Worker     uint64_t Amount = Old.getOperand(0).getImm();
240*9880d681SAndroid Build Coastguard Worker     if (Amount != 0) {
241*9880d681SAndroid Build Coastguard Worker       // We need to keep the stack aligned properly.  To do this, we round the
242*9880d681SAndroid Build Coastguard Worker       // amount of space needed for the outgoing arguments up to the next
243*9880d681SAndroid Build Coastguard Worker       // alignment boundary.
244*9880d681SAndroid Build Coastguard Worker       Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
245*9880d681SAndroid Build Coastguard Worker 
246*9880d681SAndroid Build Coastguard Worker       MachineInstr *New = nullptr;
247*9880d681SAndroid Build Coastguard Worker       if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) {
248*9880d681SAndroid Build Coastguard Worker         New =
249*9880d681SAndroid Build Coastguard Worker             BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
250*9880d681SAndroid Build Coastguard Worker                 .addReg(MSP430::SP)
251*9880d681SAndroid Build Coastguard Worker                 .addImm(Amount);
252*9880d681SAndroid Build Coastguard Worker       } else {
253*9880d681SAndroid Build Coastguard Worker         assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode());
254*9880d681SAndroid Build Coastguard Worker         // factor out the amount the callee already popped.
255*9880d681SAndroid Build Coastguard Worker         uint64_t CalleeAmt = Old.getOperand(1).getImm();
256*9880d681SAndroid Build Coastguard Worker         Amount -= CalleeAmt;
257*9880d681SAndroid Build Coastguard Worker         if (Amount)
258*9880d681SAndroid Build Coastguard Worker           New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri),
259*9880d681SAndroid Build Coastguard Worker                         MSP430::SP)
260*9880d681SAndroid Build Coastguard Worker                     .addReg(MSP430::SP)
261*9880d681SAndroid Build Coastguard Worker                     .addImm(Amount);
262*9880d681SAndroid Build Coastguard Worker       }
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker       if (New) {
265*9880d681SAndroid Build Coastguard Worker         // The SRW implicit def is dead.
266*9880d681SAndroid Build Coastguard Worker         New->getOperand(3).setIsDead();
267*9880d681SAndroid Build Coastguard Worker 
268*9880d681SAndroid Build Coastguard Worker         // Replace the pseudo instruction with a new instruction...
269*9880d681SAndroid Build Coastguard Worker         MBB.insert(I, New);
270*9880d681SAndroid Build Coastguard Worker       }
271*9880d681SAndroid Build Coastguard Worker     }
272*9880d681SAndroid Build Coastguard Worker   } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
273*9880d681SAndroid Build Coastguard Worker     // If we are performing frame pointer elimination and if the callee pops
274*9880d681SAndroid Build Coastguard Worker     // something off the stack pointer, add it back.
275*9880d681SAndroid Build Coastguard Worker     if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
276*9880d681SAndroid Build Coastguard Worker       MachineInstr &Old = *I;
277*9880d681SAndroid Build Coastguard Worker       MachineInstr *New =
278*9880d681SAndroid Build Coastguard Worker           BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP)
279*9880d681SAndroid Build Coastguard Worker               .addReg(MSP430::SP)
280*9880d681SAndroid Build Coastguard Worker               .addImm(CalleeAmt);
281*9880d681SAndroid Build Coastguard Worker       // The SRW implicit def is dead.
282*9880d681SAndroid Build Coastguard Worker       New->getOperand(3).setIsDead();
283*9880d681SAndroid Build Coastguard Worker 
284*9880d681SAndroid Build Coastguard Worker       MBB.insert(I, New);
285*9880d681SAndroid Build Coastguard Worker     }
286*9880d681SAndroid Build Coastguard Worker   }
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker   return MBB.erase(I);
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker 
291*9880d681SAndroid Build Coastguard Worker void
processFunctionBeforeFrameFinalized(MachineFunction & MF,RegScavenger *) const292*9880d681SAndroid Build Coastguard Worker MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,
293*9880d681SAndroid Build Coastguard Worker                                                          RegScavenger *) const {
294*9880d681SAndroid Build Coastguard Worker   // Create a frame entry for the FP register that must be saved.
295*9880d681SAndroid Build Coastguard Worker   if (hasFP(MF)) {
296*9880d681SAndroid Build Coastguard Worker     int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
297*9880d681SAndroid Build Coastguard Worker     (void)FrameIdx;
298*9880d681SAndroid Build Coastguard Worker     assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
299*9880d681SAndroid Build Coastguard Worker            "Slot for FP register must be last in order to be found!");
300*9880d681SAndroid Build Coastguard Worker   }
301*9880d681SAndroid Build Coastguard Worker }
302