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