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/TargetLowering.h" 29 #include "llvm/Target/TargetOptions.h" 30 31 #include <algorithm> // std::sort 32 33 using namespace llvm; 34 35 static const unsigned FramePtr = XCore::R10; 36 static const int MaxImmU16 = (1<<16) - 1; 37 38 // helper functions. FIXME: Eliminate. 39 static inline bool isImmU6(unsigned val) { 40 return val < (1 << 6); 41 } 42 43 static inline bool isImmU16(unsigned val) { 44 return val < (1 << 16); 45 } 46 47 // Helper structure with compare function for handling stack slots. 48 namespace { 49 struct StackSlotInfo { 50 int FI; 51 int Offset; 52 unsigned Reg; 53 StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){}; 54 }; 55 } // end anonymous namespace 56 57 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) { 58 return a.Offset < b.Offset; 59 } 60 61 62 static void EmitDefCfaRegister(MachineBasicBlock &MBB, 63 MachineBasicBlock::iterator MBBI, DebugLoc dl, 64 const TargetInstrInfo &TII, 65 MachineModuleInfo *MMI, unsigned DRegNum) { 66 MCSymbol *Label = MMI->getContext().CreateTempSymbol(); 67 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 68 MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(Label, DRegNum)); 69 } 70 71 static void EmitDefCfaOffset(MachineBasicBlock &MBB, 72 MachineBasicBlock::iterator MBBI, DebugLoc dl, 73 const TargetInstrInfo &TII, 74 MachineModuleInfo *MMI, int Offset) { 75 MCSymbol *Label = MMI->getContext().CreateTempSymbol(); 76 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 77 MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(Label, -Offset)); 78 } 79 80 static void EmitCfiOffset(MachineBasicBlock &MBB, 81 MachineBasicBlock::iterator MBBI, DebugLoc dl, 82 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 83 unsigned DRegNum, int Offset, MCSymbol *Label) { 84 if (!Label) { 85 Label = MMI->getContext().CreateTempSymbol(); 86 BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label); 87 } 88 MMI->addFrameInst(MCCFIInstruction::createOffset(Label, DRegNum, Offset)); 89 } 90 91 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the 92 /// frame. During these steps, it may be necessary to spill registers. 93 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only 94 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6. 95 /// \param OffsetFromTop the spill offset from the top of the frame. 96 /// \param [in,out] Adjusted the current SP offset from the top of the frame. 97 static void IfNeededExtSP(MachineBasicBlock &MBB, 98 MachineBasicBlock::iterator MBBI, DebugLoc dl, 99 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 100 int OffsetFromTop, int &Adjusted, int FrameSize, 101 bool emitFrameMoves) { 102 while (OffsetFromTop > Adjusted) { 103 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize"); 104 int remaining = FrameSize - Adjusted; 105 int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining; 106 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 107 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm); 108 Adjusted += OpImm; 109 if (emitFrameMoves) 110 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 111 } 112 } 113 114 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the 115 /// frame. During these steps, it may be necessary to re-load registers. 116 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only 117 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6. 118 /// \param OffsetFromTop the spill offset from the top of the frame. 119 /// \param [in,out] RemainingAdj the current SP offset from the top of the frame. 120 static void IfNeededLDAWSP(MachineBasicBlock &MBB, 121 MachineBasicBlock::iterator MBBI, DebugLoc dl, 122 const TargetInstrInfo &TII, int OffsetFromTop, 123 int &RemainingAdj) { 124 while (OffsetFromTop < RemainingAdj - MaxImmU16) { 125 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize"); 126 int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj; 127 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 128 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm); 129 RemainingAdj -= OpImm; 130 } 131 } 132 133 /// Creates an ordered list of registers that are spilled 134 /// during the emitPrologue/emitEpilogue. 135 /// Registers are ordered according to their frame offset. 136 /// As offsets are negative, the largest offsets will be first. 137 static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, 138 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, 139 bool fetchLR, bool fetchFP) { 140 if (fetchLR) { 141 int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 142 SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(), 143 Offset, 144 XCore::LR)); 145 } 146 if (fetchFP) { 147 int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 148 SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(), 149 Offset, 150 FramePtr)); 151 } 152 std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); 153 } 154 155 /// Creates an ordered list of EH info register 'spills'. 156 /// These slots are only used by the unwinder and calls to llvm.eh.return(). 157 /// Registers are ordered according to their frame offset. 158 /// As offsets are negative, the largest offsets will be first. 159 static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, 160 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, 161 const TargetLowering *TL) { 162 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots"); 163 const int* EHSlot = XFI->getEHSpillSlot(); 164 SpillList.push_back(StackSlotInfo(EHSlot[0], 165 MFI->getObjectOffset(EHSlot[0]), 166 TL->getExceptionPointerRegister())); 167 SpillList.push_back(StackSlotInfo(EHSlot[0], 168 MFI->getObjectOffset(EHSlot[1]), 169 TL->getExceptionSelectorRegister())); 170 std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); 171 } 172 173 174 static MachineMemOperand * 175 getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) { 176 MachineFunction *MF = MBB.getParent(); 177 const MachineFrameInfo &MFI = *MF->getFrameInfo(); 178 MachineMemOperand *MMO = 179 MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), 180 flags, MFI.getObjectSize(FrameIndex), 181 MFI.getObjectAlignment(FrameIndex)); 182 return MMO; 183 } 184 185 186 /// Restore clobbered registers with their spill slot value. 187 /// The SP will be adjusted at the same time, thus the SpillList must be ordered 188 /// with the largest (negative) offsets first. 189 static void 190 RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 191 DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, 192 SmallVectorImpl<StackSlotInfo> &SpillList) { 193 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 194 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); 195 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); 196 int OffsetFromTop = - SpillList[i].Offset/4; 197 IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj); 198 int Offset = RemainingAdj - OffsetFromTop; 199 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 200 BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg) 201 .addImm(Offset) 202 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, 203 MachineMemOperand::MOLoad)); 204 } 205 } 206 207 //===----------------------------------------------------------------------===// 208 // XCoreFrameLowering: 209 //===----------------------------------------------------------------------===// 210 211 XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) 212 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) { 213 // Do nothing 214 } 215 216 bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { 217 return MF.getTarget().Options.DisableFramePointerElim(MF) || 218 MF.getFrameInfo()->hasVarSizedObjects(); 219 } 220 221 void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { 222 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 223 MachineBasicBlock::iterator MBBI = MBB.begin(); 224 MachineFrameInfo *MFI = MF.getFrameInfo(); 225 MachineModuleInfo *MMI = &MF.getMMI(); 226 const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); 227 const XCoreInstrInfo &TII = 228 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 229 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 230 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 231 232 if (MFI->getMaxAlignment() > getStackAlignment()) 233 report_fatal_error("emitPrologue unsupported alignment: " 234 + Twine(MFI->getMaxAlignment())); 235 236 const AttributeSet &PAL = MF.getFunction()->getAttributes(); 237 if (PAL.hasAttrSomewhere(Attribute::Nest)) 238 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); 239 // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack(). 240 241 // Work out frame sizes. 242 // We will adjust the SP in stages towards the final FrameSize. 243 assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size"); 244 const int FrameSize = MFI->getStackSize() / 4; 245 int Adjusted = 0; 246 247 bool saveLR = XFI->hasLRSpillSlot(); 248 bool UseENTSP = saveLR && FrameSize 249 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 250 if (UseENTSP) 251 saveLR = false; 252 bool FP = hasFP(MF); 253 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 254 255 if (UseENTSP) { 256 // Allocate space on the stack at the same time as saving LR. 257 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize; 258 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 259 MBB.addLiveIn(XCore::LR); 260 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)); 261 MIB.addImm(Adjusted); 262 MIB->addRegisterKilled(XCore::LR, MF.getTarget().getRegisterInfo(), true); 263 if (emitFrameMoves) { 264 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 265 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true); 266 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0, NULL); 267 } 268 } 269 270 // If necessary, save LR and FP to the stack, as we EXTSP. 271 SmallVector<StackSlotInfo,2> SpillList; 272 GetSpillList(SpillList, MFI, XFI, saveLR, FP); 273 // We want the nearest (negative) offsets first, so reverse list. 274 std::reverse(SpillList.begin(), SpillList.end()); 275 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 276 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); 277 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); 278 int OffsetFromTop = - SpillList[i].Offset/4; 279 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize, 280 emitFrameMoves); 281 int Offset = Adjusted - OffsetFromTop; 282 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 283 MBB.addLiveIn(SpillList[i].Reg); 284 BuildMI(MBB, MBBI, dl, TII.get(Opcode)) 285 .addReg(SpillList[i].Reg, RegState::Kill) 286 .addImm(Offset) 287 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, 288 MachineMemOperand::MOStore)); 289 if (emitFrameMoves) { 290 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true); 291 EmitCfiOffset(MBB,MBBI,dl,TII,MMI, DRegNum, SpillList[i].Offset, NULL); 292 } 293 } 294 295 // Complete any remaining Stack adjustment. 296 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize, 297 emitFrameMoves); 298 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment"); 299 300 if (FP) { 301 // Set the FP from the SP. 302 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); 303 if (emitFrameMoves) 304 EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, 305 MRI->getDwarfRegNum(FramePtr, true)); 306 } 307 308 if (emitFrameMoves) { 309 // Frame moves for callee saved. 310 std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = 311 XFI->getSpillLabels(); 312 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 313 MCSymbol *SpillLabel = SpillLabels[I].first; 314 CalleeSavedInfo &CSI = SpillLabels[I].second; 315 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 316 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); 317 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, Offset, SpillLabel); 318 } 319 if (XFI->hasEHSpillSlot()) { 320 // The unwinder requires stack slot & CFI offsets for the exception info. 321 // We do not save/spill these registers. 322 SmallVector<StackSlotInfo,2> SpillList; 323 GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); 324 assert(SpillList.size()==2 && "Unexpected SpillList size"); 325 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, 326 MRI->getDwarfRegNum(SpillList[0].Reg, true), 327 SpillList[0].Offset, NULL); 328 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, 329 MRI->getDwarfRegNum(SpillList[1].Reg, true), 330 SpillList[1].Offset, NULL); 331 } 332 } 333 } 334 335 void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, 336 MachineBasicBlock &MBB) const { 337 MachineFrameInfo *MFI = MF.getFrameInfo(); 338 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 339 const XCoreInstrInfo &TII = 340 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 341 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 342 DebugLoc dl = MBBI->getDebugLoc(); 343 unsigned RetOpcode = MBBI->getOpcode(); 344 345 // Work out frame sizes. 346 // We will adjust the SP in stages towards the final FrameSize. 347 int RemainingAdj = MFI->getStackSize(); 348 assert(RemainingAdj%4 == 0 && "Misaligned frame size"); 349 RemainingAdj /= 4; 350 351 if (RetOpcode == XCore::EH_RETURN) { 352 // 'Restore' the exception info the unwinder has placed into the stack slots. 353 SmallVector<StackSlotInfo,2> SpillList; 354 GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); 355 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); 356 357 // Return to the landing pad. 358 unsigned EhStackReg = MBBI->getOperand(0).getReg(); 359 unsigned EhHandlerReg = MBBI->getOperand(1).getReg(); 360 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg); 361 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg); 362 MBB.erase(MBBI); // Erase the previous return instruction. 363 return; 364 } 365 366 bool restoreLR = XFI->hasLRSpillSlot(); 367 bool UseRETSP = restoreLR && RemainingAdj 368 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 369 if (UseRETSP) 370 restoreLR = false; 371 bool FP = hasFP(MF); 372 373 if (FP) // Restore the stack pointer. 374 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); 375 376 // If necessary, restore LR and FP from the stack, as we EXTSP. 377 SmallVector<StackSlotInfo,2> SpillList; 378 GetSpillList(SpillList, MFI, XFI, restoreLR, FP); 379 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); 380 381 if (RemainingAdj) { 382 // Complete all but one of the remaining Stack adjustments. 383 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj); 384 if (UseRETSP) { 385 // Fold prologue into return instruction 386 assert(RetOpcode == XCore::RETSP_u6 387 || RetOpcode == XCore::RETSP_lu6); 388 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 389 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)) 390 .addImm(RemainingAdj); 391 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) 392 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands 393 MBB.erase(MBBI); // Erase the previous return instruction. 394 } else { 395 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 : 396 XCore::LDAWSP_lru6; 397 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj); 398 // Don't erase the return instruction. 399 } 400 } // else Don't erase the return instruction. 401 } 402 403 bool XCoreFrameLowering:: 404 spillCalleeSavedRegisters(MachineBasicBlock &MBB, 405 MachineBasicBlock::iterator MI, 406 const std::vector<CalleeSavedInfo> &CSI, 407 const TargetRegisterInfo *TRI) const { 408 if (CSI.empty()) 409 return true; 410 411 MachineFunction *MF = MBB.getParent(); 412 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 413 XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>(); 414 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); 415 416 DebugLoc DL; 417 if (MI != MBB.end()) 418 DL = MI->getDebugLoc(); 419 420 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 421 it != CSI.end(); ++it) { 422 unsigned Reg = it->getReg(); 423 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 424 "LR & FP are always handled in emitPrologue"); 425 426 // Add the callee-saved register as live-in. It's killed at the spill. 427 MBB.addLiveIn(Reg); 428 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 429 TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI); 430 if (emitFrameMoves) { 431 MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol(); 432 BuildMI(MBB, MI, DL, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLabel); 433 XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it)); 434 } 435 } 436 return true; 437 } 438 439 bool XCoreFrameLowering:: 440 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 441 MachineBasicBlock::iterator MI, 442 const std::vector<CalleeSavedInfo> &CSI, 443 const TargetRegisterInfo *TRI) const{ 444 MachineFunction *MF = MBB.getParent(); 445 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); 446 bool AtStart = MI == MBB.begin(); 447 MachineBasicBlock::iterator BeforeI = MI; 448 if (!AtStart) 449 --BeforeI; 450 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 451 it != CSI.end(); ++it) { 452 unsigned Reg = it->getReg(); 453 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 454 "LR & FP are always handled in emitEpilogue"); 455 456 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 457 TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI); 458 assert(MI != MBB.begin() && 459 "loadRegFromStackSlot didn't insert any code!"); 460 // Insert in reverse order. loadRegFromStackSlot can insert multiple 461 // instructions. 462 if (AtStart) 463 MI = MBB.begin(); 464 else { 465 MI = BeforeI; 466 ++MI; 467 } 468 } 469 return true; 470 } 471 472 // This function eliminates ADJCALLSTACKDOWN, 473 // ADJCALLSTACKUP pseudo instructions 474 void XCoreFrameLowering:: 475 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 476 MachineBasicBlock::iterator I) const { 477 const XCoreInstrInfo &TII = 478 *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 479 if (!hasReservedCallFrame(MF)) { 480 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 481 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 482 MachineInstr *Old = I; 483 uint64_t Amount = Old->getOperand(0).getImm(); 484 if (Amount != 0) { 485 // We need to keep the stack aligned properly. To do this, we round the 486 // amount of space needed for the outgoing arguments up to the next 487 // alignment boundary. 488 unsigned Align = getStackAlignment(); 489 Amount = (Amount+Align-1)/Align*Align; 490 491 assert(Amount%4 == 0); 492 Amount /= 4; 493 494 bool isU6 = isImmU6(Amount); 495 if (!isU6 && !isImmU16(Amount)) { 496 // FIX could emit multiple instructions in this case. 497 #ifndef NDEBUG 498 errs() << "eliminateCallFramePseudoInstr size too big: " 499 << Amount << "\n"; 500 #endif 501 llvm_unreachable(0); 502 } 503 504 MachineInstr *New; 505 if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 506 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 507 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) 508 .addImm(Amount); 509 } else { 510 assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 511 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 512 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) 513 .addImm(Amount); 514 } 515 516 // Replace the pseudo instruction with a new instruction... 517 MBB.insert(I, New); 518 } 519 } 520 521 MBB.erase(I); 522 } 523 524 void XCoreFrameLowering:: 525 processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 526 RegScavenger *RS) const { 527 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 528 529 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 530 531 if (!LRUsed && !MF.getFunction()->isVarArg() && 532 MF.getFrameInfo()->estimateStackSize(MF)) 533 // If we need to extend the stack it is more efficient to use entsp / retsp. 534 // We force the LR to be saved so these instructions are used. 535 LRUsed = true; 536 537 if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) { 538 // The unwinder expects to find spill slots for the exception info regs R0 539 // & R1. These are used during llvm.eh.return() to 'restore' the exception 540 // info. N.B. we do not spill or restore R0, R1 during normal operation. 541 XFI->createEHSpillSlot(MF); 542 // As we will have a stack, we force the LR to be saved. 543 LRUsed = true; 544 } 545 546 if (LRUsed) { 547 // We will handle the LR in the prologue/epilogue 548 // and allocate space on the stack ourselves. 549 MF.getRegInfo().setPhysRegUnused(XCore::LR); 550 XFI->createLRSpillSlot(MF); 551 } 552 553 if (hasFP(MF)) 554 // A callee save register is used to hold the FP. 555 // This needs saving / restoring in the epilogue / prologue. 556 XFI->createFPSpillSlot(MF); 557 } 558 559 void XCoreFrameLowering:: 560 processFunctionBeforeFrameFinalized(MachineFunction &MF, 561 RegScavenger *RS) const { 562 assert(RS && "requiresRegisterScavenging failed"); 563 MachineFrameInfo *MFI = MF.getFrameInfo(); 564 const TargetRegisterClass *RC = &XCore::GRRegsRegClass; 565 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 566 // Reserve slots close to SP or frame pointer for Scavenging spills. 567 // When using SP for small frames, we don't need any scratch registers. 568 // When using SP for large frames, we may need 2 scratch registers. 569 // When using FP, for large or small frames, we may need 1 scratch register. 570 if (XFI->isLargeFrame(MF) || hasFP(MF)) 571 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 572 RC->getAlignment(), 573 false)); 574 if (XFI->isLargeFrame(MF) && !hasFP(MF)) 575 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 576 RC->getAlignment(), 577 false)); 578 } 579