LLVM API Documentation
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* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 00212 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 }