1 //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains XCore frame information that doesn't fit anywhere else 11 // cleanly... 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "XCoreFrameLowering.h" 16 #include "XCore.h" 17 #include "XCoreInstrInfo.h" 18 #include "XCoreMachineFunctionInfo.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineFunction.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/CodeGen/MachineModuleInfo.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/RegisterScavenging.h" 25 #include "llvm/IR/DataLayout.h" 26 #include "llvm/IR/Function.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Target/TargetOptions.h" 29 30 using namespace llvm; 31 32 static const unsigned FramePtr = XCore::R10; 33 static const int MaxImmU16 = (1<<16) - 1; 34 35 // helper functions. FIXME: Eliminate. 36 static inline bool isImmU6(unsigned val) { 37 return val < (1 << 6); 38 } 39 40 static inline bool isImmU16(unsigned val) { 41 return val < (1 << 16); 42 } 43 44 static void EmitDefCfaRegister(MachineBasicBlock &MBB, 45 MachineBasicBlock::iterator MBBI, DebugLoc dl, 46 const TargetInstrInfo &TII, 47 MachineModuleInfo *MMI, unsigned DRegNum) { 48 MCSymbol *Label = MMI->getContext().CreateTempSymbol(); 49 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 50 MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(Label, DRegNum)); 51 } 52 53 static void EmitDefCfaOffset(MachineBasicBlock &MBB, 54 MachineBasicBlock::iterator MBBI, DebugLoc dl, 55 const TargetInstrInfo &TII, 56 MachineModuleInfo *MMI, int Offset) { 57 MCSymbol *Label = MMI->getContext().CreateTempSymbol(); 58 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 59 MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(Label, -Offset)); 60 } 61 62 static void EmitCfiOffset(MachineBasicBlock &MBB, 63 MachineBasicBlock::iterator MBBI, DebugLoc dl, 64 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 65 unsigned DRegNum, int Offset, MCSymbol *Label) { 66 if (!Label) { 67 Label = MMI->getContext().CreateTempSymbol(); 68 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 69 } 70 MMI->addFrameInst(MCCFIInstruction::createOffset(Label, DRegNum, Offset)); 71 } 72 73 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the 74 /// frame. During these steps, it may be necessary to spill registers. 75 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only 76 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6. 77 /// \param OffsetFromTop the spill offset from the top of the frame. 78 /// \param [in,out] Adjusted the current SP offset from the top of the frame. 79 static void IfNeededExtSP(MachineBasicBlock &MBB, 80 MachineBasicBlock::iterator MBBI, DebugLoc dl, 81 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 82 int OffsetFromTop, int &Adjusted, int FrameSize, 83 bool emitFrameMoves) { 84 while (OffsetFromTop > Adjusted) { 85 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize"); 86 int remaining = FrameSize - Adjusted; 87 int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining; 88 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 89 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm); 90 Adjusted += OpImm; 91 if (emitFrameMoves) 92 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 93 } 94 } 95 96 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the 97 /// frame. During these steps, it may be necessary to re-load registers. 98 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only 99 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6. 100 /// \param OffsetFromTop the spill offset from the top of the frame. 101 /// \param [in,out] RemainingAdj the current SP offset from the top of the frame. 102 static void IfNeededLDAWSP(MachineBasicBlock &MBB, 103 MachineBasicBlock::iterator MBBI, DebugLoc dl, 104 const TargetInstrInfo &TII, int OffsetFromTop, 105 int &RemainingAdj) { 106 while (OffsetFromTop < RemainingAdj - MaxImmU16) { 107 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize"); 108 int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj; 109 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 110 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm); 111 RemainingAdj -= OpImm; 112 } 113 } 114 115 /// Creates an ordered list of registers that are spilled 116 /// during the emitPrologue/emitEpilogue. 117 /// Registers are ordered according to their frame offset. 118 static void GetSpillList(SmallVectorImpl<std::pair<unsigned,int> > &SpillList, 119 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, 120 bool fetchLR, bool fetchFP) { 121 int LRSpillOffset = fetchLR? MFI->getObjectOffset(XFI->getLRSpillSlot()) : 0; 122 int FPSpillOffset = fetchFP? MFI->getObjectOffset(XFI->getFPSpillSlot()) : 0; 123 if (fetchLR && fetchFP && LRSpillOffset > FPSpillOffset) { 124 SpillList.push_back(std::pair<unsigned, int>(XCore::LR, LRSpillOffset)); 125 fetchLR = false; 126 } 127 if (fetchFP) 128 SpillList.push_back(std::pair<unsigned, int>(FramePtr, FPSpillOffset)); 129 if (fetchLR) 130 SpillList.push_back(std::pair<unsigned, int>(XCore::LR, LRSpillOffset)); 131 } 132 133 134 //===----------------------------------------------------------------------===// 135 // XCoreFrameLowering: 136 //===----------------------------------------------------------------------===// 137 138 XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) 139 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) { 140 // Do nothing 141 } 142 143 bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { 144 return MF.getTarget().Options.DisableFramePointerElim(MF) || 145 MF.getFrameInfo()->hasVarSizedObjects(); 146 } 147 148 void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { 149 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 150 MachineBasicBlock::iterator MBBI = MBB.begin(); 151 MachineFrameInfo *MFI = MF.getFrameInfo(); 152 MachineModuleInfo *MMI = &MF.getMMI(); 153 const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); 154 const XCoreInstrInfo &TII = 155 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 156 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 157 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 158 159 if (MFI->getMaxAlignment() > getStackAlignment()) 160 report_fatal_error("emitPrologue unsupported alignment: " 161 + Twine(MFI->getMaxAlignment())); 162 163 const AttributeSet &PAL = MF.getFunction()->getAttributes(); 164 if (PAL.hasAttrSomewhere(Attribute::Nest)) 165 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); 166 167 // Work out frame sizes. 168 // We will adjust the SP in stages towards the final FrameSize. 169 assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size"); 170 const int FrameSize = MFI->getStackSize() / 4; 171 int Adjusted = 0; 172 173 bool saveLR = XFI->hasLRSpillSlot(); 174 bool UseENTSP = saveLR && FrameSize 175 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 176 if (UseENTSP) 177 saveLR = false; 178 bool FP = hasFP(MF); 179 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 180 181 if (UseENTSP) { 182 // Allocate space on the stack at the same time as saving LR. 183 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize; 184 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 185 MBB.addLiveIn(XCore::LR); 186 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)); 187 MIB.addImm(Adjusted); 188 MIB->addRegisterKilled(XCore::LR, MF.getTarget().getRegisterInfo(), true); 189 if (emitFrameMoves) { 190 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 191 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true); 192 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0, NULL); 193 } 194 } 195 196 // If necessary, save LR and FP to the stack, as we EXTSP. 197 SmallVector<std::pair<unsigned,int>,2> SpillList; 198 GetSpillList(SpillList, MFI, XFI, saveLR, FP); 199 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 200 unsigned SpillReg = SpillList[i].first; 201 int SpillOffset = SpillList[i].second; 202 assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); 203 assert(SpillOffset <= 0 && "Unexpected positive stack offset"); 204 int OffsetFromTop = - SpillOffset/4; 205 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize, 206 emitFrameMoves); 207 int Offset = Adjusted - OffsetFromTop; 208 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 209 MBB.addLiveIn(SpillReg); 210 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addReg(SpillReg, RegState::Kill) 211 .addImm(Offset); 212 if (emitFrameMoves) { 213 unsigned DRegNum = MRI->getDwarfRegNum(SpillReg, true); 214 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillOffset, NULL); 215 } 216 } 217 218 // Complete any remaining Stack adjustment. 219 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize, 220 emitFrameMoves); 221 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment"); 222 223 if (FP) { 224 // Set the FP from the SP. 225 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); 226 if (emitFrameMoves) 227 EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, 228 MRI->getDwarfRegNum(FramePtr, true)); 229 } 230 231 if (emitFrameMoves) { 232 // Frame moves for callee saved. 233 std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = 234 XFI->getSpillLabels(); 235 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 236 MCSymbol *SpillLabel = SpillLabels[I].first; 237 CalleeSavedInfo &CSI = SpillLabels[I].second; 238 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 239 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); 240 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, Offset, SpillLabel); 241 } 242 } 243 } 244 245 void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, 246 MachineBasicBlock &MBB) const { 247 MachineFrameInfo *MFI = MF.getFrameInfo(); 248 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 249 const XCoreInstrInfo &TII = 250 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 251 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 252 DebugLoc dl = MBBI->getDebugLoc(); 253 unsigned RetOpcode = MBBI->getOpcode(); 254 255 if (RetOpcode == XCore::EH_RETURN) { 256 unsigned EhStackReg = MBBI->getOperand(0).getReg(); 257 unsigned EhHandlerReg = MBBI->getOperand(1).getReg(); 258 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg); 259 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg); 260 MBB.erase(MBBI); // Erase the previous return instruction. 261 return; 262 } 263 264 // Work out frame sizes. 265 // We will adjust the SP in stages towards the final FrameSize. 266 int RemainingAdj = MFI->getStackSize(); 267 assert(RemainingAdj%4 == 0 && "Misaligned frame size"); 268 RemainingAdj /= 4; 269 270 bool restoreLR = XFI->hasLRSpillSlot(); 271 bool UseRETSP = restoreLR && RemainingAdj 272 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 273 if (UseRETSP) 274 restoreLR = false; 275 bool FP = hasFP(MF); 276 277 if (FP) // Restore the stack pointer. 278 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); 279 280 // If necessary, restore LR and FP from the stack, as we EXTSP. 281 SmallVector<std::pair<unsigned,int>,2> SpillList; 282 GetSpillList(SpillList, MFI, XFI, restoreLR, FP); 283 unsigned i = SpillList.size(); 284 while (i--) { 285 unsigned SpilledReg = SpillList[i].first; 286 int SpillOffset = SpillList[i].second; 287 assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); 288 assert(SpillOffset <= 0 && "Unexpected positive stack offset"); 289 int OffsetFromTop = - SpillOffset/4; 290 IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj); 291 int Offset = RemainingAdj - OffsetFromTop; 292 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 293 BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpilledReg).addImm(Offset); 294 } 295 296 if (RemainingAdj) { 297 // Complete all but one of the remaining Stack adjustments. 298 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj); 299 if (UseRETSP) { 300 // Fold prologue into return instruction 301 assert(RetOpcode == XCore::RETSP_u6 302 || RetOpcode == XCore::RETSP_lu6); 303 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 304 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)) 305 .addImm(RemainingAdj); 306 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) 307 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands 308 MBB.erase(MBBI); // Erase the previous return instruction. 309 } else { 310 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 : 311 XCore::LDAWSP_lru6; 312 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj); 313 // Don't erase the return instruction. 314 } 315 } // else Don't erase the return instruction. 316 } 317 318 bool XCoreFrameLowering:: 319 spillCalleeSavedRegisters(MachineBasicBlock &MBB, 320 MachineBasicBlock::iterator MI, 321 const std::vector<CalleeSavedInfo> &CSI, 322 const TargetRegisterInfo *TRI) const { 323 if (CSI.empty()) 324 return true; 325 326 MachineFunction *MF = MBB.getParent(); 327 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 328 XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>(); 329 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); 330 331 DebugLoc DL; 332 if (MI != MBB.end()) 333 DL = MI->getDebugLoc(); 334 335 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 336 it != CSI.end(); ++it) { 337 unsigned Reg = it->getReg(); 338 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 339 "LR & FP are always handled in emitPrologue"); 340 341 // Add the callee-saved register as live-in. It's killed at the spill. 342 MBB.addLiveIn(Reg); 343 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 344 TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI); 345 if (emitFrameMoves) { 346 MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol(); 347 BuildMI(MBB, MI, DL, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLabel); 348 XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it)); 349 } 350 } 351 return true; 352 } 353 354 bool XCoreFrameLowering:: 355 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 356 MachineBasicBlock::iterator MI, 357 const std::vector<CalleeSavedInfo> &CSI, 358 const TargetRegisterInfo *TRI) const{ 359 MachineFunction *MF = MBB.getParent(); 360 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 361 bool AtStart = MI == MBB.begin(); 362 MachineBasicBlock::iterator BeforeI = MI; 363 if (!AtStart) 364 --BeforeI; 365 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 366 it != CSI.end(); ++it) { 367 unsigned Reg = it->getReg(); 368 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 369 "LR & FP are always handled in emitEpilogue"); 370 371 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 372 TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI); 373 assert(MI != MBB.begin() && 374 "loadRegFromStackSlot didn't insert any code!"); 375 // Insert in reverse order. loadRegFromStackSlot can insert multiple 376 // instructions. 377 if (AtStart) 378 MI = MBB.begin(); 379 else { 380 MI = BeforeI; 381 ++MI; 382 } 383 } 384 return true; 385 } 386 387 // This function eliminates ADJCALLSTACKDOWN, 388 // ADJCALLSTACKUP pseudo instructions 389 void XCoreFrameLowering:: 390 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 391 MachineBasicBlock::iterator I) const { 392 const XCoreInstrInfo &TII = 393 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 394 if (!hasReservedCallFrame(MF)) { 395 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 396 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 397 MachineInstr *Old = I; 398 uint64_t Amount = Old->getOperand(0).getImm(); 399 if (Amount != 0) { 400 // We need to keep the stack aligned properly. To do this, we round the 401 // amount of space needed for the outgoing arguments up to the next 402 // alignment boundary. 403 unsigned Align = getStackAlignment(); 404 Amount = (Amount+Align-1)/Align*Align; 405 406 assert(Amount%4 == 0); 407 Amount /= 4; 408 409 bool isU6 = isImmU6(Amount); 410 if (!isU6 && !isImmU16(Amount)) { 411 // FIX could emit multiple instructions in this case. 412 #ifndef NDEBUG 413 errs() << "eliminateCallFramePseudoInstr size too big: " 414 << Amount << "\n"; 415 #endif 416 llvm_unreachable(0); 417 } 418 419 MachineInstr *New; 420 if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 421 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 422 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) 423 .addImm(Amount); 424 } else { 425 assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 426 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 427 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) 428 .addImm(Amount); 429 } 430 431 // Replace the pseudo instruction with a new instruction... 432 MBB.insert(I, New); 433 } 434 } 435 436 MBB.erase(I); 437 } 438 439 void XCoreFrameLowering:: 440 processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 441 RegScavenger *RS) const { 442 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 443 444 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 445 // If we need to extend the stack it is more efficient to use entsp / retsp. 446 // We force the LR to be saved so these instructions are used. 447 if (!LRUsed && !MF.getFunction()->isVarArg() && 448 MF.getFrameInfo()->estimateStackSize(MF)) 449 LRUsed = true; 450 // We will be spilling all callee saved registers in case of unwinding. 451 if (MF.getMMI().callsUnwindInit()) 452 LRUsed = true; 453 454 // We will handling LR in the prologue/epilogue 455 // and space on the stack ourselves. 456 if (LRUsed) { 457 MF.getRegInfo().setPhysRegUnused(XCore::LR); 458 XFI->createLRSpillSlot(MF); 459 } 460 461 // A callee save register is used to hold the FP. 462 // This needs saving / restoring in the epilogue / prologue. 463 if (hasFP(MF)) 464 XFI->createFPSpillSlot(MF); 465 } 466 467 void XCoreFrameLowering:: 468 processFunctionBeforeFrameFinalized(MachineFunction &MF, 469 RegScavenger *RS) const { 470 assert(RS && "requiresRegisterScavenging failed"); 471 MachineFrameInfo *MFI = MF.getFrameInfo(); 472 const TargetRegisterClass *RC = &XCore::GRRegsRegClass; 473 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 474 // Reserve slots close to SP or frame pointer for Scavenging spills. 475 // When using SP for small frames, we don't need any scratch registers. 476 // When using SP for large frames, we may need 2 scratch registers. 477 // When using FP, for large or small frames, we may need 1 scratch register. 478 if (XFI->isLargeFrame(MF) || hasFP(MF)) 479 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 480 RC->getAlignment(), 481 false)); 482 if (XFI->isLargeFrame(MF) && !hasFP(MF)) 483 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 484 RC->getAlignment(), 485 false)); 486 } 487