1dff0c46cSDimitry Andric //===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file contains the XCore implementation of the MRegisterInfo class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "XCoreRegisterInfo.h"
15f22ef01cSRoman Divacky #include "XCore.h"
1691bc56edSDimitry Andric #include "XCoreInstrInfo.h"
17139f7f9bSDimitry Andric #include "XCoreMachineFunctionInfo.h"
1839d628a0SDimitry Andric #include "XCoreSubtarget.h"
19139f7f9bSDimitry Andric #include "llvm/ADT/BitVector.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
21f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
22139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
23139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
24f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfo.h"
25f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
26f22ef01cSRoman Divacky #include "llvm/CodeGen/RegisterScavenging.h"
27139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
28139f7f9bSDimitry Andric #include "llvm/IR/Type.h"
29f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
30f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
3191bc56edSDimitry Andric #include "llvm/Support/MathExtras.h"
32f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
332cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
34139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
35139f7f9bSDimitry Andric #include "llvm/Target/TargetOptions.h"
36f22ef01cSRoman Divacky 
3791bc56edSDimitry Andric using namespace llvm;
3891bc56edSDimitry Andric 
3991bc56edSDimitry Andric #define DEBUG_TYPE "xcore-reg-info"
4091bc56edSDimitry Andric 
4117a519f9SDimitry Andric #define GET_REGINFO_TARGET_DESC
4217a519f9SDimitry Andric #include "XCoreGenRegisterInfo.inc"
4317a519f9SDimitry Andric 
XCoreRegisterInfo()44f785676fSDimitry Andric XCoreRegisterInfo::XCoreRegisterInfo()
45f785676fSDimitry Andric   : XCoreGenRegisterInfo(XCore::LR) {
46f22ef01cSRoman Divacky }
47f22ef01cSRoman Divacky 
48f22ef01cSRoman Divacky // helper functions
isImmUs(unsigned val)49f22ef01cSRoman Divacky static inline bool isImmUs(unsigned val) {
50f22ef01cSRoman Divacky   return val <= 11;
51f22ef01cSRoman Divacky }
52f22ef01cSRoman Divacky 
isImmU6(unsigned val)53f22ef01cSRoman Divacky static inline bool isImmU6(unsigned val) {
54f22ef01cSRoman Divacky   return val < (1 << 6);
55f22ef01cSRoman Divacky }
56f22ef01cSRoman Divacky 
isImmU16(unsigned val)57f22ef01cSRoman Divacky static inline bool isImmU16(unsigned val) {
58f22ef01cSRoman Divacky   return val < (1 << 16);
59f22ef01cSRoman Divacky }
60f22ef01cSRoman Divacky 
6191bc56edSDimitry Andric 
InsertFPImmInst(MachineBasicBlock::iterator II,const XCoreInstrInfo & TII,unsigned Reg,unsigned FrameReg,int Offset)6291bc56edSDimitry Andric static void InsertFPImmInst(MachineBasicBlock::iterator II,
6391bc56edSDimitry Andric                             const XCoreInstrInfo &TII,
6491bc56edSDimitry Andric                             unsigned Reg, unsigned FrameReg, int Offset ) {
6591bc56edSDimitry Andric   MachineInstr &MI = *II;
6691bc56edSDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
6791bc56edSDimitry Andric   DebugLoc dl = MI.getDebugLoc();
6891bc56edSDimitry Andric 
6991bc56edSDimitry Andric   switch (MI.getOpcode()) {
7091bc56edSDimitry Andric   case XCore::LDWFI:
7191bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
7291bc56edSDimitry Andric           .addReg(FrameReg)
7391bc56edSDimitry Andric           .addImm(Offset)
7491bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
7591bc56edSDimitry Andric     break;
7691bc56edSDimitry Andric   case XCore::STWFI:
7791bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
7891bc56edSDimitry Andric           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
7991bc56edSDimitry Andric           .addReg(FrameReg)
8091bc56edSDimitry Andric           .addImm(Offset)
8191bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
8291bc56edSDimitry Andric     break;
8391bc56edSDimitry Andric   case XCore::LDAWFI:
8491bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
8591bc56edSDimitry Andric           .addReg(FrameReg)
8691bc56edSDimitry Andric           .addImm(Offset);
8791bc56edSDimitry Andric     break;
8891bc56edSDimitry Andric   default:
8991bc56edSDimitry Andric     llvm_unreachable("Unexpected Opcode");
9091bc56edSDimitry Andric   }
9191bc56edSDimitry Andric }
9291bc56edSDimitry Andric 
InsertFPConstInst(MachineBasicBlock::iterator II,const XCoreInstrInfo & TII,unsigned Reg,unsigned FrameReg,int Offset,RegScavenger * RS)9391bc56edSDimitry Andric static void InsertFPConstInst(MachineBasicBlock::iterator II,
9491bc56edSDimitry Andric                               const XCoreInstrInfo &TII,
9591bc56edSDimitry Andric                               unsigned Reg, unsigned FrameReg,
9691bc56edSDimitry Andric                               int Offset, RegScavenger *RS ) {
9791bc56edSDimitry Andric   assert(RS && "requiresRegisterScavenging failed");
9891bc56edSDimitry Andric   MachineInstr &MI = *II;
9991bc56edSDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
10091bc56edSDimitry Andric   DebugLoc dl = MI.getDebugLoc();
10191bc56edSDimitry Andric   unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
10239d628a0SDimitry Andric   RS->setRegUsed(ScratchOffset);
10391bc56edSDimitry Andric   TII.loadImmediate(MBB, II, ScratchOffset, Offset);
10491bc56edSDimitry Andric 
10591bc56edSDimitry Andric   switch (MI.getOpcode()) {
10691bc56edSDimitry Andric   case XCore::LDWFI:
10791bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
10891bc56edSDimitry Andric           .addReg(FrameReg)
10991bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill)
11091bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
11191bc56edSDimitry Andric     break;
11291bc56edSDimitry Andric   case XCore::STWFI:
11391bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
11491bc56edSDimitry Andric           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
11591bc56edSDimitry Andric           .addReg(FrameReg)
11691bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill)
11791bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
11891bc56edSDimitry Andric     break;
11991bc56edSDimitry Andric   case XCore::LDAWFI:
12091bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
12191bc56edSDimitry Andric           .addReg(FrameReg)
12291bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill);
12391bc56edSDimitry Andric     break;
12491bc56edSDimitry Andric   default:
12591bc56edSDimitry Andric     llvm_unreachable("Unexpected Opcode");
12691bc56edSDimitry Andric   }
12791bc56edSDimitry Andric }
12891bc56edSDimitry Andric 
InsertSPImmInst(MachineBasicBlock::iterator II,const XCoreInstrInfo & TII,unsigned Reg,int Offset)12991bc56edSDimitry Andric static void InsertSPImmInst(MachineBasicBlock::iterator II,
13091bc56edSDimitry Andric                             const XCoreInstrInfo &TII,
13191bc56edSDimitry Andric                             unsigned Reg, int Offset) {
13291bc56edSDimitry Andric   MachineInstr &MI = *II;
13391bc56edSDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
13491bc56edSDimitry Andric   DebugLoc dl = MI.getDebugLoc();
13591bc56edSDimitry Andric   bool isU6 = isImmU6(Offset);
13691bc56edSDimitry Andric 
13791bc56edSDimitry Andric   switch (MI.getOpcode()) {
13891bc56edSDimitry Andric   int NewOpcode;
13991bc56edSDimitry Andric   case XCore::LDWFI:
14091bc56edSDimitry Andric     NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
14191bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
14291bc56edSDimitry Andric           .addImm(Offset)
14391bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
14491bc56edSDimitry Andric     break;
14591bc56edSDimitry Andric   case XCore::STWFI:
14691bc56edSDimitry Andric     NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
14791bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(NewOpcode))
14891bc56edSDimitry Andric           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
14991bc56edSDimitry Andric           .addImm(Offset)
15091bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
15191bc56edSDimitry Andric     break;
15291bc56edSDimitry Andric   case XCore::LDAWFI:
15391bc56edSDimitry Andric     NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
15491bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
15591bc56edSDimitry Andric           .addImm(Offset);
15691bc56edSDimitry Andric     break;
15791bc56edSDimitry Andric   default:
15891bc56edSDimitry Andric     llvm_unreachable("Unexpected Opcode");
15991bc56edSDimitry Andric   }
16091bc56edSDimitry Andric }
16191bc56edSDimitry Andric 
InsertSPConstInst(MachineBasicBlock::iterator II,const XCoreInstrInfo & TII,unsigned Reg,int Offset,RegScavenger * RS)16291bc56edSDimitry Andric static void InsertSPConstInst(MachineBasicBlock::iterator II,
16391bc56edSDimitry Andric                                 const XCoreInstrInfo &TII,
16491bc56edSDimitry Andric                                 unsigned Reg, int Offset, RegScavenger *RS ) {
16591bc56edSDimitry Andric   assert(RS && "requiresRegisterScavenging failed");
16691bc56edSDimitry Andric   MachineInstr &MI = *II;
16791bc56edSDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
16891bc56edSDimitry Andric   DebugLoc dl = MI.getDebugLoc();
16991bc56edSDimitry Andric   unsigned OpCode = MI.getOpcode();
17091bc56edSDimitry Andric 
17191bc56edSDimitry Andric   unsigned ScratchBase;
17291bc56edSDimitry Andric   if (OpCode==XCore::STWFI) {
17391bc56edSDimitry Andric     ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
17439d628a0SDimitry Andric     RS->setRegUsed(ScratchBase);
17591bc56edSDimitry Andric   } else
17691bc56edSDimitry Andric     ScratchBase = Reg;
17791bc56edSDimitry Andric   BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
17891bc56edSDimitry Andric   unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
17939d628a0SDimitry Andric   RS->setRegUsed(ScratchOffset);
18091bc56edSDimitry Andric   TII.loadImmediate(MBB, II, ScratchOffset, Offset);
18191bc56edSDimitry Andric 
18291bc56edSDimitry Andric   switch (OpCode) {
18391bc56edSDimitry Andric   case XCore::LDWFI:
18491bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
18591bc56edSDimitry Andric           .addReg(ScratchBase, RegState::Kill)
18691bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill)
18791bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
18891bc56edSDimitry Andric     break;
18991bc56edSDimitry Andric   case XCore::STWFI:
19091bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
19191bc56edSDimitry Andric           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
19291bc56edSDimitry Andric           .addReg(ScratchBase, RegState::Kill)
19391bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill)
19491bc56edSDimitry Andric           .addMemOperand(*MI.memoperands_begin());
19591bc56edSDimitry Andric     break;
19691bc56edSDimitry Andric   case XCore::LDAWFI:
19791bc56edSDimitry Andric     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
19891bc56edSDimitry Andric           .addReg(ScratchBase, RegState::Kill)
19991bc56edSDimitry Andric           .addReg(ScratchOffset, RegState::Kill);
20091bc56edSDimitry Andric     break;
20191bc56edSDimitry Andric   default:
20291bc56edSDimitry Andric     llvm_unreachable("Unexpected Opcode");
20391bc56edSDimitry Andric   }
20491bc56edSDimitry Andric }
20591bc56edSDimitry Andric 
needsFrameMoves(const MachineFunction & MF)206f22ef01cSRoman Divacky bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
2072cab237bSDimitry Andric   return MF.getMMI().hasDebugInfo() || MF.getFunction().needsUnwindTableEntry();
208f22ef01cSRoman Divacky }
209f22ef01cSRoman Divacky 
210ff0cc061SDimitry Andric const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const211ff0cc061SDimitry Andric XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
21291bc56edSDimitry Andric   // The callee saved registers LR & FP are explicitly handled during
21391bc56edSDimitry Andric   // emitPrologue & emitEpilogue and related functions.
21491bc56edSDimitry Andric   static const MCPhysReg CalleeSavedRegs[] = {
215f22ef01cSRoman Divacky     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
21691bc56edSDimitry Andric     XCore::R8, XCore::R9, XCore::R10,
217f22ef01cSRoman Divacky     0
218f22ef01cSRoman Divacky   };
21991bc56edSDimitry Andric   static const MCPhysReg CalleeSavedRegsFP[] = {
22091bc56edSDimitry Andric     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
22191bc56edSDimitry Andric     XCore::R8, XCore::R9,
22291bc56edSDimitry Andric     0
22391bc56edSDimitry Andric   };
224875ed548SDimitry Andric   const XCoreFrameLowering *TFI = getFrameLowering(*MF);
22591bc56edSDimitry Andric   if (TFI->hasFP(*MF))
22691bc56edSDimitry Andric     return CalleeSavedRegsFP;
227f22ef01cSRoman Divacky   return CalleeSavedRegs;
228f22ef01cSRoman Divacky }
229f22ef01cSRoman Divacky 
getReservedRegs(const MachineFunction & MF) const230f22ef01cSRoman Divacky BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
231f22ef01cSRoman Divacky   BitVector Reserved(getNumRegs());
232875ed548SDimitry Andric   const XCoreFrameLowering *TFI = getFrameLowering(MF);
2332754fe60SDimitry Andric 
234f22ef01cSRoman Divacky   Reserved.set(XCore::CP);
235f22ef01cSRoman Divacky   Reserved.set(XCore::DP);
236f22ef01cSRoman Divacky   Reserved.set(XCore::SP);
237f22ef01cSRoman Divacky   Reserved.set(XCore::LR);
2382754fe60SDimitry Andric   if (TFI->hasFP(MF)) {
239f22ef01cSRoman Divacky     Reserved.set(XCore::R10);
240f22ef01cSRoman Divacky   }
241f22ef01cSRoman Divacky   return Reserved;
242f22ef01cSRoman Divacky }
243f22ef01cSRoman Divacky 
244f22ef01cSRoman Divacky bool
requiresRegisterScavenging(const MachineFunction & MF) const245f22ef01cSRoman Divacky XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
24691bc56edSDimitry Andric   return true;
247f22ef01cSRoman Divacky }
248f22ef01cSRoman Divacky 
2493b0f4066SDimitry Andric bool
trackLivenessAfterRegAlloc(const MachineFunction & MF) const2507ae0e2c9SDimitry Andric XCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
25191bc56edSDimitry Andric   return true;
2527ae0e2c9SDimitry Andric }
2537ae0e2c9SDimitry Andric 
2547ae0e2c9SDimitry Andric bool
useFPForScavengingIndex(const MachineFunction & MF) const2553b0f4066SDimitry Andric XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
2563b0f4066SDimitry Andric   return false;
2573b0f4066SDimitry Andric }
2583b0f4066SDimitry Andric 
259e580952dSDimitry Andric void
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const260f22ef01cSRoman Divacky XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
261139f7f9bSDimitry Andric                                        int SPAdj, unsigned FIOperandNum,
262139f7f9bSDimitry Andric                                        RegScavenger *RS) const {
263f22ef01cSRoman Divacky   assert(SPAdj == 0 && "Unexpected");
264f22ef01cSRoman Divacky   MachineInstr &MI = *II;
265139f7f9bSDimitry Andric   MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
266f22ef01cSRoman Divacky   int FrameIndex = FrameOp.getIndex();
267f22ef01cSRoman Divacky 
268f22ef01cSRoman Divacky   MachineFunction &MF = *MI.getParent()->getParent();
26991bc56edSDimitry Andric   const XCoreInstrInfo &TII =
27039d628a0SDimitry Andric       *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
27191bc56edSDimitry Andric 
272875ed548SDimitry Andric   const XCoreFrameLowering *TFI = getFrameLowering(MF);
273d88c1a5aSDimitry Andric   int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);
274d88c1a5aSDimitry Andric   int StackSize = MF.getFrameInfo().getStackSize();
275f22ef01cSRoman Divacky 
276f22ef01cSRoman Divacky   #ifndef NDEBUG
277*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "\nFunction         : " << MF.getName() << "\n");
278*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "<--------->\n");
279*4ba319b5SDimitry Andric   LLVM_DEBUG(MI.print(errs()));
280*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");
281*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "FrameOffset        : " << Offset << "\n");
282*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "StackSize          : " << StackSize << "\n");
283f22ef01cSRoman Divacky #endif
284f22ef01cSRoman Divacky 
285f22ef01cSRoman Divacky   Offset += StackSize;
286f22ef01cSRoman Divacky 
28717a519f9SDimitry Andric   unsigned FrameReg = getFrameRegister(MF);
28817a519f9SDimitry Andric 
28917a519f9SDimitry Andric   // Special handling of DBG_VALUE instructions.
29017a519f9SDimitry Andric   if (MI.isDebugValue()) {
291139f7f9bSDimitry Andric     MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
292139f7f9bSDimitry Andric     MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
29317a519f9SDimitry Andric     return;
29417a519f9SDimitry Andric   }
29517a519f9SDimitry Andric 
296f22ef01cSRoman Divacky   // fold constant into offset.
297139f7f9bSDimitry Andric   Offset += MI.getOperand(FIOperandNum + 1).getImm();
298139f7f9bSDimitry Andric   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
299f22ef01cSRoman Divacky 
300f22ef01cSRoman Divacky   assert(Offset%4 == 0 && "Misaligned stack offset");
301*4ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "Offset             : " << Offset << "\n"
302*4ba319b5SDimitry Andric                     << "<--------->\n");
303f22ef01cSRoman Divacky   Offset/=4;
304f22ef01cSRoman Divacky 
305f22ef01cSRoman Divacky   unsigned Reg = MI.getOperand(0).getReg();
3067ae0e2c9SDimitry Andric   assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
307f22ef01cSRoman Divacky 
30891bc56edSDimitry Andric   if (TFI->hasFP(MF)) {
30991bc56edSDimitry Andric     if (isImmUs(Offset))
31091bc56edSDimitry Andric       InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
31191bc56edSDimitry Andric     else
31291bc56edSDimitry Andric       InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
313f22ef01cSRoman Divacky   } else {
31491bc56edSDimitry Andric     if (isImmU16(Offset))
31591bc56edSDimitry Andric       InsertSPImmInst(II, TII, Reg, Offset);
31691bc56edSDimitry Andric     else
31791bc56edSDimitry Andric       InsertSPConstInst(II, TII, Reg, Offset, RS);
318f22ef01cSRoman Divacky   }
319f22ef01cSRoman Divacky   // Erase old instruction.
32091bc56edSDimitry Andric   MachineBasicBlock &MBB = *MI.getParent();
321f22ef01cSRoman Divacky   MBB.erase(II);
322f22ef01cSRoman Divacky }
323f22ef01cSRoman Divacky 
324f22ef01cSRoman Divacky 
getFrameRegister(const MachineFunction & MF) const325f22ef01cSRoman Divacky unsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
326875ed548SDimitry Andric   const XCoreFrameLowering *TFI = getFrameLowering(MF);
327f22ef01cSRoman Divacky 
3282754fe60SDimitry Andric   return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
329f22ef01cSRoman Divacky }
330