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