Add XCore backend.
[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, 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, 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   unsigned i = 0;
175
176   while (!MI.getOperand(i).isFI()) {
177     ++i;
178     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
179   }
180
181   MachineOperand &FrameOp = MI.getOperand(i);
182   int FrameIndex = FrameOp.getIndex();
183
184   MachineFunction &MF = *MI.getParent()->getParent();
185   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
186   int StackSize = MF.getFrameInfo()->getStackSize();
187
188   #ifndef NDEBUG
189   DOUT << "\nFunction         : " << MF.getFunction()->getName() << "\n";
190   DOUT << "<--------->\n";
191   MI.print(DOUT);
192   DOUT << "FrameIndex         : " << FrameIndex << "\n";
193   DOUT << "FrameOffset        : " << Offset << "\n";
194   DOUT << "StackSize          : " << StackSize << "\n";
195   #endif
196
197   Offset += StackSize;
198   
199   // fold constant into offset.
200   Offset += MI.getOperand(i + 1).getImm();
201   MI.getOperand(i + 1).ChangeToImmediate(0);
202   
203   assert(Offset%4 == 0 && "Misaligned stack offset");
204
205   #ifndef NDEBUG
206   DOUT << "Offset             : " << Offset << "\n";
207   DOUT << "<--------->\n";
208   #endif
209   
210   Offset/=4;
211   
212   bool FP = hasFP(MF);
213   
214   if (FP) {
215     bool isUs = isImmUs(Offset);
216     MachineBasicBlock &MBB = *MI.getParent();
217     unsigned FramePtr = XCore::R10;
218     unsigned Reg = MI.getOperand(0).getReg();
219     bool isKill = MI.getOperand(0).isKill();
220     
221     if (Reg == XCore::LR) {
222       // The LR should have been save in the prologue.
223       cerr << "saving LR to FP unimplemented\n";
224       abort();
225     }
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);
236       switch (MI.getOpcode()) {
237       case XCore::LDWSP_lru6:
238         New = BuildMI(MBB, II, TII.get(XCore::LDW_3r), Reg)
239               .addReg(FramePtr)
240               .addReg(ScratchReg, false, false, true);
241         break;
242       case XCore::STWSP_lru6:
243         New = BuildMI(MBB, II, TII.get(XCore::STW_3r))
244               .addReg(Reg, false, false, isKill)
245               .addReg(FramePtr)
246               .addReg(ScratchReg, false, false, true);
247         break;
248       case XCore::LDAWSP_lru6:
249         New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l3r), Reg)
250               .addReg(FramePtr)
251               .addReg(ScratchReg, false, false, true);
252         break;
253       default:
254         assert(0 && "Unexpected Opcode\n");
255       }
256     } else {
257       switch (MI.getOpcode()) {
258       case XCore::LDWSP_lru6:
259         New = BuildMI(MBB, II, TII.get(XCore::LDW_2rus), Reg)
260               .addReg(FramePtr)
261               .addImm(Offset);
262         break;
263       case XCore::STWSP_lru6:
264         New = BuildMI(MBB, II, TII.get(XCore::STW_2rus))
265               .addReg(Reg, false, false, isKill)
266               .addReg(FramePtr)
267               .addImm(Offset);
268         break;
269       case XCore::LDAWSP_lru6:
270         New = BuildMI(MBB, II, 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     
279     // Erase old instruction.
280     MBB.erase(II);
281   } else {
282     bool isU6 = isImmU6(Offset);
283     if (!isU6 && !isImmU16(Offset)) {
284       // FIXME could make this work for LDWSP, LDAWSP.
285       cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n";
286       abort();
287     }
288
289     int NewOpcode = MI.getOpcode();
290
291     switch (NewOpcode) {
292     case XCore::LDWSP_lru6:
293       NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
294       break;
295     case XCore::STWSP_lru6:
296       NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
297       break;
298     case XCore::LDAWSP_lru6:
299       NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
300       break;
301     default:
302       assert(0 && "Unexpected Opcode\n");
303     }
304
305     MI.setDesc(TII.get(NewOpcode));
306     FrameOp.ChangeToImmediate(Offset);
307   }
308 }
309
310 void
311 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
312                                                       RegScavenger *RS) const {
313   MachineFrameInfo *MFI = MF.getFrameInfo();
314   bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
315   const TargetRegisterClass *RC = XCore::GRRegsRegisterClass;
316   XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
317   if (LRUsed) {
318     MF.getRegInfo().setPhysRegUnused(XCore::LR);
319     
320     bool isVarArg = MF.getFunction()->isVarArg();
321     int FrameIdx;
322     if (! isVarArg) {
323       // A fixed offset of 0 allows us to save / restore LR using entsp / retsp.
324       FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0);
325     } else {
326       FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
327     }
328     XFI->setUsesLR(FrameIdx);
329     XFI->setLRSpillSlot(FrameIdx);
330   }
331   if (requiresRegisterScavenging(MF)) {
332     // Reserve a slot close to SP or frame pointer.
333     RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
334                                                 RC->getAlignment()));
335   }
336   if (hasFP(MF)) {
337     // A callee save register is used to hold the FP.
338     // This needs saving / restoring in the epilogue / prologue.
339     XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(),
340                         RC->getAlignment()));
341   }
342 }
343
344 void XCoreRegisterInfo::
345 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
346   
347 }
348
349 void XCoreRegisterInfo::
350 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
351             unsigned DstReg, int64_t Value) const {
352   // TODO use mkmsk if possible.
353   if (!isImmU16(Value)) {
354     // TODO use constant pool.
355     cerr << "loadConstant value too big " << Value << "\n";
356     abort();
357   }
358   int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
359   BuildMI(MBB, I, TII.get(Opcode), DstReg).addImm(Value);
360 }
361
362 void XCoreRegisterInfo::
363 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
364                   unsigned SrcReg, int Offset) const {
365   assert(Offset%4 == 0 && "Misaligned stack offset");
366   Offset/=4;
367   bool isU6 = isImmU6(Offset);
368   if (!isU6 && !isImmU16(Offset)) {
369     cerr << "storeToStack offset too big " << Offset << "\n";
370     abort();
371   }
372   int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
373   BuildMI(MBB, I, TII.get(Opcode))
374     .addReg(SrcReg)
375     .addImm(Offset)
376     .addImm(0);
377 }
378
379 void XCoreRegisterInfo::
380 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
381                   unsigned DstReg, int Offset) const {
382   assert(Offset%4 == 0 && "Misaligned stack offset");
383   Offset/=4;
384   bool isU6 = isImmU6(Offset);
385   if (!isU6 && !isImmU16(Offset)) {
386     cerr << "storeToStack offset too big " << Offset << "\n";
387     abort();
388   }
389   int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
390   BuildMI(MBB, I, TII.get(Opcode), DstReg)
391     .addImm(Offset)
392     .addImm(0);
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
402   bool FP = hasFP(MF);
403
404   // Work out frame sizes.
405   int FrameSize = MFI->getStackSize();
406
407   assert(FrameSize%4 == 0 && "Misaligned frame size");
408   
409   FrameSize/=4;
410   
411   bool isU6 = isImmU6(FrameSize);
412
413   if (!isU6 && !isImmU16(FrameSize)) {
414     // FIXME could emit multiple instructions.
415     cerr << "emitPrologue Frame size too big: " << FrameSize << "\n";
416     abort();
417   }
418   bool emitFrameMoves = needsFrameMoves(MF);
419
420   // Do we need to allocate space on the stack?
421   if (FrameSize) {
422     bool saveLR = XFI->getUsesLR();
423     bool LRSavedOnEntry = false;
424     int Opcode;
425     if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) {
426       Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
427       MBB.addLiveIn(XCore::LR);
428       saveLR = false;
429       LRSavedOnEntry = true;
430     } else {
431       Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
432     }
433     BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize);
434     
435     if (emitFrameMoves) {
436       std::vector<MachineMove> &Moves = MMI->getFrameMoves();
437       
438       // Show update of SP.
439       unsigned FrameLabelId = MMI->NextLabelID();
440       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
441       
442       MachineLocation SPDst(MachineLocation::VirtualFP);
443       MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4);
444       Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
445       
446       if (LRSavedOnEntry) {
447         MachineLocation CSDst(MachineLocation::VirtualFP, 0);
448         MachineLocation CSSrc(XCore::LR);
449         Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
450       }
451     }
452     if (saveLR) {
453       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
454       storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4);
455       MBB.addLiveIn(XCore::LR);
456       
457       if (emitFrameMoves) {
458         unsigned SaveLRLabelId = MMI->NextLabelID();
459         BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId);
460         MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset);
461         MachineLocation CSSrc(XCore::LR);
462         MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId,
463                                                    CSDst, CSSrc));
464       }
465     }
466   }
467   
468   if (FP) {
469     // Save R10 to the stack.
470     int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
471     storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4);
472     // R10 is live-in. It is killed at the spill.
473     MBB.addLiveIn(XCore::R10);
474     if (emitFrameMoves) {
475       unsigned SaveR10LabelId = MMI->NextLabelID();
476       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId);
477       MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset);
478       MachineLocation CSSrc(XCore::R10);
479       MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId,
480                                                  CSDst, CSSrc));
481     }
482     // Set the FP from the SP.
483     unsigned FramePtr = XCore::R10;
484     BuildMI(MBB, MBBI, TII.get(XCore::LDAWSP_ru6), FramePtr)
485       .addImm(0)
486       .addImm(0);
487     if (emitFrameMoves) {
488       // Show FP is now valid.
489       unsigned FrameLabelId = MMI->NextLabelID();
490       BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
491       MachineLocation SPDst(FramePtr);
492       MachineLocation SPSrc(MachineLocation::VirtualFP);
493       MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
494     }
495   }
496   
497   if (emitFrameMoves) {
498     // Frame moves for callee saved.
499     std::vector<MachineMove> &Moves = MMI->getFrameMoves();
500     std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels =
501         XFI->getSpillLabels();
502     for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
503       unsigned SpillLabel = SpillLabels[I].first;
504       CalleeSavedInfo &CSI = SpillLabels[I].second;
505       int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
506       unsigned Reg = CSI.getReg();
507       MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
508       MachineLocation CSSrc(Reg);
509       Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc));
510     }
511   }
512 }
513
514 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF,
515                                      MachineBasicBlock &MBB) const {
516   MachineFrameInfo *MFI            = MF.getFrameInfo();
517   MachineBasicBlock::iterator MBBI = prior(MBB.end());
518   
519   bool FP = hasFP(MF);
520   
521   if (FP) {
522     // Restore the stack pointer.
523     unsigned FramePtr = XCore::R10;
524     BuildMI(MBB, MBBI, TII.get(XCore::SETSP_1r))
525       .addReg(FramePtr);
526   }
527
528   // Work out frame sizes.
529   int FrameSize = MFI->getStackSize();
530
531   assert(FrameSize%4 == 0 && "Misaligned frame size");
532
533   FrameSize/=4;
534   
535   bool isU6 = isImmU6(FrameSize);
536
537   if (!isU6 && !isImmU16(FrameSize)) {
538     // FIXME could emit multiple instructions.
539     cerr << "emitEpilogue Frame size too big: " << FrameSize << "\n";
540     abort();
541   }
542
543   if (FrameSize) {
544     XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
545     
546     if (FP) {
547       // Restore R10
548       int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
549       FPSpillOffset += FrameSize*4;
550       loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset);
551     }
552     bool restoreLR = XFI->getUsesLR();
553     if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) {
554       int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
555       LRSpillOffset += FrameSize*4;
556       loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset);
557       restoreLR = false;
558     }
559     if (restoreLR) {
560       // Fold prologue into return instruction
561       assert(MBBI->getOpcode() == XCore::RETSP_u6
562         || MBBI->getOpcode() == XCore::RETSP_lu6);
563       int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
564       BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize);
565       MBB.erase(MBBI);
566     } else {
567       int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
568       BuildMI(MBB, MBBI, TII.get(Opcode), XCore::SP).addImm(FrameSize);
569     }
570   }
571 }
572
573 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
574   return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
575 }
576
577 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const {
578   bool FP = hasFP(MF);
579   
580   return FP ? XCore::R10 : XCore::SP;
581 }
582
583 unsigned XCoreRegisterInfo::getRARegister() const {
584   return XCore::LR;
585 }
586
587 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves)
588                                                                          const {
589   // Initial state of the frame pointer is SP.
590   MachineLocation Dst(MachineLocation::VirtualFP);
591   MachineLocation Src(XCore::SP, 0);
592   Moves.push_back(MachineMove(0, Dst, Src));
593 }
594
595 #include "XCoreGenRegisterInfo.inc"
596