LLVM API Documentation

XCoreFrameLowering.cpp
Go to the documentation of this file.
00001 //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains XCore frame information that doesn't fit anywhere else
00011 // cleanly...
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "XCoreFrameLowering.h"
00016 #include "XCore.h"
00017 #include "XCoreInstrInfo.h"
00018 #include "XCoreMachineFunctionInfo.h"
00019 #include "XCoreSubtarget.h"
00020 #include "llvm/CodeGen/MachineFrameInfo.h"
00021 #include "llvm/CodeGen/MachineFunction.h"
00022 #include "llvm/CodeGen/MachineInstrBuilder.h"
00023 #include "llvm/CodeGen/MachineModuleInfo.h"
00024 #include "llvm/CodeGen/MachineRegisterInfo.h"
00025 #include "llvm/CodeGen/RegisterScavenging.h"
00026 #include "llvm/IR/DataLayout.h"
00027 #include "llvm/IR/Function.h"
00028 #include "llvm/Support/ErrorHandling.h"
00029 #include "llvm/Target/TargetLowering.h"
00030 #include "llvm/Target/TargetOptions.h"
00031 #include <algorithm>    // std::sort
00032 
00033 using namespace llvm;
00034 
00035 static const unsigned FramePtr = XCore::R10;
00036 static const int MaxImmU16 = (1<<16) - 1;
00037 
00038 // helper functions. FIXME: Eliminate.
00039 static inline bool isImmU6(unsigned val) {
00040   return val < (1 << 6);
00041 }
00042 
00043 static inline bool isImmU16(unsigned val) {
00044   return val < (1 << 16);
00045 }
00046 
00047 // Helper structure with compare function for handling stack slots.
00048 namespace {
00049 struct StackSlotInfo {
00050   int FI;
00051   int Offset;
00052   unsigned Reg;
00053   StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
00054 };
00055 }  // end anonymous namespace
00056 
00057 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
00058   return a.Offset < b.Offset;
00059 }
00060 
00061 
00062 static void EmitDefCfaRegister(MachineBasicBlock &MBB,
00063                                MachineBasicBlock::iterator MBBI, DebugLoc dl,
00064                                const TargetInstrInfo &TII,
00065                                MachineModuleInfo *MMI, unsigned DRegNum) {
00066   unsigned CFIIndex = MMI->addFrameInst(
00067       MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
00068   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00069       .addCFIIndex(CFIIndex);
00070 }
00071 
00072 static void EmitDefCfaOffset(MachineBasicBlock &MBB,
00073                              MachineBasicBlock::iterator MBBI, DebugLoc dl,
00074                              const TargetInstrInfo &TII,
00075                              MachineModuleInfo *MMI, int Offset) {
00076   unsigned CFIIndex =
00077       MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
00078   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00079       .addCFIIndex(CFIIndex);
00080 }
00081 
00082 static void EmitCfiOffset(MachineBasicBlock &MBB,
00083                           MachineBasicBlock::iterator MBBI, DebugLoc dl,
00084                           const TargetInstrInfo &TII, MachineModuleInfo *MMI,
00085                           unsigned DRegNum, int Offset) {
00086   unsigned CFIIndex = MMI->addFrameInst(
00087       MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
00088   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00089       .addCFIIndex(CFIIndex);
00090 }
00091 
00092 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
00093 /// frame. During these steps, it may be necessary to spill registers.
00094 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
00095 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
00096 /// \param OffsetFromTop the spill offset from the top of the frame.
00097 /// \param [in,out] Adjusted the current SP offset from the top of the frame.
00098 static void IfNeededExtSP(MachineBasicBlock &MBB,
00099                           MachineBasicBlock::iterator MBBI, DebugLoc dl,
00100                           const TargetInstrInfo &TII, MachineModuleInfo *MMI,
00101                           int OffsetFromTop, int &Adjusted, int FrameSize,
00102                           bool emitFrameMoves) {
00103   while (OffsetFromTop > Adjusted) {
00104     assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
00105     int remaining = FrameSize - Adjusted;
00106     int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
00107     int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
00108     BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
00109     Adjusted += OpImm;
00110     if (emitFrameMoves)
00111       EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
00112   }
00113 }
00114 
00115 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the
00116 /// frame. During these steps, it may be necessary to re-load registers.
00117 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
00118 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
00119 /// \param OffsetFromTop the spill offset from the top of the frame.
00120 /// \param [in,out] RemainingAdj the current SP offset from the top of the
00121 /// frame.
00122 static void IfNeededLDAWSP(MachineBasicBlock &MBB,
00123                            MachineBasicBlock::iterator MBBI, DebugLoc dl,
00124                            const TargetInstrInfo &TII, int OffsetFromTop,
00125                            int &RemainingAdj) {
00126   while (OffsetFromTop < RemainingAdj - MaxImmU16) {
00127     assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
00128     int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
00129     int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
00130     BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
00131     RemainingAdj -= OpImm;
00132   }
00133 }
00134 
00135 /// Creates an ordered list of registers that are spilled
00136 /// during the emitPrologue/emitEpilogue.
00137 /// Registers are ordered according to their frame offset.
00138 /// As offsets are negative, the largest offsets will be first.
00139 static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
00140                          MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
00141                          bool fetchLR, bool fetchFP) {
00142   if (fetchLR) {
00143     int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot());
00144     SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
00145                                       Offset,
00146                                       XCore::LR));
00147   }
00148   if (fetchFP) {
00149     int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot());
00150     SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
00151                                       Offset,
00152                                       FramePtr));
00153   }
00154   std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
00155 }
00156 
00157 /// Creates an ordered list of EH info register 'spills'.
00158 /// These slots are only used by the unwinder and calls to llvm.eh.return().
00159 /// Registers are ordered according to their frame offset.
00160 /// As offsets are negative, the largest offsets will be first.
00161 static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
00162                            MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
00163                            const TargetLowering *TL) {
00164   assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
00165   const int* EHSlot = XFI->getEHSpillSlot();
00166   SpillList.push_back(StackSlotInfo(EHSlot[0],
00167                                     MFI->getObjectOffset(EHSlot[0]),
00168                                     TL->getExceptionPointerRegister()));
00169   SpillList.push_back(StackSlotInfo(EHSlot[0],
00170                                     MFI->getObjectOffset(EHSlot[1]),
00171                                     TL->getExceptionSelectorRegister()));
00172   std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
00173 }
00174 
00175 
00176 static MachineMemOperand *
00177 getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) {
00178   MachineFunction *MF = MBB.getParent();
00179   const MachineFrameInfo &MFI = *MF->getFrameInfo();
00180   MachineMemOperand *MMO =
00181     MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex),
00182                              flags, MFI.getObjectSize(FrameIndex),
00183                              MFI.getObjectAlignment(FrameIndex));
00184   return MMO;
00185 }
00186 
00187 
00188 /// Restore clobbered registers with their spill slot value.
00189 /// The SP will be adjusted at the same time, thus the SpillList must be ordered
00190 /// with the largest (negative) offsets first.
00191 static void
00192 RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
00193                  DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj,
00194                  SmallVectorImpl<StackSlotInfo> &SpillList) {
00195   for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
00196     assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
00197     assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
00198     int OffsetFromTop = - SpillList[i].Offset/4;
00199     IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
00200     int Offset = RemainingAdj - OffsetFromTop;
00201     int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
00202     BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
00203       .addImm(Offset)
00204       .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
00205                                       MachineMemOperand::MOLoad));
00206   }
00207 }
00208 
00209 //===----------------------------------------------------------------------===//
00210 // XCoreFrameLowering:
00211 //===----------------------------------------------------------------------===//
00212 
00213 XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
00214   : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
00215   // Do nothing
00216 }
00217 
00218 bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
00219   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
00220          MF.getFrameInfo()->hasVarSizedObjects();
00221 }
00222 
00223 void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
00224   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
00225   MachineBasicBlock::iterator MBBI = MBB.begin();
00226   MachineFrameInfo *MFI = MF.getFrameInfo();
00227   MachineModuleInfo *MMI = &MF.getMMI();
00228   const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
00229   const XCoreInstrInfo &TII =
00230       *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
00231   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00232   // Debug location must be unknown since the first debug location is used
00233   // to determine the end of the prologue.
00234   DebugLoc dl;
00235 
00236   if (MFI->getMaxAlignment() > getStackAlignment())
00237     report_fatal_error("emitPrologue unsupported alignment: "
00238                        + Twine(MFI->getMaxAlignment()));
00239 
00240   const AttributeSet &PAL = MF.getFunction()->getAttributes();
00241   if (PAL.hasAttrSomewhere(Attribute::Nest))
00242     BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
00243     // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
00244 
00245   // Work out frame sizes.
00246   // We will adjust the SP in stages towards the final FrameSize.
00247   assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size");
00248   const int FrameSize = MFI->getStackSize() / 4;
00249   int Adjusted = 0;
00250 
00251   bool saveLR = XFI->hasLRSpillSlot();
00252   bool UseENTSP = saveLR && FrameSize
00253                   && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
00254   if (UseENTSP)
00255     saveLR = false;
00256   bool FP = hasFP(MF);
00257   bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
00258 
00259   if (UseENTSP) {
00260     // Allocate space on the stack at the same time as saving LR.
00261     Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
00262     int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
00263     MBB.addLiveIn(XCore::LR);
00264     MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
00265     MIB.addImm(Adjusted);
00266     MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
00267                            true);
00268     if (emitFrameMoves) {
00269       EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
00270       unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
00271       EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0);
00272     }
00273   }
00274 
00275   // If necessary, save LR and FP to the stack, as we EXTSP.
00276   SmallVector<StackSlotInfo,2> SpillList;
00277   GetSpillList(SpillList, MFI, XFI, saveLR, FP);
00278   // We want the nearest (negative) offsets first, so reverse list.
00279   std::reverse(SpillList.begin(), SpillList.end());
00280   for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
00281     assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
00282     assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
00283     int OffsetFromTop = - SpillList[i].Offset/4;
00284     IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize,
00285                   emitFrameMoves);
00286     int Offset = Adjusted - OffsetFromTop;
00287     int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
00288     MBB.addLiveIn(SpillList[i].Reg);
00289     BuildMI(MBB, MBBI, dl, TII.get(Opcode))
00290       .addReg(SpillList[i].Reg, RegState::Kill)
00291       .addImm(Offset)
00292       .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
00293                                       MachineMemOperand::MOStore));
00294     if (emitFrameMoves) {
00295       unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
00296       EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset);
00297     }
00298   }
00299 
00300   // Complete any remaining Stack adjustment.
00301   IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize,
00302                 emitFrameMoves);
00303   assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
00304 
00305   if (FP) {
00306     // Set the FP from the SP.
00307     BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
00308     if (emitFrameMoves)
00309       EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI,
00310                          MRI->getDwarfRegNum(FramePtr, true));
00311   }
00312 
00313   if (emitFrameMoves) {
00314     // Frame moves for callee saved.
00315     auto SpillLabels = XFI->getSpillLabels();
00316     for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
00317       MachineBasicBlock::iterator Pos = SpillLabels[I].first;
00318       ++Pos;
00319       CalleeSavedInfo &CSI = SpillLabels[I].second;
00320       int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
00321       unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
00322       EmitCfiOffset(MBB, Pos, dl, TII, MMI, DRegNum, Offset);
00323     }
00324     if (XFI->hasEHSpillSlot()) {
00325       // The unwinder requires stack slot & CFI offsets for the exception info.
00326       // We do not save/spill these registers.
00327       SmallVector<StackSlotInfo,2> SpillList;
00328       GetEHSpillList(SpillList, MFI, XFI,
00329                      MF.getSubtarget().getTargetLowering());
00330       assert(SpillList.size()==2 && "Unexpected SpillList size");
00331       EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
00332                     MRI->getDwarfRegNum(SpillList[0].Reg, true),
00333                     SpillList[0].Offset);
00334       EmitCfiOffset(MBB, MBBI, dl, TII, MMI,
00335                     MRI->getDwarfRegNum(SpillList[1].Reg, true),
00336                     SpillList[1].Offset);
00337     }
00338   }
00339 }
00340 
00341 void XCoreFrameLowering::emitEpilogue(MachineFunction &MF,
00342                                      MachineBasicBlock &MBB) const {
00343   MachineFrameInfo *MFI = MF.getFrameInfo();
00344   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
00345   const XCoreInstrInfo &TII =
00346       *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
00347   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00348   DebugLoc dl = MBBI->getDebugLoc();
00349   unsigned RetOpcode = MBBI->getOpcode();
00350 
00351   // Work out frame sizes.
00352   // We will adjust the SP in stages towards the final FrameSize.
00353   int RemainingAdj = MFI->getStackSize();
00354   assert(RemainingAdj%4 == 0 && "Misaligned frame size");
00355   RemainingAdj /= 4;
00356 
00357   if (RetOpcode == XCore::EH_RETURN) {
00358     // 'Restore' the exception info the unwinder has placed into the stack
00359     // slots.
00360     SmallVector<StackSlotInfo,2> SpillList;
00361     GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering());
00362     RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
00363 
00364     // Return to the landing pad.
00365     unsigned EhStackReg = MBBI->getOperand(0).getReg();
00366     unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
00367     BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
00368     BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
00369     MBB.erase(MBBI);  // Erase the previous return instruction.
00370     return;
00371   }
00372 
00373   bool restoreLR = XFI->hasLRSpillSlot();
00374   bool UseRETSP = restoreLR && RemainingAdj
00375                   && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
00376   if (UseRETSP)
00377     restoreLR = false;
00378   bool FP = hasFP(MF);
00379 
00380   if (FP) // Restore the stack pointer.
00381     BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
00382 
00383   // If necessary, restore LR and FP from the stack, as we EXTSP.
00384   SmallVector<StackSlotInfo,2> SpillList;
00385   GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
00386   RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
00387 
00388   if (RemainingAdj) {
00389     // Complete all but one of the remaining Stack adjustments.
00390     IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
00391     if (UseRETSP) {
00392       // Fold prologue into return instruction
00393       assert(RetOpcode == XCore::RETSP_u6
00394              || RetOpcode == XCore::RETSP_lu6);
00395       int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
00396       MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
00397                                   .addImm(RemainingAdj);
00398       for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
00399         MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
00400       MBB.erase(MBBI);  // Erase the previous return instruction.
00401     } else {
00402       int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
00403                                            XCore::LDAWSP_lru6;
00404       BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
00405       // Don't erase the return instruction.
00406     }
00407   } // else Don't erase the return instruction.
00408 }
00409 
00410 bool XCoreFrameLowering::
00411 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
00412                           MachineBasicBlock::iterator MI,
00413                           const std::vector<CalleeSavedInfo> &CSI,
00414                           const TargetRegisterInfo *TRI) const {
00415   if (CSI.empty())
00416     return true;
00417 
00418   MachineFunction *MF = MBB.getParent();
00419   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
00420   XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
00421   bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
00422 
00423   DebugLoc DL;
00424   if (MI != MBB.end() && !MI->isDebugValue())
00425     DL = MI->getDebugLoc();
00426 
00427   for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
00428                                                     it != CSI.end(); ++it) {
00429     unsigned Reg = it->getReg();
00430     assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
00431            "LR & FP are always handled in emitPrologue");
00432 
00433     // Add the callee-saved register as live-in. It's killed at the spill.
00434     MBB.addLiveIn(Reg);
00435     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
00436     TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
00437     if (emitFrameMoves) {
00438       auto Store = MI;
00439       --Store;
00440       XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
00441     }
00442   }
00443   return true;
00444 }
00445 
00446 bool XCoreFrameLowering::
00447 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
00448                             MachineBasicBlock::iterator MI,
00449                             const std::vector<CalleeSavedInfo> &CSI,
00450                             const TargetRegisterInfo *TRI) const{
00451   MachineFunction *MF = MBB.getParent();
00452   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
00453   bool AtStart = MI == MBB.begin();
00454   MachineBasicBlock::iterator BeforeI = MI;
00455   if (!AtStart)
00456     --BeforeI;
00457   for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
00458                                                     it != CSI.end(); ++it) {
00459     unsigned Reg = it->getReg();
00460     assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
00461            "LR & FP are always handled in emitEpilogue");
00462 
00463     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
00464     TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
00465     assert(MI != MBB.begin() &&
00466            "loadRegFromStackSlot didn't insert any code!");
00467     // Insert in reverse order.  loadRegFromStackSlot can insert multiple
00468     // instructions.
00469     if (AtStart)
00470       MI = MBB.begin();
00471     else {
00472       MI = BeforeI;
00473       ++MI;
00474     }
00475   }
00476   return true;
00477 }
00478 
00479 // This function eliminates ADJCALLSTACKDOWN,
00480 // ADJCALLSTACKUP pseudo instructions
00481 void XCoreFrameLowering::
00482 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00483                               MachineBasicBlock::iterator I) const {
00484   const XCoreInstrInfo &TII =
00485       *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
00486   if (!hasReservedCallFrame(MF)) {
00487     // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
00488     // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
00489     MachineInstr *Old = I;
00490     uint64_t Amount = Old->getOperand(0).getImm();
00491     if (Amount != 0) {
00492       // We need to keep the stack aligned properly.  To do this, we round the
00493       // amount of space needed for the outgoing arguments up to the next
00494       // alignment boundary.
00495       unsigned Align = getStackAlignment();
00496       Amount = (Amount+Align-1)/Align*Align;
00497 
00498       assert(Amount%4 == 0);
00499       Amount /= 4;
00500 
00501       bool isU6 = isImmU6(Amount);
00502       if (!isU6 && !isImmU16(Amount)) {
00503         // FIX could emit multiple instructions in this case.
00504 #ifndef NDEBUG
00505         errs() << "eliminateCallFramePseudoInstr size too big: "
00506                << Amount << "\n";
00507 #endif
00508         llvm_unreachable(nullptr);
00509       }
00510 
00511       MachineInstr *New;
00512       if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
00513         int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
00514         New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
00515           .addImm(Amount);
00516       } else {
00517         assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
00518         int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
00519         New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
00520           .addImm(Amount);
00521       }
00522 
00523       // Replace the pseudo instruction with a new instruction...
00524       MBB.insert(I, New);
00525     }
00526   }
00527 
00528   MBB.erase(I);
00529 }
00530 
00531 void XCoreFrameLowering::
00532 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
00533                                      RegScavenger *RS) const {
00534   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00535 
00536   bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
00537 
00538   if (!LRUsed && !MF.getFunction()->isVarArg() &&
00539       MF.getFrameInfo()->estimateStackSize(MF))
00540     // If we need to extend the stack it is more efficient to use entsp / retsp.
00541     // We force the LR to be saved so these instructions are used.
00542     LRUsed = true;
00543 
00544   if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
00545     // The unwinder expects to find spill slots for the exception info regs R0
00546     // & R1. These are used during llvm.eh.return() to 'restore' the exception
00547     // info. N.B. we do not spill or restore R0, R1 during normal operation.
00548     XFI->createEHSpillSlot(MF);
00549     // As we will  have a stack, we force the LR to be saved.
00550     LRUsed = true;
00551   }
00552 
00553   if (LRUsed) {
00554     // We will handle the LR in the prologue/epilogue
00555     // and allocate space on the stack ourselves.
00556     MF.getRegInfo().setPhysRegUnused(XCore::LR);
00557     XFI->createLRSpillSlot(MF);
00558   }
00559 
00560   if (hasFP(MF))
00561     // A callee save register is used to hold the FP.
00562     // This needs saving / restoring in the epilogue / prologue.
00563     XFI->createFPSpillSlot(MF);
00564 }
00565 
00566 void XCoreFrameLowering::
00567 processFunctionBeforeFrameFinalized(MachineFunction &MF,
00568                                     RegScavenger *RS) const {
00569   assert(RS && "requiresRegisterScavenging failed");
00570   MachineFrameInfo *MFI = MF.getFrameInfo();
00571   const TargetRegisterClass *RC = &XCore::GRRegsRegClass;
00572   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00573   // Reserve slots close to SP or frame pointer for Scavenging spills.
00574   // When using SP for small frames, we don't need any scratch registers.
00575   // When using SP for large frames, we may need 2 scratch registers.
00576   // When using FP, for large or small frames, we may need 1 scratch register.
00577   if (XFI->isLargeFrame(MF) || hasFP(MF))
00578     RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
00579                                                        RC->getAlignment(),
00580                                                        false));
00581   if (XFI->isLargeFrame(MF) && !hasFP(MF))
00582     RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
00583                                                        RC->getAlignment(),
00584                                                        false));
00585 }