LLVM API Documentation

XCoreRegisterInfo.cpp

Go to the documentation of this file.
00001 //===- XCoreRegisterInfo.cpp - XCore Register Information -------*- C++ -*-===//
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 the XCore implementation of the MRegisterInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "XCoreRegisterInfo.h"
00015 #include "XCoreMachineFunctionInfo.h"
00016 #include "XCore.h"
00017 #include "llvm/CodeGen/MachineInstrBuilder.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineLocation.h"
00021 #include "llvm/CodeGen/MachineModuleInfo.h"
00022 #include "llvm/CodeGen/MachineRegisterInfo.h"
00023 #include "llvm/CodeGen/RegisterScavenging.h"
00024 #include "llvm/Target/TargetFrameInfo.h"
00025 #include "llvm/Target/TargetMachine.h"
00026 #include "llvm/Target/TargetOptions.h"
00027 #include "llvm/Target/TargetInstrInfo.h"
00028 #include "llvm/Type.h"
00029 #include "llvm/Function.h"
00030 #include "llvm/ADT/BitVector.h"
00031 #include "llvm/ADT/STLExtras.h"
00032 #include "llvm/Support/Debug.h"
00033 
00034 using namespace llvm;
00035 
00036 XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii)
00037   : XCoreGenRegisterInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP),
00038     TII(tii) {
00039 }
00040 
00041 // helper functions
00042 static inline bool isImmUs(unsigned val) {
00043   return val <= 11;
00044 }
00045 
00046 static inline bool isImmU6(unsigned val) {
00047   return val < (1 << 6);
00048 }
00049 
00050 static inline bool isImmU16(unsigned val) {
00051   return val < (1 << 16);
00052 }
00053 
00054 static const unsigned XCore_ArgRegs[] = {
00055   XCore::R0, XCore::R1, XCore::R2, XCore::R3
00056 };
00057 
00058 const unsigned * XCoreRegisterInfo::getArgRegs(const MachineFunction *MF)
00059 {
00060   return XCore_ArgRegs;
00061 }
00062 
00063 unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF)
00064 {
00065   return array_lengthof(XCore_ArgRegs);
00066 }
00067 
00068 bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF)
00069 {
00070   const MachineFrameInfo *MFI = MF.getFrameInfo();
00071   MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
00072   return (MMI && MMI->hasDebugInfo()) ||
00073           !MF.getFunction()->doesNotThrow() ||
00074           UnwindTablesMandatory;
00075 }
00076 
00077 const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
00078                                                                          const {
00079   static const unsigned CalleeSavedRegs[] = {
00080     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
00081     XCore::R8, XCore::R9, XCore::R10, XCore::LR,
00082     0
00083   };
00084   return CalleeSavedRegs;
00085 }
00086 
00087 const TargetRegisterClass* const*
00088 XCoreRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
00089   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
00090     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
00091     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
00092     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
00093     XCore::GRRegsRegisterClass, XCore::RRegsRegisterClass,
00094     0
00095   };
00096   return CalleeSavedRegClasses;
00097 }
00098 
00099 BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
00100   BitVector Reserved(getNumRegs());
00101   Reserved.set(XCore::CP);
00102   Reserved.set(XCore::DP);
00103   Reserved.set(XCore::SP);
00104   Reserved.set(XCore::LR);
00105   if (hasFP(MF)) {
00106     Reserved.set(XCore::R10);
00107   }
00108   return Reserved;
00109 }
00110 
00111 bool
00112 XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
00113   // TODO can we estimate stack size?
00114   return hasFP(MF);
00115 }
00116 
00117 bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const {
00118   return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
00119 }
00120 
00121 // This function eliminates ADJCALLSTACKDOWN,
00122 // ADJCALLSTACKUP pseudo instructions
00123 void XCoreRegisterInfo::
00124 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00125                               MachineBasicBlock::iterator I) const {
00126   if (!hasReservedCallFrame(MF)) {
00127     // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
00128     // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
00129     MachineInstr *Old = I;
00130     uint64_t Amount = Old->getOperand(0).getImm();
00131     if (Amount != 0) {
00132       // We need to keep the stack aligned properly.  To do this, we round the
00133       // amount of space needed for the outgoing arguments up to the next
00134       // alignment boundary.
00135       unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
00136       Amount = (Amount+Align-1)/Align*Align;
00137 
00138       assert(Amount%4 == 0);
00139       Amount /= 4;
00140       
00141       bool isU6 = isImmU6(Amount);
00142       
00143       if (!isU6 && !isImmU16(Amount)) {
00144         // FIX could emit multiple instructions in this case.
00145         cerr << "eliminateCallFramePseudoInstr size too big: "
00146              << Amount << "\n";
00147         abort();
00148       }
00149 
00150       MachineInstr *New;
00151       if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
00152         int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
00153         New=BuildMI(MF, TII.get(Opcode))
00154           .addImm(Amount);
00155       } else {
00156         assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
00157         int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
00158         New=BuildMI(MF, TII.get(Opcode), XCore::SP)
00159           .addImm(Amount);
00160       }
00161 
00162       // Replace the pseudo instruction with a new instruction...
00163       MBB.insert(I, New);
00164     }
00165   }
00166   
00167   MBB.erase(I);
00168 }
00169 
00170 void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
00171                                             int SPAdj, RegScavenger *RS) const {
00172   assert(SPAdj == 0 && "Unexpected");
00173   MachineInstr &MI = *II;
00174   unsigned i = 0;
00175 
00176   while (!MI.getOperand(i).isFI()) {
00177     ++i;
00178     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
00179   }
00180 
00181   MachineOperand &FrameOp = MI.getOperand(i);
00182   int FrameIndex = FrameOp.getIndex();
00183 
00184   MachineFunction &MF = *MI.getParent()->getParent();
00185   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
00186   int StackSize = MF.getFrameInfo()->getStackSize();
00187 
00188   #ifndef NDEBUG
00189   DOUT << "\nFunction         : " << MF.getFunction()->getName() << "\n";
00190   DOUT << "<--------->\n";
00191   MI.print(DOUT);
00192   DOUT << "FrameIndex         : " << FrameIndex << "\n";
00193   DOUT << "FrameOffset        : " << Offset << "\n";
00194   DOUT << "StackSize          : " << StackSize << "\n";
00195   #endif
00196 
00197   Offset += StackSize;
00198   
00199   // fold constant into offset.
00200   Offset += MI.getOperand(i + 1).getImm();
00201   MI.getOperand(i + 1).ChangeToImmediate(0);
00202   
00203   assert(Offset%4 == 0 && "Misaligned stack offset");
00204 
00205   #ifndef NDEBUG
00206   DOUT << "Offset             : " << Offset << "\n";
00207   DOUT << "<--------->\n";
00208   #endif
00209   
00210   Offset/=4;
00211   
00212   bool FP = hasFP(MF);
00213   
00214   unsigned Reg = MI.getOperand(0).getReg();
00215   bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill();
00216 
00217   assert(XCore::GRRegsRegisterClass->contains(Reg) &&
00218          "Unexpected register operand");
00219   
00220   MachineBasicBlock &MBB = *MI.getParent();
00221   
00222   if (FP) {
00223     bool isUs = isImmUs(Offset);
00224     unsigned FramePtr = XCore::R10;
00225     
00226     MachineInstr *New = 0;
00227     if (!isUs) {
00228       if (!RS) {
00229         cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n";
00230         abort();
00231       }
00232       unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II,
00233                                                  SPAdj);
00234       loadConstant(MBB, II, ScratchReg, Offset);
00235       switch (MI.getOpcode()) {
00236       case XCore::LDWFI:
00237         New = BuildMI(MBB, II, TII.get(XCore::LDW_3r), Reg)
00238               .addReg(FramePtr)
00239               .addReg(ScratchReg, false, false, true);
00240         break;
00241       case XCore::STWFI:
00242         New = BuildMI(MBB, II, TII.get(XCore::STW_3r))
00243               .addReg(Reg, false, false, isKill)
00244               .addReg(FramePtr)
00245               .addReg(ScratchReg, false, false, true);
00246         break;
00247       case XCore::LDAWFI:
00248         New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l3r), Reg)
00249               .addReg(FramePtr)
00250               .addReg(ScratchReg, false, false, true);
00251         break;
00252       default:
00253         assert(0 && "Unexpected Opcode\n");
00254       }
00255     } else {
00256       switch (MI.getOpcode()) {
00257       case XCore::LDWFI:
00258         New = BuildMI(MBB, II, TII.get(XCore::LDW_2rus), Reg)
00259               .addReg(FramePtr)
00260               .addImm(Offset);
00261         break;
00262       case XCore::STWFI:
00263         New = BuildMI(MBB, II, TII.get(XCore::STW_2rus))
00264               .addReg(Reg, false, false, isKill)
00265               .addReg(FramePtr)
00266               .addImm(Offset);
00267         break;
00268       case XCore::LDAWFI:
00269         New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l2rus), Reg)
00270               .addReg(FramePtr)
00271               .addImm(Offset);
00272         break;
00273       default:
00274         assert(0 && "Unexpected Opcode\n");
00275       }
00276     }
00277   } else {
00278     bool isU6 = isImmU6(Offset);
00279     if (!isU6 && !isImmU16(Offset)) {
00280       // FIXME could make this work for LDWSP, LDAWSP.
00281       cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n";
00282       abort();
00283     }
00284 
00285     switch (MI.getOpcode()) {
00286     int NewOpcode;
00287     case XCore::LDWFI:
00288       NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
00289       BuildMI(MBB, II, TII.get(NewOpcode), Reg)
00290             .addImm(Offset);
00291       break;
00292     case XCore::STWFI:
00293       NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
00294       BuildMI(MBB, II, TII.get(NewOpcode))
00295             .addReg(Reg, false, false, isKill)
00296             .addImm(Offset);
00297       break;
00298     case XCore::LDAWFI:
00299       NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
00300       BuildMI(MBB, II, TII.get(NewOpcode), Reg)
00301             .addImm(Offset);
00302       break;
00303     default:
00304       assert(0 && "Unexpected Opcode\n");
00305     }
00306   }
00307   // Erase old instruction.
00308   MBB.erase(II);
00309 }
00310 
00311 void
00312 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
00313                                                       RegScavenger *RS) const {
00314   MachineFrameInfo *MFI = MF.getFrameInfo();
00315   bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
00316   const TargetRegisterClass *RC = XCore::GRRegsRegisterClass;
00317   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00318   if (LRUsed) {
00319     MF.getRegInfo().setPhysRegUnused(XCore::LR);
00320     
00321     bool isVarArg = MF.getFunction()->isVarArg();
00322     int FrameIdx;
00323     if (! isVarArg) {
00324       // A fixed offset of 0 allows us to save / restore LR using entsp / retsp.
00325       FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0);
00326     } else {
00327       FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
00328     }
00329     XFI->setUsesLR(FrameIdx);
00330     XFI->setLRSpillSlot(FrameIdx);
00331   }
00332   if (requiresRegisterScavenging(MF)) {
00333     // Reserve a slot close to SP or frame pointer.
00334     RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
00335                                                 RC->getAlignment()));
00336   }
00337   if (hasFP(MF)) {
00338     // A callee save register is used to hold the FP.
00339     // This needs saving / restoring in the epilogue / prologue.
00340     XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(),
00341                         RC->getAlignment()));
00342   }
00343 }
00344 
00345 void XCoreRegisterInfo::
00346 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
00347   
00348 }
00349 
00350 void XCoreRegisterInfo::
00351 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00352             unsigned DstReg, int64_t Value) const {
00353   // TODO use mkmsk if possible.
00354   if (!isImmU16(Value)) {
00355     // TODO use constant pool.
00356     cerr << "loadConstant value too big " << Value << "\n";
00357     abort();
00358   }
00359   int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
00360   BuildMI(MBB, I, TII.get(Opcode), DstReg).addImm(Value);
00361 }
00362 
00363 void XCoreRegisterInfo::
00364 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00365                   unsigned SrcReg, int Offset) const {
00366   assert(Offset%4 == 0 && "Misaligned stack offset");
00367   Offset/=4;
00368   bool isU6 = isImmU6(Offset);
00369   if (!isU6 && !isImmU16(Offset)) {
00370     cerr << "storeToStack offset too big " << Offset << "\n";
00371     abort();
00372   }
00373   int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
00374   BuildMI(MBB, I, TII.get(Opcode))
00375     .addReg(SrcReg)
00376     .addImm(Offset);
00377 }
00378 
00379 void XCoreRegisterInfo::
00380 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00381                   unsigned DstReg, int Offset) const {
00382   assert(Offset%4 == 0 && "Misaligned stack offset");
00383   Offset/=4;
00384   bool isU6 = isImmU6(Offset);
00385   if (!isU6 && !isImmU16(Offset)) {
00386     cerr << "storeToStack offset too big " << Offset << "\n";
00387     abort();
00388   }
00389   int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
00390   BuildMI(MBB, I, TII.get(Opcode), DstReg)
00391     .addImm(Offset);
00392 }
00393 
00394 void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
00395   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
00396   MachineBasicBlock::iterator MBBI = MBB.begin();
00397   MachineFrameInfo *MFI = MF.getFrameInfo();
00398   MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
00399   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00400 
00401   bool FP = hasFP(MF);
00402 
00403   // Work out frame sizes.
00404   int FrameSize = MFI->getStackSize();
00405 
00406   assert(FrameSize%4 == 0 && "Misaligned frame size");
00407   
00408   FrameSize/=4;
00409   
00410   bool isU6 = isImmU6(FrameSize);
00411 
00412   if (!isU6 && !isImmU16(FrameSize)) {
00413     // FIXME could emit multiple instructions.
00414     cerr << "emitPrologue Frame size too big: " << FrameSize << "\n";
00415     abort();
00416   }
00417   bool emitFrameMoves = needsFrameMoves(MF);
00418 
00419   // Do we need to allocate space on the stack?
00420   if (FrameSize) {
00421     bool saveLR = XFI->getUsesLR();
00422     bool LRSavedOnEntry = false;
00423     int Opcode;
00424     if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) {
00425       Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
00426       MBB.addLiveIn(XCore::LR);
00427       saveLR = false;
00428       LRSavedOnEntry = true;
00429     } else {
00430       Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
00431     }
00432     BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize);
00433     
00434     if (emitFrameMoves) {
00435       std::vector<MachineMove> &Moves = MMI->getFrameMoves();
00436       
00437       // Show update of SP.
00438       unsigned FrameLabelId = MMI->NextLabelID();
00439       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
00440       
00441       MachineLocation SPDst(MachineLocation::VirtualFP);
00442       MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4);
00443       Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
00444       
00445       if (LRSavedOnEntry) {
00446         MachineLocation CSDst(MachineLocation::VirtualFP, 0);
00447         MachineLocation CSSrc(XCore::LR);
00448         Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
00449       }
00450     }
00451     if (saveLR) {
00452       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
00453       storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4);
00454       MBB.addLiveIn(XCore::LR);
00455       
00456       if (emitFrameMoves) {
00457         unsigned SaveLRLabelId = MMI->NextLabelID();
00458         BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId);
00459         MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset);
00460         MachineLocation CSSrc(XCore::LR);
00461         MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId,
00462                                                    CSDst, CSSrc));
00463       }
00464     }
00465   }
00466   
00467   if (FP) {
00468     // Save R10 to the stack.
00469     int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
00470     storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4);
00471     // R10 is live-in. It is killed at the spill.
00472     MBB.addLiveIn(XCore::R10);
00473     if (emitFrameMoves) {
00474       unsigned SaveR10LabelId = MMI->NextLabelID();
00475       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId);
00476       MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset);
00477       MachineLocation CSSrc(XCore::R10);
00478       MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId,
00479                                                  CSDst, CSSrc));
00480     }
00481     // Set the FP from the SP.
00482     unsigned FramePtr = XCore::R10;
00483     BuildMI(MBB, MBBI, TII.get(XCore::LDAWSP_ru6), FramePtr)
00484       .addImm(0);
00485     if (emitFrameMoves) {
00486       // Show FP is now valid.
00487       unsigned FrameLabelId = MMI->NextLabelID();
00488       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
00489       MachineLocation SPDst(FramePtr);
00490       MachineLocation SPSrc(MachineLocation::VirtualFP);
00491       MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
00492     }
00493   }
00494   
00495   if (emitFrameMoves) {
00496     // Frame moves for callee saved.
00497     std::vector<MachineMove> &Moves = MMI->getFrameMoves();
00498     std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels =
00499         XFI->getSpillLabels();
00500     for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
00501       unsigned SpillLabel = SpillLabels[I].first;
00502       CalleeSavedInfo &CSI = SpillLabels[I].second;
00503       int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
00504       unsigned Reg = CSI.getReg();
00505       MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
00506       MachineLocation CSSrc(Reg);
00507       Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc));
00508     }
00509   }
00510 }
00511 
00512 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF,
00513                                      MachineBasicBlock &MBB) const {
00514   MachineFrameInfo *MFI            = MF.getFrameInfo();
00515   MachineBasicBlock::iterator MBBI = prior(MBB.end());
00516   
00517   bool FP = hasFP(MF);
00518   
00519   if (FP) {
00520     // Restore the stack pointer.
00521     unsigned FramePtr = XCore::R10;
00522     BuildMI(MBB, MBBI, TII.get(XCore::SETSP_1r))
00523       .addReg(FramePtr);
00524   }
00525 
00526   // Work out frame sizes.
00527   int FrameSize = MFI->getStackSize();
00528 
00529   assert(FrameSize%4 == 0 && "Misaligned frame size");
00530 
00531   FrameSize/=4;
00532   
00533   bool isU6 = isImmU6(FrameSize);
00534 
00535   if (!isU6 && !isImmU16(FrameSize)) {
00536     // FIXME could emit multiple instructions.
00537     cerr << "emitEpilogue Frame size too big: " << FrameSize << "\n";
00538     abort();
00539   }
00540 
00541   if (FrameSize) {
00542     XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
00543     
00544     if (FP) {
00545       // Restore R10
00546       int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
00547       FPSpillOffset += FrameSize*4;
00548       loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset);
00549     }
00550     bool restoreLR = XFI->getUsesLR();
00551     if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) {
00552       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
00553       LRSpillOffset += FrameSize*4;
00554       loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset);
00555       restoreLR = false;
00556     }
00557     if (restoreLR) {
00558       // Fold prologue into return instruction
00559       assert(MBBI->getOpcode() == XCore::RETSP_u6
00560         || MBBI->getOpcode() == XCore::RETSP_lu6);
00561       int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
00562       BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize);
00563       MBB.erase(MBBI);
00564     } else {
00565       int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
00566       BuildMI(MBB, MBBI, TII.get(Opcode), XCore::SP).addImm(FrameSize);
00567     }
00568   }
00569 }
00570 
00571 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
00572   return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
00573 }
00574 
00575 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const {
00576   bool FP = hasFP(MF);
00577   
00578   return FP ? XCore::R10 : XCore::SP;
00579 }
00580 
00581 unsigned XCoreRegisterInfo::getRARegister() const {
00582   return XCore::LR;
00583 }
00584 
00585 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves)
00586                                                                          const {
00587   // Initial state of the frame pointer is SP.
00588   MachineLocation Dst(MachineLocation::VirtualFP);
00589   MachineLocation Src(XCore::SP, 0);
00590   Moves.push_back(MachineMove(0, Dst, Src));
00591 }
00592 
00593 #include "XCoreGenRegisterInfo.inc"
00594