82cd92d5685ca0dff5d533f51c0b2d984b291e44
[oota-llvm.git] / lib / Target / XCore / XCoreRegisterInfo.cpp
1 //===- XCoreRegisterInfo.cpp - XCore Register Information -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the XCore implementation of the MRegisterInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "XCoreRegisterInfo.h"
15 #include "XCoreMachineFunctionInfo.h"
16 #include "XCore.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineLocation.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/RegisterScavenging.h"
24 #include "llvm/Target/TargetFrameInfo.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/Target/TargetInstrInfo.h"
28 #include "llvm/Type.h"
29 #include "llvm/Function.h"
30 #include "llvm/ADT/BitVector.h"
31 #include "llvm/ADT/STLExtras.h"
32 #include "llvm/Support/Debug.h"
33
34 using namespace llvm;
35
36 XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii)
37   : XCoreGenRegisterInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP),
38     TII(tii) {
39 }
40
41 // helper functions
42 static inline bool isImmUs(unsigned val) {
43   return val <= 11;
44 }
45
46 static inline bool isImmU6(unsigned val) {
47   return val < (1 << 6);
48 }
49
50 static inline bool isImmU16(unsigned val) {
51   return val < (1 << 16);
52 }
53
54 static const unsigned XCore_ArgRegs[] = {
55   XCore::R0, XCore::R1, XCore::R2, XCore::R3
56 };
57
58 const unsigned * XCoreRegisterInfo::getArgRegs(const MachineFunction *MF)
59 {
60   return XCore_ArgRegs;
61 }
62
63 unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF)
64 {
65   return array_lengthof(XCore_ArgRegs);
66 }
67
68 bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF)
69 {
70   const MachineFrameInfo *MFI = MF.getFrameInfo();
71   MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
72   return (MMI && MMI->hasDebugInfo()) ||
73           !MF.getFunction()->doesNotThrow() ||
74           UnwindTablesMandatory;
75 }
76
77 const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
78                                                                          const {
79   static const unsigned CalleeSavedRegs[] = {
80     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
81     XCore::R8, XCore::R9, XCore::R10, XCore::LR,
82     0
83   };
84   return CalleeSavedRegs;
85 }
86
87 const TargetRegisterClass* const*
88 XCoreRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
89   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
90     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
91     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
92     XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass,
93     XCore::GRRegsRegisterClass, XCore::RRegsRegisterClass,
94     0
95   };
96   return CalleeSavedRegClasses;
97 }
98
99 BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
100   BitVector Reserved(getNumRegs());
101   Reserved.set(XCore::CP);
102   Reserved.set(XCore::DP);
103   Reserved.set(XCore::SP);
104   Reserved.set(XCore::LR);
105   if (hasFP(MF)) {
106     Reserved.set(XCore::R10);
107   }
108   return Reserved;
109 }
110
111 bool
112 XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
113   // TODO can we estimate stack size?
114   return hasFP(MF);
115 }
116
117 bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const {
118   return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
119 }
120
121 // This function eliminates ADJCALLSTACKDOWN,
122 // ADJCALLSTACKUP pseudo instructions
123 void XCoreRegisterInfo::
124 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
125                               MachineBasicBlock::iterator I) const {
126   if (!hasReservedCallFrame(MF)) {
127     // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
128     // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
129     MachineInstr *Old = I;
130     uint64_t Amount = Old->getOperand(0).getImm();
131     if (Amount != 0) {
132       // We need to keep the stack aligned properly.  To do this, we round the
133       // amount of space needed for the outgoing arguments up to the next
134       // alignment boundary.
135       unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
136       Amount = (Amount+Align-1)/Align*Align;
137
138       assert(Amount%4 == 0);
139       Amount /= 4;
140       
141       bool isU6 = isImmU6(Amount);
142       
143       if (!isU6 && !isImmU16(Amount)) {
144         // FIX could emit multiple instructions in this case.
145         cerr << "eliminateCallFramePseudoInstr size too big: "
146              << Amount << "\n";
147         abort();
148       }
149
150       MachineInstr *New;
151       if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
152         int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
153         New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
154           .addImm(Amount);
155       } else {
156         assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
157         int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
158         New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
159           .addImm(Amount);
160       }
161
162       // Replace the pseudo instruction with a new instruction...
163       MBB.insert(I, New);
164     }
165   }
166   
167   MBB.erase(I);
168 }
169
170 void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
171                                             int SPAdj, RegScavenger *RS) const {
172   assert(SPAdj == 0 && "Unexpected");
173   MachineInstr &MI = *II;
174   DebugLoc dl = MI.getDebugLoc();
175   unsigned i = 0;
176
177   while (!MI.getOperand(i).isFI()) {
178     ++i;
179     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
180   }
181
182   MachineOperand &FrameOp = MI.getOperand(i);
183   int FrameIndex = FrameOp.getIndex();
184
185   MachineFunction &MF = *MI.getParent()->getParent();
186   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
187   int StackSize = MF.getFrameInfo()->getStackSize();
188
189   #ifndef NDEBUG
190   DOUT << "\nFunction         : " << MF.getFunction()->getName() << "\n";
191   DOUT << "<--------->\n";
192   MI.print(DOUT);
193   DOUT << "FrameIndex         : " << FrameIndex << "\n";
194   DOUT << "FrameOffset        : " << Offset << "\n";
195   DOUT << "StackSize          : " << StackSize << "\n";
196   #endif
197
198   Offset += StackSize;
199   
200   // fold constant into offset.
201   Offset += MI.getOperand(i + 1).getImm();
202   MI.getOperand(i + 1).ChangeToImmediate(0);
203   
204   assert(Offset%4 == 0 && "Misaligned stack offset");
205
206   #ifndef NDEBUG
207   DOUT << "Offset             : " << Offset << "\n";
208   DOUT << "<--------->\n";
209   #endif
210   
211   Offset/=4;
212   
213   bool FP = hasFP(MF);
214   
215   unsigned Reg = MI.getOperand(0).getReg();
216   bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill();
217
218   assert(XCore::GRRegsRegisterClass->contains(Reg) &&
219          "Unexpected register operand");
220   
221   MachineBasicBlock &MBB = *MI.getParent();
222   
223   if (FP) {
224     bool isUs = isImmUs(Offset);
225     unsigned FramePtr = XCore::R10;
226     
227     MachineInstr *New = 0;
228     if (!isUs) {
229       if (!RS) {
230         cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n";
231         abort();
232       }
233       unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II,
234                                                  SPAdj);
235       loadConstant(MBB, II, ScratchReg, Offset, dl);
236       switch (MI.getOpcode()) {
237       case XCore::LDWFI:
238         New = BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
239               .addReg(FramePtr)
240               .addReg(ScratchReg, RegState::Kill);
241         break;
242       case XCore::STWFI:
243         New = BuildMI(MBB, II, dl, TII.get(XCore::STW_3r))
244               .addReg(Reg, getKillRegState(isKill))
245               .addReg(FramePtr)
246               .addReg(ScratchReg, RegState::Kill);
247         break;
248       case XCore::LDAWFI:
249         New = BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
250               .addReg(FramePtr)
251               .addReg(ScratchReg, RegState::Kill);
252         break;
253       default:
254         assert(0 && "Unexpected Opcode\n");
255       }
256     } else {
257       switch (MI.getOpcode()) {
258       case XCore::LDWFI:
259         New = BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
260               .addReg(FramePtr)
261               .addImm(Offset);
262         break;
263       case XCore::STWFI:
264         New = BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
265               .addReg(Reg, getKillRegState(isKill))
266               .addReg(FramePtr)
267               .addImm(Offset);
268         break;
269       case XCore::LDAWFI:
270         New = BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
271               .addReg(FramePtr)
272               .addImm(Offset);
273         break;
274       default:
275         assert(0 && "Unexpected Opcode\n");
276       }
277     }
278   } else {
279     bool isU6 = isImmU6(Offset);
280     if (!isU6 && !isImmU16(Offset)) {
281       // FIXME could make this work for LDWSP, LDAWSP.
282       cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n";
283       abort();
284     }
285
286     switch (MI.getOpcode()) {
287     int NewOpcode;
288     case XCore::LDWFI:
289       NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
290       BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
291             .addImm(Offset);
292       break;
293     case XCore::STWFI:
294       NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
295       BuildMI(MBB, II, dl, TII.get(NewOpcode))
296             .addReg(Reg, getKillRegState(isKill))
297             .addImm(Offset);
298       break;
299     case XCore::LDAWFI:
300       NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
301       BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
302             .addImm(Offset);
303       break;
304     default:
305       assert(0 && "Unexpected Opcode\n");
306     }
307   }
308   // Erase old instruction.
309   MBB.erase(II);
310 }
311
312 void
313 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
314                                                       RegScavenger *RS) const {
315   MachineFrameInfo *MFI = MF.getFrameInfo();
316   bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
317   const TargetRegisterClass *RC = XCore::GRRegsRegisterClass;
318   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
319   if (LRUsed) {
320     MF.getRegInfo().setPhysRegUnused(XCore::LR);
321     
322     bool isVarArg = MF.getFunction()->isVarArg();
323     int FrameIdx;
324     if (! isVarArg) {
325       // A fixed offset of 0 allows us to save / restore LR using entsp / retsp.
326       FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0);
327     } else {
328       FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
329     }
330     XFI->setUsesLR(FrameIdx);
331     XFI->setLRSpillSlot(FrameIdx);
332   }
333   if (requiresRegisterScavenging(MF)) {
334     // Reserve a slot close to SP or frame pointer.
335     RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
336                                                 RC->getAlignment()));
337   }
338   if (hasFP(MF)) {
339     // A callee save register is used to hold the FP.
340     // This needs saving / restoring in the epilogue / prologue.
341     XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(),
342                         RC->getAlignment()));
343   }
344 }
345
346 void XCoreRegisterInfo::
347 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
348   
349 }
350
351 void XCoreRegisterInfo::
352 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
353             unsigned DstReg, int64_t Value, DebugLoc dl) const {
354   // TODO use mkmsk if possible.
355   if (!isImmU16(Value)) {
356     // TODO use constant pool.
357     cerr << "loadConstant value too big " << Value << "\n";
358     abort();
359   }
360   int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
361   BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value);
362 }
363
364 void XCoreRegisterInfo::
365 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
366                   unsigned SrcReg, int Offset, DebugLoc dl) const {
367   assert(Offset%4 == 0 && "Misaligned stack offset");
368   Offset/=4;
369   bool isU6 = isImmU6(Offset);
370   if (!isU6 && !isImmU16(Offset)) {
371     cerr << "storeToStack offset too big " << Offset << "\n";
372     abort();
373   }
374   int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
375   BuildMI(MBB, I, dl, TII.get(Opcode))
376     .addReg(SrcReg)
377     .addImm(Offset);
378 }
379
380 void XCoreRegisterInfo::
381 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
382                   unsigned DstReg, int Offset, DebugLoc dl) const {
383   assert(Offset%4 == 0 && "Misaligned stack offset");
384   Offset/=4;
385   bool isU6 = isImmU6(Offset);
386   if (!isU6 && !isImmU16(Offset)) {
387     cerr << "loadFromStack offset too big " << Offset << "\n";
388     abort();
389   }
390   int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
391   BuildMI(MBB, I, dl, TII.get(Opcode), DstReg)
392     .addImm(Offset);
393 }
394
395 void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
396   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
397   MachineBasicBlock::iterator MBBI = MBB.begin();
398   MachineFrameInfo *MFI = MF.getFrameInfo();
399   MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
400   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
401   DebugLoc dl = (MBBI != MBB.end() ?
402                  MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
403
404   bool FP = hasFP(MF);
405
406   // Work out frame sizes.
407   int FrameSize = MFI->getStackSize();
408
409   assert(FrameSize%4 == 0 && "Misaligned frame size");
410   
411   FrameSize/=4;
412   
413   bool isU6 = isImmU6(FrameSize);
414
415   if (!isU6 && !isImmU16(FrameSize)) {
416     // FIXME could emit multiple instructions.
417     cerr << "emitPrologue Frame size too big: " << FrameSize << "\n";
418     abort();
419   }
420   bool emitFrameMoves = needsFrameMoves(MF);
421
422   // Do we need to allocate space on the stack?
423   if (FrameSize) {
424     bool saveLR = XFI->getUsesLR();
425     bool LRSavedOnEntry = false;
426     int Opcode;
427     if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) {
428       Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
429       MBB.addLiveIn(XCore::LR);
430       saveLR = false;
431       LRSavedOnEntry = true;
432     } else {
433       Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
434     }
435     BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
436     
437     if (emitFrameMoves) {
438       std::vector<MachineMove> &Moves = MMI->getFrameMoves();
439       
440       // Show update of SP.
441       unsigned FrameLabelId = MMI->NextLabelID();
442       BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
443       
444       MachineLocation SPDst(MachineLocation::VirtualFP);
445       MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4);
446       Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
447       
448       if (LRSavedOnEntry) {
449         MachineLocation CSDst(MachineLocation::VirtualFP, 0);
450         MachineLocation CSSrc(XCore::LR);
451         Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
452       }
453     }
454     if (saveLR) {
455       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
456       storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl);
457       MBB.addLiveIn(XCore::LR);
458       
459       if (emitFrameMoves) {
460         unsigned SaveLRLabelId = MMI->NextLabelID();
461         BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId);
462         MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset);
463         MachineLocation CSSrc(XCore::LR);
464         MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId,
465                                                    CSDst, CSSrc));
466       }
467     }
468   }
469   
470   if (FP) {
471     // Save R10 to the stack.
472     int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
473     storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl);
474     // R10 is live-in. It is killed at the spill.
475     MBB.addLiveIn(XCore::R10);
476     if (emitFrameMoves) {
477       unsigned SaveR10LabelId = MMI->NextLabelID();
478       BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId);
479       MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset);
480       MachineLocation CSSrc(XCore::R10);
481       MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId,
482                                                  CSDst, CSSrc));
483     }
484     // Set the FP from the SP.
485     unsigned FramePtr = XCore::R10;
486     BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr)
487       .addImm(0);
488     if (emitFrameMoves) {
489       // Show FP is now valid.
490       unsigned FrameLabelId = MMI->NextLabelID();
491       BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
492       MachineLocation SPDst(FramePtr);
493       MachineLocation SPSrc(MachineLocation::VirtualFP);
494       MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
495     }
496   }
497   
498   if (emitFrameMoves) {
499     // Frame moves for callee saved.
500     std::vector<MachineMove> &Moves = MMI->getFrameMoves();
501     std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels =
502         XFI->getSpillLabels();
503     for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
504       unsigned SpillLabel = SpillLabels[I].first;
505       CalleeSavedInfo &CSI = SpillLabels[I].second;
506       int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
507       unsigned Reg = CSI.getReg();
508       MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
509       MachineLocation CSSrc(Reg);
510       Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc));
511     }
512   }
513 }
514
515 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF,
516                                      MachineBasicBlock &MBB) const {
517   MachineFrameInfo *MFI            = MF.getFrameInfo();
518   MachineBasicBlock::iterator MBBI = prior(MBB.end());
519   DebugLoc dl = MBBI->getDebugLoc();
520   
521   bool FP = hasFP(MF);
522   
523   if (FP) {
524     // Restore the stack pointer.
525     unsigned FramePtr = XCore::R10;
526     BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r))
527       .addReg(FramePtr);
528   }
529
530   // Work out frame sizes.
531   int FrameSize = MFI->getStackSize();
532
533   assert(FrameSize%4 == 0 && "Misaligned frame size");
534
535   FrameSize/=4;
536   
537   bool isU6 = isImmU6(FrameSize);
538
539   if (!isU6 && !isImmU16(FrameSize)) {
540     // FIXME could emit multiple instructions.
541     cerr << "emitEpilogue Frame size too big: " << FrameSize << "\n";
542     abort();
543   }
544
545   if (FrameSize) {
546     XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
547     
548     if (FP) {
549       // Restore R10
550       int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
551       FPSpillOffset += FrameSize*4;
552       loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl);
553     }
554     bool restoreLR = XFI->getUsesLR();
555     if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) {
556       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
557       LRSpillOffset += FrameSize*4;
558       loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl);
559       restoreLR = false;
560     }
561     if (restoreLR) {
562       // Fold prologue into return instruction
563       assert(MBBI->getOpcode() == XCore::RETSP_u6
564         || MBBI->getOpcode() == XCore::RETSP_lu6);
565       int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
566       BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
567       MBB.erase(MBBI);
568     } else {
569       int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
570       BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize);
571     }
572   }
573 }
574
575 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
576   return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
577 }
578
579 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const {
580   bool FP = hasFP(MF);
581   
582   return FP ? XCore::R10 : XCore::SP;
583 }
584
585 unsigned XCoreRegisterInfo::getRARegister() const {
586   return XCore::LR;
587 }
588
589 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves)
590                                                                          const {
591   // Initial state of the frame pointer is SP.
592   MachineLocation Dst(MachineLocation::VirtualFP);
593   MachineLocation Src(XCore::SP, 0);
594   Moves.push_back(MachineMove(0, Dst, Src));
595 }
596
597 #include "XCoreGenRegisterInfo.inc"
598