XCoreFrameLowering.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
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 XCore frame information that doesn't fit anywhere else
11// cleanly...
12//
13//===----------------------------------------------------------------------===//
14
15#include "XCoreFrameLowering.h"
16#include "XCore.h"
17#include "XCoreInstrInfo.h"
18#include "XCoreMachineFunctionInfo.h"
19#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineModuleInfo.h"
23#include "llvm/CodeGen/MachineRegisterInfo.h"
24#include "llvm/CodeGen/RegisterScavenging.h"
25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/Function.h"
27#include "llvm/Support/ErrorHandling.h"
28#include "llvm/Target/TargetLowering.h"
29#include "llvm/Target/TargetOptions.h"
30#include <algorithm>    // std::sort
31
32using namespace llvm;
33
34static const unsigned FramePtr = XCore::R10;
35static const int MaxImmU16 = (1<<16) - 1;
36
37// helper functions. FIXME: Eliminate.
38static inline bool isImmU6(unsigned val) {
39  return val < (1 << 6);
40}
41
42static inline bool isImmU16(unsigned val) {
43  return val < (1 << 16);
44}
45
46// Helper structure with compare function for handling stack slots.
47namespace {
48struct StackSlotInfo {
49  int FI;
50  int Offset;
51  unsigned Reg;
52  StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
53};
54}  // end anonymous namespace
55
56static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
57  return a.Offset < b.Offset;
58}
59
60
61static void EmitDefCfaRegister(MachineBasicBlock &MBB,
62                               MachineBasicBlock::iterator MBBI, DebugLoc dl,
63                               const TargetInstrInfo &TII,
64                               MachineModuleInfo *MMI, unsigned DRegNum) {
65  unsigned CFIIndex = MMI->addFrameInst(
66      MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
67  BuildMI(MBB, MBBI, dl, TII.get(XCore::CFI_INSTRUCTION)).addCFIIndex(CFIIndex);
68}
69
70static void EmitDefCfaOffset(MachineBasicBlock &MBB,
71                             MachineBasicBlock::iterator MBBI, DebugLoc dl,
72                             const TargetInstrInfo &TII,
73                             MachineModuleInfo *MMI, int Offset) {
74  unsigned CFIIndex =
75      MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
76  BuildMI(MBB, MBBI, dl, TII.get(XCore::CFI_INSTRUCTION)).addCFIIndex(CFIIndex);
77}
78
79static void EmitCfiOffset(MachineBasicBlock &MBB,
80                          MachineBasicBlock::iterator MBBI, DebugLoc dl,
81                          const TargetInstrInfo &TII, MachineModuleInfo *MMI,
82                          unsigned DRegNum, int Offset) {
83  unsigned CFIIndex = MMI->addFrameInst(
84      MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
85  BuildMI(MBB, MBBI, dl, TII.get(XCore::CFI_INSTRUCTION)).addCFIIndex(CFIIndex);
86}
87
88/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
89/// frame. During these steps, it may be necessary to spill registers.
90/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
91/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
92/// \param OffsetFromTop the spill offset from the top of the frame.
93/// \param [in,out] Adjusted the current SP offset from the top of the frame.
94static void IfNeededExtSP(MachineBasicBlock &MBB,
95                          MachineBasicBlock::iterator MBBI, DebugLoc dl,
96                          const TargetInstrInfo &TII, MachineModuleInfo *MMI,
97                          int OffsetFromTop, int &Adjusted, int FrameSize,
98                          bool emitFrameMoves) {
99  while (OffsetFromTop > Adjusted) {
100    assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
101    int remaining = FrameSize - Adjusted;
102    int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
103    int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
104    BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
105    Adjusted += OpImm;
106    if (emitFrameMoves)
107      EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
108  }
109}
110
111/// The SP register is moved in steps of 'MaxImmU16' towards the top of the
112/// frame. During these steps, it may be necessary to re-load registers.
113/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
114/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
115/// \param OffsetFromTop the spill offset from the top of the frame.
116/// \param [in,out] RemainingAdj the current SP offset from the top of the frame.
117static void IfNeededLDAWSP(MachineBasicBlock &MBB,
118                           MachineBasicBlock::iterator MBBI, DebugLoc dl,
119                           const TargetInstrInfo &TII, int OffsetFromTop,
120                           int &RemainingAdj) {
121  while (OffsetFromTop < RemainingAdj - MaxImmU16) {
122    assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
123    int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
124    int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
125    BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
126    RemainingAdj -= OpImm;
127  }
128}
129
130/// Creates an ordered list of registers that are spilled
131/// during the emitPrologue/emitEpilogue.
132/// Registers are ordered according to their frame offset.
133/// As offsets are negative, the largest offsets will be first.
134static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
135                         MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
136                         bool fetchLR, bool fetchFP) {
137  if (fetchLR) {
138    int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot());
139    SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
140                                      Offset,
141                                      XCore::LR));
142  }
143  if (fetchFP) {
144    int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot());
145    SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
146                                      Offset,
147                                      FramePtr));
148  }
149  std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
150}
151
152/// Creates an ordered list of EH info register 'spills'.
153/// These slots are only used by the unwinder and calls to llvm.eh.return().
154/// Registers are ordered according to their frame offset.
155/// As offsets are negative, the largest offsets will be first.
156static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
157                           MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
158                           const TargetLowering *TL) {
159  assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
160  const int* EHSlot = XFI->getEHSpillSlot();
161  SpillList.push_back(StackSlotInfo(EHSlot[0],
162                                    MFI->getObjectOffset(EHSlot[0]),
163                                    TL->getExceptionPointerRegister()));
164  SpillList.push_back(StackSlotInfo(EHSlot[0],
165                                    MFI->getObjectOffset(EHSlot[1]),
166                                    TL->getExceptionSelectorRegister()));
167  std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
168}
169
170
171static MachineMemOperand *
172getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) {
173  MachineFunction *MF = MBB.getParent();
174  const MachineFrameInfo &MFI = *MF->getFrameInfo();
175  MachineMemOperand *MMO =
176    MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex),
177                             flags, MFI.getObjectSize(FrameIndex),
178                             MFI.getObjectAlignment(FrameIndex));
179  return MMO;
180}
181
182
183/// Restore clobbered registers with their spill slot value.
184/// The SP will be adjusted at the same time, thus the SpillList must be ordered
185/// with the largest (negative) offsets first.
186static void
187RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
188                 DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj,
189                 SmallVectorImpl<StackSlotInfo> &SpillList) {
190  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
191    assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
192    assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
193    int OffsetFromTop = - SpillList[i].Offset/4;
194    IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
195    int Offset = RemainingAdj - OffsetFromTop;
196    int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
197    BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
198      .addImm(Offset)
199      .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
200                                      MachineMemOperand::MOLoad));
201  }
202}
203
204//===----------------------------------------------------------------------===//
205// XCoreFrameLowering:
206//===----------------------------------------------------------------------===//
207
208XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
209  : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
210  // Do nothing
211}
212
213bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
214  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
215         MF.getFrameInfo()->hasVarSizedObjects();
216}
217
218void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
219  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
220  MachineBasicBlock::iterator MBBI = MBB.begin();
221  MachineFrameInfo *MFI = MF.getFrameInfo();
222  MachineModuleInfo *MMI = &MF.getMMI();
223  const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
224  const XCoreInstrInfo &TII =
225    *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
226  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
227  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
228
229  if (MFI->getMaxAlignment() > getStackAlignment())
230    report_fatal_error("emitPrologue unsupported alignment: "
231                       + Twine(MFI->getMaxAlignment()));
232
233  const AttributeSet &PAL = MF.getFunction()->getAttributes();
234  if (PAL.hasAttrSomewhere(Attribute::Nest))
235    BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
236    // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
237
238  // Work out frame sizes.
239  // We will adjust the SP in stages towards the final FrameSize.
240  assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size");
241  const int FrameSize = MFI->getStackSize() / 4;
242  int Adjusted = 0;
243
244  bool saveLR = XFI->hasLRSpillSlot();
245  bool UseENTSP = saveLR && FrameSize
246                  && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
247  if (UseENTSP)
248    saveLR = false;
249  bool FP = hasFP(MF);
250  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
251
252  if (UseENTSP) {
253    // Allocate space on the stack at the same time as saving LR.
254    Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
255    int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
256    MBB.addLiveIn(XCore::LR);
257    MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
258    MIB.addImm(Adjusted);
259    MIB->addRegisterKilled(XCore::LR, MF.getTarget().getRegisterInfo(), true);
260    if (emitFrameMoves) {
261      EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
262      unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
263      EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0);
264    }
265  }
266
267  // If necessary, save LR and FP to the stack, as we EXTSP.
268  SmallVector<StackSlotInfo,2> SpillList;
269  GetSpillList(SpillList, MFI, XFI, saveLR, FP);
270  // We want the nearest (negative) offsets first, so reverse list.
271  std::reverse(SpillList.begin(), SpillList.end());
272  for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
273    assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
274    assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
275    int OffsetFromTop = - SpillList[i].Offset/4;
276    IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize,
277                  emitFrameMoves);
278    int Offset = Adjusted - OffsetFromTop;
279    int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
280    MBB.addLiveIn(SpillList[i].Reg);
281    BuildMI(MBB, MBBI, dl, TII.get(Opcode))
282      .addReg(SpillList[i].Reg, RegState::Kill)
283      .addImm(Offset)
284      .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
285                                      MachineMemOperand::MOStore));
286    if (emitFrameMoves) {
287      unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
288      EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset);
289    }
290  }
291
292  // Complete any remaining Stack adjustment.
293  IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize,
294                emitFrameMoves);
295  assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
296
297  if (FP) {
298    // Set the FP from the SP.
299    BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
300    if (emitFrameMoves)
301      EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI,
302                         MRI->getDwarfRegNum(FramePtr, true));
303  }
304
305  if (emitFrameMoves) {
306    // Frame moves for callee saved.
307    auto SpillLabels = XFI->getSpillLabels();
308    for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
309      MachineBasicBlock::iterator Pos = SpillLabels[I].first;
310      ++Pos;
311      CalleeSavedInfo &CSI = SpillLabels[I].second;
312      int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
313      unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
314      EmitCfiOffset(MBB, Pos, dl, TII, MMI, DRegNum, Offset);
315    }
316    if (XFI->hasEHSpillSlot()) {
317      // The unwinder requires stack slot & CFI offsets for the exception info.
318      // We do not save/spill these registers.
319      SmallVector<StackSlotInfo,2> SpillList;
320      GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering());
321      assert(SpillList.size()==2 && "Unexpected SpillList size");
322      EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
323                    MRI->getDwarfRegNum(SpillList[0].Reg, true),
324                    SpillList[0].Offset);
325      EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
326                    MRI->getDwarfRegNum(SpillList[1].Reg, true),
327                    SpillList[1].Offset);
328    }
329  }
330}
331
332void XCoreFrameLowering::emitEpilogue(MachineFunction &MF,
333                                     MachineBasicBlock &MBB) const {
334  MachineFrameInfo *MFI = MF.getFrameInfo();
335  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
336  const XCoreInstrInfo &TII =
337    *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
338  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
339  DebugLoc dl = MBBI->getDebugLoc();
340  unsigned RetOpcode = MBBI->getOpcode();
341
342  // Work out frame sizes.
343  // We will adjust the SP in stages towards the final FrameSize.
344  int RemainingAdj = MFI->getStackSize();
345  assert(RemainingAdj%4 == 0 && "Misaligned frame size");
346  RemainingAdj /= 4;
347
348  if (RetOpcode == XCore::EH_RETURN) {
349    // 'Restore' the exception info the unwinder has placed into the stack slots.
350    SmallVector<StackSlotInfo,2> SpillList;
351    GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering());
352    RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
353
354    // Return to the landing pad.
355    unsigned EhStackReg = MBBI->getOperand(0).getReg();
356    unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
357    BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
358    BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
359    MBB.erase(MBBI);  // Erase the previous return instruction.
360    return;
361  }
362
363  bool restoreLR = XFI->hasLRSpillSlot();
364  bool UseRETSP = restoreLR && RemainingAdj
365                  && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
366  if (UseRETSP)
367    restoreLR = false;
368  bool FP = hasFP(MF);
369
370  if (FP) // Restore the stack pointer.
371    BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
372
373  // If necessary, restore LR and FP from the stack, as we EXTSP.
374  SmallVector<StackSlotInfo,2> SpillList;
375  GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
376  RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
377
378  if (RemainingAdj) {
379    // Complete all but one of the remaining Stack adjustments.
380    IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
381    if (UseRETSP) {
382      // Fold prologue into return instruction
383      assert(RetOpcode == XCore::RETSP_u6
384             || RetOpcode == XCore::RETSP_lu6);
385      int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
386      MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
387                                  .addImm(RemainingAdj);
388      for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
389        MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
390      MBB.erase(MBBI);  // Erase the previous return instruction.
391    } else {
392      int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
393                                           XCore::LDAWSP_lru6;
394      BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
395      // Don't erase the return instruction.
396    }
397  } // else Don't erase the return instruction.
398}
399
400bool XCoreFrameLowering::
401spillCalleeSavedRegisters(MachineBasicBlock &MBB,
402                          MachineBasicBlock::iterator MI,
403                          const std::vector<CalleeSavedInfo> &CSI,
404                          const TargetRegisterInfo *TRI) const {
405  if (CSI.empty())
406    return true;
407
408  MachineFunction *MF = MBB.getParent();
409  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
410  XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
411  bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
412
413  DebugLoc DL;
414  if (MI != MBB.end())
415    DL = MI->getDebugLoc();
416
417  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
418                                                    it != CSI.end(); ++it) {
419    unsigned Reg = it->getReg();
420    assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
421           "LR & FP are always handled in emitPrologue");
422
423    // Add the callee-saved register as live-in. It's killed at the spill.
424    MBB.addLiveIn(Reg);
425    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
426    TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
427    if (emitFrameMoves) {
428      auto Store = MI;
429      --Store;
430      XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
431    }
432  }
433  return true;
434}
435
436bool XCoreFrameLowering::
437restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
438                            MachineBasicBlock::iterator MI,
439                            const std::vector<CalleeSavedInfo> &CSI,
440                            const TargetRegisterInfo *TRI) const{
441  MachineFunction *MF = MBB.getParent();
442  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
443  bool AtStart = MI == MBB.begin();
444  MachineBasicBlock::iterator BeforeI = MI;
445  if (!AtStart)
446    --BeforeI;
447  for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
448                                                    it != CSI.end(); ++it) {
449    unsigned Reg = it->getReg();
450    assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
451           "LR & FP are always handled in emitEpilogue");
452
453    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
454    TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
455    assert(MI != MBB.begin() &&
456           "loadRegFromStackSlot didn't insert any code!");
457    // Insert in reverse order.  loadRegFromStackSlot can insert multiple
458    // instructions.
459    if (AtStart)
460      MI = MBB.begin();
461    else {
462      MI = BeforeI;
463      ++MI;
464    }
465  }
466  return true;
467}
468
469// This function eliminates ADJCALLSTACKDOWN,
470// ADJCALLSTACKUP pseudo instructions
471void XCoreFrameLowering::
472eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
473                              MachineBasicBlock::iterator I) const {
474  const XCoreInstrInfo &TII =
475    *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
476  if (!hasReservedCallFrame(MF)) {
477    // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
478    // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
479    MachineInstr *Old = I;
480    uint64_t Amount = Old->getOperand(0).getImm();
481    if (Amount != 0) {
482      // We need to keep the stack aligned properly.  To do this, we round the
483      // amount of space needed for the outgoing arguments up to the next
484      // alignment boundary.
485      unsigned Align = getStackAlignment();
486      Amount = (Amount+Align-1)/Align*Align;
487
488      assert(Amount%4 == 0);
489      Amount /= 4;
490
491      bool isU6 = isImmU6(Amount);
492      if (!isU6 && !isImmU16(Amount)) {
493        // FIX could emit multiple instructions in this case.
494#ifndef NDEBUG
495        errs() << "eliminateCallFramePseudoInstr size too big: "
496               << Amount << "\n";
497#endif
498        llvm_unreachable(0);
499      }
500
501      MachineInstr *New;
502      if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
503        int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
504        New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
505          .addImm(Amount);
506      } else {
507        assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
508        int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
509        New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
510          .addImm(Amount);
511      }
512
513      // Replace the pseudo instruction with a new instruction...
514      MBB.insert(I, New);
515    }
516  }
517
518  MBB.erase(I);
519}
520
521void XCoreFrameLowering::
522processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
523                                     RegScavenger *RS) const {
524  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
525
526  bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
527
528  if (!LRUsed && !MF.getFunction()->isVarArg() &&
529      MF.getFrameInfo()->estimateStackSize(MF))
530    // If we need to extend the stack it is more efficient to use entsp / retsp.
531    // We force the LR to be saved so these instructions are used.
532    LRUsed = true;
533
534  if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
535    // The unwinder expects to find spill slots for the exception info regs R0
536    // & R1. These are used during llvm.eh.return() to 'restore' the exception
537    // info. N.B. we do not spill or restore R0, R1 during normal operation.
538    XFI->createEHSpillSlot(MF);
539    // As we will  have a stack, we force the LR to be saved.
540    LRUsed = true;
541  }
542
543  if (LRUsed) {
544    // We will handle the LR in the prologue/epilogue
545    // and allocate space on the stack ourselves.
546    MF.getRegInfo().setPhysRegUnused(XCore::LR);
547    XFI->createLRSpillSlot(MF);
548  }
549
550  if (hasFP(MF))
551    // A callee save register is used to hold the FP.
552    // This needs saving / restoring in the epilogue / prologue.
553    XFI->createFPSpillSlot(MF);
554}
555
556void XCoreFrameLowering::
557processFunctionBeforeFrameFinalized(MachineFunction &MF,
558                                    RegScavenger *RS) const {
559  assert(RS && "requiresRegisterScavenging failed");
560  MachineFrameInfo *MFI = MF.getFrameInfo();
561  const TargetRegisterClass *RC = &XCore::GRRegsRegClass;
562  XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
563  // Reserve slots close to SP or frame pointer for Scavenging spills.
564  // When using SP for small frames, we don't need any scratch registers.
565  // When using SP for large frames, we may need 2 scratch registers.
566  // When using FP, for large or small frames, we may need 1 scratch register.
567  if (XFI->isLargeFrame(MF) || hasFP(MF))
568    RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
569                                                       RC->getAlignment(),
570                                                       false));
571  if (XFI->isLargeFrame(MF) && !hasFP(MF))
572    RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
573                                                       RC->getAlignment(),
574                                                       false));
575}
576