LLVM API Documentation

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