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