LLVM API Documentation
00001 //===- XCoreRegisterInfo.cpp - XCore Register Information -------*- C++ -*-===// 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 "XCoreMachineFunctionInfo.h" 00016 #include "XCore.h" 00017 #include "llvm/CodeGen/MachineInstrBuilder.h" 00018 #include "llvm/CodeGen/MachineFunction.h" 00019 #include "llvm/CodeGen/MachineFrameInfo.h" 00020 #include "llvm/CodeGen/MachineLocation.h" 00021 #include "llvm/CodeGen/MachineModuleInfo.h" 00022 #include "llvm/CodeGen/MachineRegisterInfo.h" 00023 #include "llvm/CodeGen/RegisterScavenging.h" 00024 #include "llvm/Target/TargetFrameInfo.h" 00025 #include "llvm/Target/TargetMachine.h" 00026 #include "llvm/Target/TargetOptions.h" 00027 #include "llvm/Target/TargetInstrInfo.h" 00028 #include "llvm/Type.h" 00029 #include "llvm/Function.h" 00030 #include "llvm/ADT/BitVector.h" 00031 #include "llvm/ADT/STLExtras.h" 00032 #include "llvm/Support/Debug.h" 00033 00034 using namespace llvm; 00035 00036 XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) 00037 : XCoreGenRegisterInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 00038 TII(tii) { 00039 } 00040 00041 // helper functions 00042 static inline bool isImmUs(unsigned val) { 00043 return val <= 11; 00044 } 00045 00046 static inline bool isImmU6(unsigned val) { 00047 return val < (1 << 6); 00048 } 00049 00050 static inline bool isImmU16(unsigned val) { 00051 return val < (1 << 16); 00052 } 00053 00054 static const unsigned XCore_ArgRegs[] = { 00055 XCore::R0, XCore::R1, XCore::R2, XCore::R3 00056 }; 00057 00058 const unsigned * XCoreRegisterInfo::getArgRegs(const MachineFunction *MF) 00059 { 00060 return XCore_ArgRegs; 00061 } 00062 00063 unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF) 00064 { 00065 return array_lengthof(XCore_ArgRegs); 00066 } 00067 00068 bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) 00069 { 00070 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00071 MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); 00072 return (MMI && MMI->hasDebugInfo()) || 00073 !MF.getFunction()->doesNotThrow() || 00074 UnwindTablesMandatory; 00075 } 00076 00077 const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 00078 const { 00079 static const unsigned CalleeSavedRegs[] = { 00080 XCore::R4, XCore::R5, XCore::R6, XCore::R7, 00081 XCore::R8, XCore::R9, XCore::R10, XCore::LR, 00082 0 00083 }; 00084 return CalleeSavedRegs; 00085 } 00086 00087 const TargetRegisterClass* const* 00088 XCoreRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 00089 static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 00090 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 00091 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 00092 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 00093 XCore::GRRegsRegisterClass, XCore::RRegsRegisterClass, 00094 0 00095 }; 00096 return CalleeSavedRegClasses; 00097 } 00098 00099 BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 00100 BitVector Reserved(getNumRegs()); 00101 Reserved.set(XCore::CP); 00102 Reserved.set(XCore::DP); 00103 Reserved.set(XCore::SP); 00104 Reserved.set(XCore::LR); 00105 if (hasFP(MF)) { 00106 Reserved.set(XCore::R10); 00107 } 00108 return Reserved; 00109 } 00110 00111 bool 00112 XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 00113 // TODO can we estimate stack size? 00114 return hasFP(MF); 00115 } 00116 00117 bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { 00118 return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); 00119 } 00120 00121 // This function eliminates ADJCALLSTACKDOWN, 00122 // ADJCALLSTACKUP pseudo instructions 00123 void XCoreRegisterInfo:: 00124 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00125 MachineBasicBlock::iterator I) const { 00126 if (!hasReservedCallFrame(MF)) { 00127 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 00128 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 00129 MachineInstr *Old = I; 00130 uint64_t Amount = Old->getOperand(0).getImm(); 00131 if (Amount != 0) { 00132 // We need to keep the stack aligned properly. To do this, we round the 00133 // amount of space needed for the outgoing arguments up to the next 00134 // alignment boundary. 00135 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00136 Amount = (Amount+Align-1)/Align*Align; 00137 00138 assert(Amount%4 == 0); 00139 Amount /= 4; 00140 00141 bool isU6 = isImmU6(Amount); 00142 00143 if (!isU6 && !isImmU16(Amount)) { 00144 // FIX could emit multiple instructions in this case. 00145 cerr << "eliminateCallFramePseudoInstr size too big: " 00146 << Amount << "\n"; 00147 abort(); 00148 } 00149 00150 MachineInstr *New; 00151 if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 00152 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 00153 New=BuildMI(MF, TII.get(Opcode)) 00154 .addImm(Amount); 00155 } else { 00156 assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 00157 int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; 00158 New=BuildMI(MF, TII.get(Opcode), XCore::SP) 00159 .addImm(Amount); 00160 } 00161 00162 // Replace the pseudo instruction with a new instruction... 00163 MBB.insert(I, New); 00164 } 00165 } 00166 00167 MBB.erase(I); 00168 } 00169 00170 void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00171 int SPAdj, RegScavenger *RS) const { 00172 assert(SPAdj == 0 && "Unexpected"); 00173 MachineInstr &MI = *II; 00174 unsigned i = 0; 00175 00176 while (!MI.getOperand(i).isFI()) { 00177 ++i; 00178 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00179 } 00180 00181 MachineOperand &FrameOp = MI.getOperand(i); 00182 int FrameIndex = FrameOp.getIndex(); 00183 00184 MachineFunction &MF = *MI.getParent()->getParent(); 00185 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 00186 int StackSize = MF.getFrameInfo()->getStackSize(); 00187 00188 #ifndef NDEBUG 00189 DOUT << "\nFunction : " << MF.getFunction()->getName() << "\n"; 00190 DOUT << "<--------->\n"; 00191 MI.print(DOUT); 00192 DOUT << "FrameIndex : " << FrameIndex << "\n"; 00193 DOUT << "FrameOffset : " << Offset << "\n"; 00194 DOUT << "StackSize : " << StackSize << "\n"; 00195 #endif 00196 00197 Offset += StackSize; 00198 00199 // fold constant into offset. 00200 Offset += MI.getOperand(i + 1).getImm(); 00201 MI.getOperand(i + 1).ChangeToImmediate(0); 00202 00203 assert(Offset%4 == 0 && "Misaligned stack offset"); 00204 00205 #ifndef NDEBUG 00206 DOUT << "Offset : " << Offset << "\n"; 00207 DOUT << "<--------->\n"; 00208 #endif 00209 00210 Offset/=4; 00211 00212 bool FP = hasFP(MF); 00213 00214 unsigned Reg = MI.getOperand(0).getReg(); 00215 bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); 00216 00217 assert(XCore::GRRegsRegisterClass->contains(Reg) && 00218 "Unexpected register operand"); 00219 00220 MachineBasicBlock &MBB = *MI.getParent(); 00221 00222 if (FP) { 00223 bool isUs = isImmUs(Offset); 00224 unsigned FramePtr = XCore::R10; 00225 00226 MachineInstr *New = 0; 00227 if (!isUs) { 00228 if (!RS) { 00229 cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n"; 00230 abort(); 00231 } 00232 unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II, 00233 SPAdj); 00234 loadConstant(MBB, II, ScratchReg, Offset); 00235 switch (MI.getOpcode()) { 00236 case XCore::LDWFI: 00237 New = BuildMI(MBB, II, TII.get(XCore::LDW_3r), Reg) 00238 .addReg(FramePtr) 00239 .addReg(ScratchReg, false, false, true); 00240 break; 00241 case XCore::STWFI: 00242 New = BuildMI(MBB, II, TII.get(XCore::STW_3r)) 00243 .addReg(Reg, false, false, isKill) 00244 .addReg(FramePtr) 00245 .addReg(ScratchReg, false, false, true); 00246 break; 00247 case XCore::LDAWFI: 00248 New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l3r), Reg) 00249 .addReg(FramePtr) 00250 .addReg(ScratchReg, false, false, true); 00251 break; 00252 default: 00253 assert(0 && "Unexpected Opcode\n"); 00254 } 00255 } else { 00256 switch (MI.getOpcode()) { 00257 case XCore::LDWFI: 00258 New = BuildMI(MBB, II, TII.get(XCore::LDW_2rus), Reg) 00259 .addReg(FramePtr) 00260 .addImm(Offset); 00261 break; 00262 case XCore::STWFI: 00263 New = BuildMI(MBB, II, TII.get(XCore::STW_2rus)) 00264 .addReg(Reg, false, false, isKill) 00265 .addReg(FramePtr) 00266 .addImm(Offset); 00267 break; 00268 case XCore::LDAWFI: 00269 New = BuildMI(MBB, II, TII.get(XCore::LDAWF_l2rus), Reg) 00270 .addReg(FramePtr) 00271 .addImm(Offset); 00272 break; 00273 default: 00274 assert(0 && "Unexpected Opcode\n"); 00275 } 00276 } 00277 } else { 00278 bool isU6 = isImmU6(Offset); 00279 if (!isU6 && !isImmU16(Offset)) { 00280 // FIXME could make this work for LDWSP, LDAWSP. 00281 cerr << "eliminateFrameIndex Frame size too big: " << Offset << "\n"; 00282 abort(); 00283 } 00284 00285 switch (MI.getOpcode()) { 00286 int NewOpcode; 00287 case XCore::LDWFI: 00288 NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 00289 BuildMI(MBB, II, TII.get(NewOpcode), Reg) 00290 .addImm(Offset); 00291 break; 00292 case XCore::STWFI: 00293 NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 00294 BuildMI(MBB, II, TII.get(NewOpcode)) 00295 .addReg(Reg, false, false, isKill) 00296 .addImm(Offset); 00297 break; 00298 case XCore::LDAWFI: 00299 NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 00300 BuildMI(MBB, II, TII.get(NewOpcode), Reg) 00301 .addImm(Offset); 00302 break; 00303 default: 00304 assert(0 && "Unexpected Opcode\n"); 00305 } 00306 } 00307 // Erase old instruction. 00308 MBB.erase(II); 00309 } 00310 00311 void 00312 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 00313 RegScavenger *RS) const { 00314 MachineFrameInfo *MFI = MF.getFrameInfo(); 00315 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 00316 const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; 00317 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00318 if (LRUsed) { 00319 MF.getRegInfo().setPhysRegUnused(XCore::LR); 00320 00321 bool isVarArg = MF.getFunction()->isVarArg(); 00322 int FrameIdx; 00323 if (! isVarArg) { 00324 // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. 00325 FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0); 00326 } else { 00327 FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); 00328 } 00329 XFI->setUsesLR(FrameIdx); 00330 XFI->setLRSpillSlot(FrameIdx); 00331 } 00332 if (requiresRegisterScavenging(MF)) { 00333 // Reserve a slot close to SP or frame pointer. 00334 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 00335 RC->getAlignment())); 00336 } 00337 if (hasFP(MF)) { 00338 // A callee save register is used to hold the FP. 00339 // This needs saving / restoring in the epilogue / prologue. 00340 XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), 00341 RC->getAlignment())); 00342 } 00343 } 00344 00345 void XCoreRegisterInfo:: 00346 processFunctionBeforeFrameFinalized(MachineFunction &MF) const { 00347 00348 } 00349 00350 void XCoreRegisterInfo:: 00351 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00352 unsigned DstReg, int64_t Value) const { 00353 // TODO use mkmsk if possible. 00354 if (!isImmU16(Value)) { 00355 // TODO use constant pool. 00356 cerr << "loadConstant value too big " << Value << "\n"; 00357 abort(); 00358 } 00359 int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 00360 BuildMI(MBB, I, TII.get(Opcode), DstReg).addImm(Value); 00361 } 00362 00363 void XCoreRegisterInfo:: 00364 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00365 unsigned SrcReg, int Offset) const { 00366 assert(Offset%4 == 0 && "Misaligned stack offset"); 00367 Offset/=4; 00368 bool isU6 = isImmU6(Offset); 00369 if (!isU6 && !isImmU16(Offset)) { 00370 cerr << "storeToStack offset too big " << Offset << "\n"; 00371 abort(); 00372 } 00373 int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 00374 BuildMI(MBB, I, TII.get(Opcode)) 00375 .addReg(SrcReg) 00376 .addImm(Offset); 00377 } 00378 00379 void XCoreRegisterInfo:: 00380 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00381 unsigned DstReg, int Offset) const { 00382 assert(Offset%4 == 0 && "Misaligned stack offset"); 00383 Offset/=4; 00384 bool isU6 = isImmU6(Offset); 00385 if (!isU6 && !isImmU16(Offset)) { 00386 cerr << "storeToStack offset too big " << Offset << "\n"; 00387 abort(); 00388 } 00389 int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 00390 BuildMI(MBB, I, TII.get(Opcode), DstReg) 00391 .addImm(Offset); 00392 } 00393 00394 void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { 00395 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00396 MachineBasicBlock::iterator MBBI = MBB.begin(); 00397 MachineFrameInfo *MFI = MF.getFrameInfo(); 00398 MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); 00399 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00400 00401 bool FP = hasFP(MF); 00402 00403 // Work out frame sizes. 00404 int FrameSize = MFI->getStackSize(); 00405 00406 assert(FrameSize%4 == 0 && "Misaligned frame size"); 00407 00408 FrameSize/=4; 00409 00410 bool isU6 = isImmU6(FrameSize); 00411 00412 if (!isU6 && !isImmU16(FrameSize)) { 00413 // FIXME could emit multiple instructions. 00414 cerr << "emitPrologue Frame size too big: " << FrameSize << "\n"; 00415 abort(); 00416 } 00417 bool emitFrameMoves = needsFrameMoves(MF); 00418 00419 // Do we need to allocate space on the stack? 00420 if (FrameSize) { 00421 bool saveLR = XFI->getUsesLR(); 00422 bool LRSavedOnEntry = false; 00423 int Opcode; 00424 if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { 00425 Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 00426 MBB.addLiveIn(XCore::LR); 00427 saveLR = false; 00428 LRSavedOnEntry = true; 00429 } else { 00430 Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 00431 } 00432 BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize); 00433 00434 if (emitFrameMoves) { 00435 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 00436 00437 // Show update of SP. 00438 unsigned FrameLabelId = MMI->NextLabelID(); 00439 BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 00440 00441 MachineLocation SPDst(MachineLocation::VirtualFP); 00442 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); 00443 Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 00444 00445 if (LRSavedOnEntry) { 00446 MachineLocation CSDst(MachineLocation::VirtualFP, 0); 00447 MachineLocation CSSrc(XCore::LR); 00448 Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); 00449 } 00450 } 00451 if (saveLR) { 00452 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 00453 storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4); 00454 MBB.addLiveIn(XCore::LR); 00455 00456 if (emitFrameMoves) { 00457 unsigned SaveLRLabelId = MMI->NextLabelID(); 00458 BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId); 00459 MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); 00460 MachineLocation CSSrc(XCore::LR); 00461 MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId, 00462 CSDst, CSSrc)); 00463 } 00464 } 00465 } 00466 00467 if (FP) { 00468 // Save R10 to the stack. 00469 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 00470 storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4); 00471 // R10 is live-in. It is killed at the spill. 00472 MBB.addLiveIn(XCore::R10); 00473 if (emitFrameMoves) { 00474 unsigned SaveR10LabelId = MMI->NextLabelID(); 00475 BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId); 00476 MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); 00477 MachineLocation CSSrc(XCore::R10); 00478 MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId, 00479 CSDst, CSSrc)); 00480 } 00481 // Set the FP from the SP. 00482 unsigned FramePtr = XCore::R10; 00483 BuildMI(MBB, MBBI, TII.get(XCore::LDAWSP_ru6), FramePtr) 00484 .addImm(0); 00485 if (emitFrameMoves) { 00486 // Show FP is now valid. 00487 unsigned FrameLabelId = MMI->NextLabelID(); 00488 BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 00489 MachineLocation SPDst(FramePtr); 00490 MachineLocation SPSrc(MachineLocation::VirtualFP); 00491 MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 00492 } 00493 } 00494 00495 if (emitFrameMoves) { 00496 // Frame moves for callee saved. 00497 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 00498 std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels = 00499 XFI->getSpillLabels(); 00500 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 00501 unsigned SpillLabel = SpillLabels[I].first; 00502 CalleeSavedInfo &CSI = SpillLabels[I].second; 00503 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 00504 unsigned Reg = CSI.getReg(); 00505 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 00506 MachineLocation CSSrc(Reg); 00507 Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); 00508 } 00509 } 00510 } 00511 00512 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF, 00513 MachineBasicBlock &MBB) const { 00514 MachineFrameInfo *MFI = MF.getFrameInfo(); 00515 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 00516 00517 bool FP = hasFP(MF); 00518 00519 if (FP) { 00520 // Restore the stack pointer. 00521 unsigned FramePtr = XCore::R10; 00522 BuildMI(MBB, MBBI, TII.get(XCore::SETSP_1r)) 00523 .addReg(FramePtr); 00524 } 00525 00526 // Work out frame sizes. 00527 int FrameSize = MFI->getStackSize(); 00528 00529 assert(FrameSize%4 == 0 && "Misaligned frame size"); 00530 00531 FrameSize/=4; 00532 00533 bool isU6 = isImmU6(FrameSize); 00534 00535 if (!isU6 && !isImmU16(FrameSize)) { 00536 // FIXME could emit multiple instructions. 00537 cerr << "emitEpilogue Frame size too big: " << FrameSize << "\n"; 00538 abort(); 00539 } 00540 00541 if (FrameSize) { 00542 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00543 00544 if (FP) { 00545 // Restore R10 00546 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 00547 FPSpillOffset += FrameSize*4; 00548 loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset); 00549 } 00550 bool restoreLR = XFI->getUsesLR(); 00551 if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { 00552 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 00553 LRSpillOffset += FrameSize*4; 00554 loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset); 00555 restoreLR = false; 00556 } 00557 if (restoreLR) { 00558 // Fold prologue into return instruction 00559 assert(MBBI->getOpcode() == XCore::RETSP_u6 00560 || MBBI->getOpcode() == XCore::RETSP_lu6); 00561 int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 00562 BuildMI(MBB, MBBI, TII.get(Opcode)).addImm(FrameSize); 00563 MBB.erase(MBBI); 00564 } else { 00565 int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; 00566 BuildMI(MBB, MBBI, TII.get(Opcode), XCore::SP).addImm(FrameSize); 00567 } 00568 } 00569 } 00570 00571 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 00572 return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 00573 } 00574 00575 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const { 00576 bool FP = hasFP(MF); 00577 00578 return FP ? XCore::R10 : XCore::SP; 00579 } 00580 00581 unsigned XCoreRegisterInfo::getRARegister() const { 00582 return XCore::LR; 00583 } 00584 00585 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) 00586 const { 00587 // Initial state of the frame pointer is SP. 00588 MachineLocation Dst(MachineLocation::VirtualFP); 00589 MachineLocation Src(XCore::SP, 0); 00590 Moves.push_back(MachineMove(0, Dst, Src)); 00591 } 00592 00593 #include "XCoreGenRegisterInfo.inc" 00594