1235633Sdim//===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file contains XCore frame information that doesn't fit anywhere else 11218885Sdim// cleanly... 12218885Sdim// 13218885Sdim//===----------------------------------------------------------------------===// 14218885Sdim 15235633Sdim#include "XCoreFrameLowering.h" 16218885Sdim#include "XCore.h" 17218885Sdim#include "XCoreInstrInfo.h" 18218885Sdim#include "XCoreMachineFunctionInfo.h" 19218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 20218885Sdim#include "llvm/CodeGen/MachineFunction.h" 21218885Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 22218885Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 23218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 24218885Sdim#include "llvm/CodeGen/RegisterScavenging.h" 25252723Sdim#include "llvm/IR/DataLayout.h" 26252723Sdim#include "llvm/IR/Function.h" 27252723Sdim#include "llvm/Support/ErrorHandling.h" 28218885Sdim#include "llvm/Target/TargetOptions.h" 29218885Sdim 30218885Sdimusing namespace llvm; 31218885Sdim 32218885Sdim// helper functions. FIXME: Eliminate. 33218885Sdimstatic inline bool isImmU6(unsigned val) { 34218885Sdim return val < (1 << 6); 35218885Sdim} 36218885Sdim 37218885Sdimstatic inline bool isImmU16(unsigned val) { 38218885Sdim return val < (1 << 16); 39218885Sdim} 40218885Sdim 41218885Sdimstatic void loadFromStack(MachineBasicBlock &MBB, 42218885Sdim MachineBasicBlock::iterator I, 43218885Sdim unsigned DstReg, int Offset, DebugLoc dl, 44218885Sdim const TargetInstrInfo &TII) { 45218885Sdim assert(Offset%4 == 0 && "Misaligned stack offset"); 46218885Sdim Offset/=4; 47218885Sdim bool isU6 = isImmU6(Offset); 48218885Sdim if (!isU6 && !isImmU16(Offset)) 49218885Sdim report_fatal_error("loadFromStack offset too big " + Twine(Offset)); 50218885Sdim int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 51218885Sdim BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) 52218885Sdim .addImm(Offset); 53218885Sdim} 54218885Sdim 55218885Sdim 56218885Sdimstatic void storeToStack(MachineBasicBlock &MBB, 57218885Sdim MachineBasicBlock::iterator I, 58218885Sdim unsigned SrcReg, int Offset, DebugLoc dl, 59218885Sdim const TargetInstrInfo &TII) { 60218885Sdim assert(Offset%4 == 0 && "Misaligned stack offset"); 61218885Sdim Offset/=4; 62218885Sdim bool isU6 = isImmU6(Offset); 63218885Sdim if (!isU6 && !isImmU16(Offset)) 64218885Sdim report_fatal_error("storeToStack offset too big " + Twine(Offset)); 65218885Sdim int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 66218885Sdim BuildMI(MBB, I, dl, TII.get(Opcode)) 67218885Sdim .addReg(SrcReg) 68218885Sdim .addImm(Offset); 69218885Sdim} 70218885Sdim 71218885Sdim 72218885Sdim//===----------------------------------------------------------------------===// 73218885Sdim// XCoreFrameLowering: 74218885Sdim//===----------------------------------------------------------------------===// 75218885Sdim 76218885SdimXCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) 77245431Sdim : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) { 78218885Sdim // Do nothing 79218885Sdim} 80218885Sdim 81218885Sdimbool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { 82235633Sdim return MF.getTarget().Options.DisableFramePointerElim(MF) || 83235633Sdim MF.getFrameInfo()->hasVarSizedObjects(); 84218885Sdim} 85218885Sdim 86218885Sdimvoid XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { 87218885Sdim MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 88218885Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 89218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 90218885Sdim MachineModuleInfo *MMI = &MF.getMMI(); 91263509Sdim const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); 92218885Sdim const XCoreInstrInfo &TII = 93218885Sdim *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 94218885Sdim XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 95218885Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 96218885Sdim 97263509Sdim if (MFI->getMaxAlignment() > getStackAlignment()) 98263509Sdim report_fatal_error("emitPrologue unsupported alignment: " 99263509Sdim + Twine(MFI->getMaxAlignment())); 100263509Sdim 101218885Sdim bool FP = hasFP(MF); 102252723Sdim const AttributeSet &PAL = MF.getFunction()->getAttributes(); 103218885Sdim 104252723Sdim if (PAL.hasAttrSomewhere(Attribute::Nest)) 105252723Sdim loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII); 106218885Sdim 107218885Sdim // Work out frame sizes. 108218885Sdim int FrameSize = MFI->getStackSize(); 109218885Sdim assert(FrameSize%4 == 0 && "Misaligned frame size"); 110218885Sdim FrameSize/=4; 111218885Sdim 112218885Sdim bool isU6 = isImmU6(FrameSize); 113218885Sdim 114218885Sdim if (!isU6 && !isImmU16(FrameSize)) { 115218885Sdim // FIXME could emit multiple instructions. 116218885Sdim report_fatal_error("emitPrologue Frame size too big: " + Twine(FrameSize)); 117218885Sdim } 118235633Sdim bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 119218885Sdim 120263509Sdim bool saveLR = XFI->getUsesLR(); 121218885Sdim // Do we need to allocate space on the stack? 122218885Sdim if (FrameSize) { 123218885Sdim bool LRSavedOnEntry = false; 124218885Sdim int Opcode; 125218885Sdim if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { 126218885Sdim Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 127218885Sdim MBB.addLiveIn(XCore::LR); 128218885Sdim saveLR = false; 129218885Sdim LRSavedOnEntry = true; 130218885Sdim } else { 131218885Sdim Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 132218885Sdim } 133218885Sdim BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 134218885Sdim 135218885Sdim if (emitFrameMoves) { 136218885Sdim // Show update of SP. 137218885Sdim MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); 138218885Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); 139263509Sdim MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel, 140263509Sdim -FrameSize*4)); 141218885Sdim if (LRSavedOnEntry) { 142263509Sdim unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); 143263509Sdim MMI->addFrameInst(MCCFIInstruction::createOffset(FrameLabel, Reg, 0)); 144218885Sdim } 145218885Sdim } 146263509Sdim } 147263509Sdim if (saveLR) { 148263509Sdim int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 149263509Sdim storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); 150263509Sdim MBB.addLiveIn(XCore::LR); 151218885Sdim 152263509Sdim if (emitFrameMoves) { 153263509Sdim MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); 154263509Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); 155263509Sdim unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); 156263509Sdim MMI->addFrameInst(MCCFIInstruction::createOffset(SaveLRLabel, Reg, 157263509Sdim LRSpillOffset)); 158218885Sdim } 159218885Sdim } 160218885Sdim 161218885Sdim if (FP) { 162218885Sdim // Save R10 to the stack. 163218885Sdim int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 164218885Sdim storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl, TII); 165218885Sdim // R10 is live-in. It is killed at the spill. 166218885Sdim MBB.addLiveIn(XCore::R10); 167218885Sdim if (emitFrameMoves) { 168218885Sdim MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol(); 169218885Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label); 170263509Sdim unsigned Reg = MRI->getDwarfRegNum(XCore::R10, true); 171263509Sdim MMI->addFrameInst(MCCFIInstruction::createOffset(SaveR10Label, Reg, 172263509Sdim FPSpillOffset)); 173218885Sdim } 174218885Sdim // Set the FP from the SP. 175218885Sdim unsigned FramePtr = XCore::R10; 176263509Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); 177218885Sdim if (emitFrameMoves) { 178218885Sdim // Show FP is now valid. 179218885Sdim MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); 180218885Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); 181263509Sdim unsigned Reg = MRI->getDwarfRegNum(FramePtr, true); 182263509Sdim MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, 183263509Sdim Reg)); 184218885Sdim } 185218885Sdim } 186218885Sdim 187218885Sdim if (emitFrameMoves) { 188218885Sdim // Frame moves for callee saved. 189218885Sdim std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = 190218885Sdim XFI->getSpillLabels(); 191218885Sdim for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 192218885Sdim MCSymbol *SpillLabel = SpillLabels[I].first; 193218885Sdim CalleeSavedInfo &CSI = SpillLabels[I].second; 194218885Sdim int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 195263509Sdim unsigned Reg = MRI->getDwarfRegNum(CSI.getReg(), true); 196263509Sdim MMI->addFrameInst(MCCFIInstruction::createOffset(SpillLabel, Reg, 197263509Sdim Offset)); 198218885Sdim } 199218885Sdim } 200218885Sdim} 201218885Sdim 202218885Sdimvoid XCoreFrameLowering::emitEpilogue(MachineFunction &MF, 203218885Sdim MachineBasicBlock &MBB) const { 204218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 205218885Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 206218885Sdim const XCoreInstrInfo &TII = 207218885Sdim *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 208263509Sdim XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 209218885Sdim DebugLoc dl = MBBI->getDebugLoc(); 210218885Sdim 211218885Sdim bool FP = hasFP(MF); 212218885Sdim if (FP) { 213218885Sdim // Restore the stack pointer. 214218885Sdim unsigned FramePtr = XCore::R10; 215218885Sdim BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) 216218885Sdim .addReg(FramePtr); 217218885Sdim } 218218885Sdim 219218885Sdim // Work out frame sizes. 220218885Sdim int FrameSize = MFI->getStackSize(); 221218885Sdim 222218885Sdim assert(FrameSize%4 == 0 && "Misaligned frame size"); 223218885Sdim 224218885Sdim FrameSize/=4; 225218885Sdim 226218885Sdim bool isU6 = isImmU6(FrameSize); 227218885Sdim 228218885Sdim if (!isU6 && !isImmU16(FrameSize)) { 229218885Sdim // FIXME could emit multiple instructions. 230218885Sdim report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); 231218885Sdim } 232218885Sdim 233263509Sdim if (FP) { 234263509Sdim // Restore R10 235263509Sdim int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 236263509Sdim FPSpillOffset += FrameSize*4; 237263509Sdim loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); 238263509Sdim } 239263509Sdim 240263509Sdim bool restoreLR = XFI->getUsesLR(); 241263509Sdim if (restoreLR && 242263509Sdim (FrameSize == 0 || MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0)) { 243263509Sdim int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 244263509Sdim LRSpillOffset += FrameSize*4; 245263509Sdim loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); 246263509Sdim restoreLR = false; 247263509Sdim } 248263509Sdim 249218885Sdim if (FrameSize) { 250218885Sdim if (restoreLR) { 251218885Sdim // Fold prologue into return instruction 252263509Sdim assert(MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 253218885Sdim assert(MBBI->getOpcode() == XCore::RETSP_u6 254218885Sdim || MBBI->getOpcode() == XCore::RETSP_lu6); 255218885Sdim int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 256263509Sdim MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 257263509Sdim for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) 258263509Sdim MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands 259218885Sdim MBB.erase(MBBI); 260218885Sdim } else { 261252723Sdim int Opcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 262218885Sdim BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); 263218885Sdim } 264218885Sdim } 265218885Sdim} 266218885Sdim 267218885Sdimbool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 268218885Sdim MachineBasicBlock::iterator MI, 269218885Sdim const std::vector<CalleeSavedInfo> &CSI, 270218885Sdim const TargetRegisterInfo *TRI) const { 271218885Sdim if (CSI.empty()) 272218885Sdim return true; 273218885Sdim 274218885Sdim MachineFunction *MF = MBB.getParent(); 275218885Sdim const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 276218885Sdim 277218885Sdim XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>(); 278218885Sdim bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); 279218885Sdim 280218885Sdim DebugLoc DL; 281218885Sdim if (MI != MBB.end()) DL = MI->getDebugLoc(); 282218885Sdim 283218885Sdim for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 284218885Sdim it != CSI.end(); ++it) { 285218885Sdim // Add the callee-saved register as live-in. It's killed at the spill. 286218885Sdim MBB.addLiveIn(it->getReg()); 287218885Sdim 288218885Sdim unsigned Reg = it->getReg(); 289218885Sdim const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 290218885Sdim TII.storeRegToStackSlot(MBB, MI, Reg, true, 291218885Sdim it->getFrameIdx(), RC, TRI); 292218885Sdim if (emitFrameMoves) { 293218885Sdim MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol(); 294218885Sdim BuildMI(MBB, MI, DL, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLabel); 295218885Sdim XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it)); 296218885Sdim } 297218885Sdim } 298218885Sdim return true; 299218885Sdim} 300218885Sdim 301218885Sdimbool XCoreFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 302218885Sdim MachineBasicBlock::iterator MI, 303218885Sdim const std::vector<CalleeSavedInfo> &CSI, 304218885Sdim const TargetRegisterInfo *TRI) const{ 305218885Sdim MachineFunction *MF = MBB.getParent(); 306218885Sdim const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 307218885Sdim 308218885Sdim bool AtStart = MI == MBB.begin(); 309218885Sdim MachineBasicBlock::iterator BeforeI = MI; 310218885Sdim if (!AtStart) 311218885Sdim --BeforeI; 312218885Sdim for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 313218885Sdim it != CSI.end(); ++it) { 314218885Sdim unsigned Reg = it->getReg(); 315218885Sdim const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 316218885Sdim TII.loadRegFromStackSlot(MBB, MI, it->getReg(), it->getFrameIdx(), 317218885Sdim RC, TRI); 318218885Sdim assert(MI != MBB.begin() && 319218885Sdim "loadRegFromStackSlot didn't insert any code!"); 320218885Sdim // Insert in reverse order. loadRegFromStackSlot can insert multiple 321218885Sdim // instructions. 322218885Sdim if (AtStart) 323218885Sdim MI = MBB.begin(); 324218885Sdim else { 325218885Sdim MI = BeforeI; 326218885Sdim ++MI; 327218885Sdim } 328218885Sdim } 329218885Sdim return true; 330218885Sdim} 331218885Sdim 332252723Sdim// This function eliminates ADJCALLSTACKDOWN, 333252723Sdim// ADJCALLSTACKUP pseudo instructions 334252723Sdimvoid XCoreFrameLowering:: 335252723SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 336252723Sdim MachineBasicBlock::iterator I) const { 337252723Sdim const XCoreInstrInfo &TII = 338252723Sdim *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 339252723Sdim if (!hasReservedCallFrame(MF)) { 340252723Sdim // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 341252723Sdim // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 342252723Sdim MachineInstr *Old = I; 343252723Sdim uint64_t Amount = Old->getOperand(0).getImm(); 344252723Sdim if (Amount != 0) { 345252723Sdim // We need to keep the stack aligned properly. To do this, we round the 346252723Sdim // amount of space needed for the outgoing arguments up to the next 347252723Sdim // alignment boundary. 348252723Sdim unsigned Align = getStackAlignment(); 349252723Sdim Amount = (Amount+Align-1)/Align*Align; 350252723Sdim 351252723Sdim assert(Amount%4 == 0); 352252723Sdim Amount /= 4; 353252723Sdim 354252723Sdim bool isU6 = isImmU6(Amount); 355252723Sdim if (!isU6 && !isImmU16(Amount)) { 356252723Sdim // FIX could emit multiple instructions in this case. 357252723Sdim#ifndef NDEBUG 358252723Sdim errs() << "eliminateCallFramePseudoInstr size too big: " 359252723Sdim << Amount << "\n"; 360252723Sdim#endif 361252723Sdim llvm_unreachable(0); 362252723Sdim } 363252723Sdim 364252723Sdim MachineInstr *New; 365252723Sdim if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 366252723Sdim int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 367252723Sdim New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) 368252723Sdim .addImm(Amount); 369252723Sdim } else { 370252723Sdim assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 371252723Sdim int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 372252723Sdim New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) 373252723Sdim .addImm(Amount); 374252723Sdim } 375252723Sdim 376252723Sdim // Replace the pseudo instruction with a new instruction... 377252723Sdim MBB.insert(I, New); 378252723Sdim } 379252723Sdim } 380252723Sdim 381252723Sdim MBB.erase(I); 382252723Sdim} 383252723Sdim 384218885Sdimvoid 385218885SdimXCoreFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 386218885Sdim RegScavenger *RS) const { 387218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 388218885Sdim const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); 389218885Sdim bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 390245431Sdim const TargetRegisterClass *RC = &XCore::GRRegsRegClass; 391218885Sdim XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 392218885Sdim if (LRUsed) { 393218885Sdim MF.getRegInfo().setPhysRegUnused(XCore::LR); 394218885Sdim 395218885Sdim bool isVarArg = MF.getFunction()->isVarArg(); 396218885Sdim int FrameIdx; 397218885Sdim if (! isVarArg) { 398218885Sdim // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. 399218885Sdim FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true); 400218885Sdim } else { 401218885Sdim FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), 402218885Sdim false); 403218885Sdim } 404218885Sdim XFI->setUsesLR(FrameIdx); 405218885Sdim XFI->setLRSpillSlot(FrameIdx); 406218885Sdim } 407218885Sdim if (RegInfo->requiresRegisterScavenging(MF)) { 408218885Sdim // Reserve a slot close to SP or frame pointer. 409252723Sdim RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 410218885Sdim RC->getAlignment(), 411218885Sdim false)); 412218885Sdim } 413218885Sdim if (hasFP(MF)) { 414218885Sdim // A callee save register is used to hold the FP. 415218885Sdim // This needs saving / restoring in the epilogue / prologue. 416218885Sdim XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), 417218885Sdim RC->getAlignment(), 418218885Sdim false)); 419218885Sdim } 420218885Sdim} 421