LLVM  mainline
XCoreRegisterInfo.cpp
Go to the documentation of this file.
00001 //===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//
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 "XCore.h"
00016 #include "XCoreInstrInfo.h"
00017 #include "XCoreMachineFunctionInfo.h"
00018 #include "XCoreSubtarget.h"
00019 #include "llvm/ADT/BitVector.h"
00020 #include "llvm/ADT/STLExtras.h"
00021 #include "llvm/CodeGen/MachineFrameInfo.h"
00022 #include "llvm/CodeGen/MachineFunction.h"
00023 #include "llvm/CodeGen/MachineInstrBuilder.h"
00024 #include "llvm/CodeGen/MachineModuleInfo.h"
00025 #include "llvm/CodeGen/MachineRegisterInfo.h"
00026 #include "llvm/CodeGen/RegisterScavenging.h"
00027 #include "llvm/IR/Function.h"
00028 #include "llvm/IR/Type.h"
00029 #include "llvm/Support/Debug.h"
00030 #include "llvm/Support/ErrorHandling.h"
00031 #include "llvm/Support/MathExtras.h"
00032 #include "llvm/Support/raw_ostream.h"
00033 #include "llvm/Target/TargetFrameLowering.h"
00034 #include "llvm/Target/TargetMachine.h"
00035 #include "llvm/Target/TargetOptions.h"
00036 
00037 using namespace llvm;
00038 
00039 #define DEBUG_TYPE "xcore-reg-info"
00040 
00041 #define GET_REGINFO_TARGET_DESC
00042 #include "XCoreGenRegisterInfo.inc"
00043 
00044 XCoreRegisterInfo::XCoreRegisterInfo()
00045   : XCoreGenRegisterInfo(XCore::LR) {
00046 }
00047 
00048 // helper functions
00049 static inline bool isImmUs(unsigned val) {
00050   return val <= 11;
00051 }
00052 
00053 static inline bool isImmU6(unsigned val) {
00054   return val < (1 << 6);
00055 }
00056 
00057 static inline bool isImmU16(unsigned val) {
00058   return val < (1 << 16);
00059 }
00060 
00061 
00062 static void InsertFPImmInst(MachineBasicBlock::iterator II,
00063                             const XCoreInstrInfo &TII,
00064                             unsigned Reg, unsigned FrameReg, int Offset ) {
00065   MachineInstr &MI = *II;
00066   MachineBasicBlock &MBB = *MI.getParent();
00067   DebugLoc dl = MI.getDebugLoc();
00068 
00069   switch (MI.getOpcode()) {
00070   case XCore::LDWFI:
00071     BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)
00072           .addReg(FrameReg)
00073           .addImm(Offset)
00074           .addMemOperand(*MI.memoperands_begin());
00075     break;
00076   case XCore::STWFI:
00077     BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))
00078           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
00079           .addReg(FrameReg)
00080           .addImm(Offset)
00081           .addMemOperand(*MI.memoperands_begin());
00082     break;
00083   case XCore::LDAWFI:
00084     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)
00085           .addReg(FrameReg)
00086           .addImm(Offset);
00087     break;
00088   default:
00089     llvm_unreachable("Unexpected Opcode");
00090   }
00091 }
00092 
00093 static void InsertFPConstInst(MachineBasicBlock::iterator II,
00094                               const XCoreInstrInfo &TII,
00095                               unsigned Reg, unsigned FrameReg,
00096                               int Offset, RegScavenger *RS ) {
00097   assert(RS && "requiresRegisterScavenging failed");
00098   MachineInstr &MI = *II;
00099   MachineBasicBlock &MBB = *MI.getParent();
00100   DebugLoc dl = MI.getDebugLoc();
00101   unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
00102   RS->setRegUsed(ScratchOffset);
00103   TII.loadImmediate(MBB, II, ScratchOffset, Offset);
00104 
00105   switch (MI.getOpcode()) {
00106   case XCore::LDWFI:
00107     BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
00108           .addReg(FrameReg)
00109           .addReg(ScratchOffset, RegState::Kill)
00110           .addMemOperand(*MI.memoperands_begin());
00111     break;
00112   case XCore::STWFI:
00113     BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
00114           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
00115           .addReg(FrameReg)
00116           .addReg(ScratchOffset, RegState::Kill)
00117           .addMemOperand(*MI.memoperands_begin());
00118     break;
00119   case XCore::LDAWFI:
00120     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
00121           .addReg(FrameReg)
00122           .addReg(ScratchOffset, RegState::Kill);
00123     break;
00124   default:
00125     llvm_unreachable("Unexpected Opcode");
00126   }
00127 }
00128 
00129 static void InsertSPImmInst(MachineBasicBlock::iterator II,
00130                             const XCoreInstrInfo &TII,
00131                             unsigned Reg, int Offset) {
00132   MachineInstr &MI = *II;
00133   MachineBasicBlock &MBB = *MI.getParent();
00134   DebugLoc dl = MI.getDebugLoc();
00135   bool isU6 = isImmU6(Offset);
00136 
00137   switch (MI.getOpcode()) {
00138   int NewOpcode;
00139   case XCore::LDWFI:
00140     NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
00141     BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
00142           .addImm(Offset)
00143           .addMemOperand(*MI.memoperands_begin());
00144     break;
00145   case XCore::STWFI:
00146     NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
00147     BuildMI(MBB, II, dl, TII.get(NewOpcode))
00148           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
00149           .addImm(Offset)
00150           .addMemOperand(*MI.memoperands_begin());
00151     break;
00152   case XCore::LDAWFI:
00153     NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
00154     BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)
00155           .addImm(Offset);
00156     break;
00157   default:
00158     llvm_unreachable("Unexpected Opcode");
00159   }
00160 }
00161 
00162 static void InsertSPConstInst(MachineBasicBlock::iterator II,
00163                                 const XCoreInstrInfo &TII,
00164                                 unsigned Reg, int Offset, RegScavenger *RS ) {
00165   assert(RS && "requiresRegisterScavenging failed");
00166   MachineInstr &MI = *II;
00167   MachineBasicBlock &MBB = *MI.getParent();
00168   DebugLoc dl = MI.getDebugLoc();
00169   unsigned OpCode = MI.getOpcode();
00170 
00171   unsigned ScratchBase;
00172   if (OpCode==XCore::STWFI) {
00173     ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
00174     RS->setRegUsed(ScratchBase);
00175   } else
00176     ScratchBase = Reg;
00177   BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);
00178   unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0);
00179   RS->setRegUsed(ScratchOffset);
00180   TII.loadImmediate(MBB, II, ScratchOffset, Offset);
00181 
00182   switch (OpCode) {
00183   case XCore::LDWFI:
00184     BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)
00185           .addReg(ScratchBase, RegState::Kill)
00186           .addReg(ScratchOffset, RegState::Kill)
00187           .addMemOperand(*MI.memoperands_begin());
00188     break;
00189   case XCore::STWFI:
00190     BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))
00191           .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))
00192           .addReg(ScratchBase, RegState::Kill)
00193           .addReg(ScratchOffset, RegState::Kill)
00194           .addMemOperand(*MI.memoperands_begin());
00195     break;
00196   case XCore::LDAWFI:
00197     BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)
00198           .addReg(ScratchBase, RegState::Kill)
00199           .addReg(ScratchOffset, RegState::Kill);
00200     break;
00201   default:
00202     llvm_unreachable("Unexpected Opcode");
00203   }
00204 }
00205 
00206 bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
00207   return MF.getMMI().hasDebugInfo() ||
00208     MF.getFunction()->needsUnwindTableEntry();
00209 }
00210 
00211 const MCPhysReg *
00212 XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
00213   // The callee saved registers LR & FP are explicitly handled during
00214   // emitPrologue & emitEpilogue and related functions.
00215   static const MCPhysReg CalleeSavedRegs[] = {
00216     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
00217     XCore::R8, XCore::R9, XCore::R10,
00218     0
00219   };
00220   static const MCPhysReg CalleeSavedRegsFP[] = {
00221     XCore::R4, XCore::R5, XCore::R6, XCore::R7,
00222     XCore::R8, XCore::R9,
00223     0
00224   };
00225   const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
00226   if (TFI->hasFP(*MF))
00227     return CalleeSavedRegsFP;
00228   return CalleeSavedRegs;
00229 }
00230 
00231 BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
00232   BitVector Reserved(getNumRegs());
00233   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
00234 
00235   Reserved.set(XCore::CP);
00236   Reserved.set(XCore::DP);
00237   Reserved.set(XCore::SP);
00238   Reserved.set(XCore::LR);
00239   if (TFI->hasFP(MF)) {
00240     Reserved.set(XCore::R10);
00241   }
00242   return Reserved;
00243 }
00244 
00245 bool
00246 XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
00247   return true;
00248 }
00249 
00250 bool
00251 XCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
00252   return true;
00253 }
00254 
00255 bool
00256 XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
00257   return false;
00258 }
00259 
00260 void
00261 XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
00262                                        int SPAdj, unsigned FIOperandNum,
00263                                        RegScavenger *RS) const {
00264   assert(SPAdj == 0 && "Unexpected");
00265   MachineInstr &MI = *II;
00266   MachineOperand &FrameOp = MI.getOperand(FIOperandNum);
00267   int FrameIndex = FrameOp.getIndex();
00268 
00269   MachineFunction &MF = *MI.getParent()->getParent();
00270   const XCoreInstrInfo &TII =
00271       *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());
00272 
00273   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
00274   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
00275   int StackSize = MF.getFrameInfo()->getStackSize();
00276 
00277   #ifndef NDEBUG
00278   DEBUG(errs() << "\nFunction         : " 
00279         << MF.getName() << "\n");
00280   DEBUG(errs() << "<--------->\n");
00281   DEBUG(MI.print(errs()));
00282   DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");
00283   DEBUG(errs() << "FrameOffset        : " << Offset << "\n");
00284   DEBUG(errs() << "StackSize          : " << StackSize << "\n");
00285   #endif
00286 
00287   Offset += StackSize;
00288 
00289   unsigned FrameReg = getFrameRegister(MF);
00290 
00291   // Special handling of DBG_VALUE instructions.
00292   if (MI.isDebugValue()) {
00293     MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
00294     MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
00295     return;
00296   }
00297 
00298   // fold constant into offset.
00299   Offset += MI.getOperand(FIOperandNum + 1).getImm();
00300   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
00301   
00302   assert(Offset%4 == 0 && "Misaligned stack offset");
00303   DEBUG(errs() << "Offset             : " << Offset << "\n" << "<--------->\n");
00304   Offset/=4;
00305   
00306   unsigned Reg = MI.getOperand(0).getReg();
00307   assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");
00308 
00309   if (TFI->hasFP(MF)) {
00310     if (isImmUs(Offset))
00311       InsertFPImmInst(II, TII, Reg, FrameReg, Offset);
00312     else
00313       InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);
00314   } else {
00315     if (isImmU16(Offset))
00316       InsertSPImmInst(II, TII, Reg, Offset);
00317     else
00318       InsertSPConstInst(II, TII, Reg, Offset, RS);
00319   }
00320   // Erase old instruction.
00321   MachineBasicBlock &MBB = *MI.getParent();
00322   MBB.erase(II);
00323 }
00324 
00325 
00326 unsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
00327   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
00328 
00329   return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;
00330 }