1 //===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===// 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 #include "SystemZFrameLowering.h" 10 #include "SystemZCallingConv.h" 11 #include "SystemZInstrBuilder.h" 12 #include "SystemZInstrInfo.h" 13 #include "SystemZMachineFunctionInfo.h" 14 #include "SystemZRegisterInfo.h" 15 #include "SystemZSubtarget.h" 16 #include "llvm/CodeGen/MachineModuleInfo.h" 17 #include "llvm/CodeGen/MachineRegisterInfo.h" 18 #include "llvm/CodeGen/RegisterScavenging.h" 19 #include "llvm/IR/Function.h" 20 21 using namespace llvm; 22 23 namespace { 24 // The ABI-defined register save slots, relative to the incoming stack 25 // pointer. 26 static const TargetFrameLowering::SpillSlot SpillOffsetTable[] = { 27 { SystemZ::R2D, 0x10 }, 28 { SystemZ::R3D, 0x18 }, 29 { SystemZ::R4D, 0x20 }, 30 { SystemZ::R5D, 0x28 }, 31 { SystemZ::R6D, 0x30 }, 32 { SystemZ::R7D, 0x38 }, 33 { SystemZ::R8D, 0x40 }, 34 { SystemZ::R9D, 0x48 }, 35 { SystemZ::R10D, 0x50 }, 36 { SystemZ::R11D, 0x58 }, 37 { SystemZ::R12D, 0x60 }, 38 { SystemZ::R13D, 0x68 }, 39 { SystemZ::R14D, 0x70 }, 40 { SystemZ::R15D, 0x78 }, 41 { SystemZ::F0D, 0x80 }, 42 { SystemZ::F2D, 0x88 }, 43 { SystemZ::F4D, 0x90 }, 44 { SystemZ::F6D, 0x98 } 45 }; 46 } // end anonymous namespace 47 48 SystemZFrameLowering::SystemZFrameLowering() 49 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8), 50 -SystemZMC::CallFrameSize, Align(8), 51 false /* StackRealignable */) { 52 // Create a mapping from register number to save slot offset. 53 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); 54 for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I) 55 RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset; 56 } 57 58 const TargetFrameLowering::SpillSlot * 59 SystemZFrameLowering::getCalleeSavedSpillSlots(unsigned &NumEntries) const { 60 NumEntries = array_lengthof(SpillOffsetTable); 61 return SpillOffsetTable; 62 } 63 64 void SystemZFrameLowering::determineCalleeSaves(MachineFunction &MF, 65 BitVector &SavedRegs, 66 RegScavenger *RS) const { 67 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 68 69 MachineFrameInfo &MFFrame = MF.getFrameInfo(); 70 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 71 bool HasFP = hasFP(MF); 72 SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); 73 bool IsVarArg = MF.getFunction().isVarArg(); 74 75 // va_start stores incoming FPR varargs in the normal way, but delegates 76 // the saving of incoming GPR varargs to spillCalleeSavedRegisters(). 77 // Record these pending uses, which typically include the call-saved 78 // argument register R6D. 79 if (IsVarArg) 80 for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 81 SavedRegs.set(SystemZ::ArgGPRs[I]); 82 83 // If there are any landing pads, entering them will modify r6/r7. 84 if (!MF.getLandingPads().empty()) { 85 SavedRegs.set(SystemZ::R6D); 86 SavedRegs.set(SystemZ::R7D); 87 } 88 89 // If the function requires a frame pointer, record that the hard 90 // frame pointer will be clobbered. 91 if (HasFP) 92 SavedRegs.set(SystemZ::R11D); 93 94 // If the function calls other functions, record that the return 95 // address register will be clobbered. 96 if (MFFrame.hasCalls()) 97 SavedRegs.set(SystemZ::R14D); 98 99 // If we are saving GPRs other than the stack pointer, we might as well 100 // save and restore the stack pointer at the same time, via STMG and LMG. 101 // This allows the deallocation to be done by the LMG, rather than needing 102 // a separate %r15 addition. 103 const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF); 104 for (unsigned I = 0; CSRegs[I]; ++I) { 105 unsigned Reg = CSRegs[I]; 106 if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) { 107 SavedRegs.set(SystemZ::R15D); 108 break; 109 } 110 } 111 } 112 113 // Add GPR64 to the save instruction being built by MIB, which is in basic 114 // block MBB. IsImplicit says whether this is an explicit operand to the 115 // instruction, or an implicit one that comes between the explicit start 116 // and end registers. 117 static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, 118 unsigned GPR64, bool IsImplicit) { 119 const TargetRegisterInfo *RI = 120 MBB.getParent()->getSubtarget().getRegisterInfo(); 121 Register GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32); 122 bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32); 123 if (!IsLive || !IsImplicit) { 124 MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive)); 125 if (!IsLive) 126 MBB.addLiveIn(GPR64); 127 } 128 } 129 130 bool SystemZFrameLowering:: 131 spillCalleeSavedRegisters(MachineBasicBlock &MBB, 132 MachineBasicBlock::iterator MBBI, 133 const std::vector<CalleeSavedInfo> &CSI, 134 const TargetRegisterInfo *TRI) const { 135 if (CSI.empty()) 136 return false; 137 138 MachineFunction &MF = *MBB.getParent(); 139 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 140 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 141 bool IsVarArg = MF.getFunction().isVarArg(); 142 DebugLoc DL; 143 144 // Scan the call-saved GPRs and find the bounds of the register spill area. 145 unsigned LowGPR = 0; 146 unsigned HighGPR = SystemZ::R15D; 147 unsigned StartOffset = -1U; 148 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 149 unsigned Reg = CSI[I].getReg(); 150 if (SystemZ::GR64BitRegClass.contains(Reg)) { 151 unsigned Offset = RegSpillOffsets[Reg]; 152 assert(Offset && "Unexpected GPR save"); 153 if (StartOffset > Offset) { 154 LowGPR = Reg; 155 StartOffset = Offset; 156 } 157 } 158 } 159 160 // Save the range of call-saved registers, for use by the epilogue inserter. 161 ZFI->setLowSavedGPR(LowGPR); 162 ZFI->setHighSavedGPR(HighGPR); 163 164 // Include the GPR varargs, if any. R6D is call-saved, so would 165 // be included by the loop above, but we also need to handle the 166 // call-clobbered argument registers. 167 if (IsVarArg) { 168 unsigned FirstGPR = ZFI->getVarArgsFirstGPR(); 169 if (FirstGPR < SystemZ::NumArgGPRs) { 170 unsigned Reg = SystemZ::ArgGPRs[FirstGPR]; 171 unsigned Offset = RegSpillOffsets[Reg]; 172 if (StartOffset > Offset) { 173 LowGPR = Reg; StartOffset = Offset; 174 } 175 } 176 } 177 178 // Save GPRs 179 if (LowGPR) { 180 assert(LowGPR != HighGPR && "Should be saving %r15 and something else"); 181 182 // Build an STMG instruction. 183 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG)); 184 185 // Add the explicit register operands. 186 addSavedGPR(MBB, MIB, LowGPR, false); 187 addSavedGPR(MBB, MIB, HighGPR, false); 188 189 // Add the address. 190 MIB.addReg(SystemZ::R15D).addImm(StartOffset); 191 192 // Make sure all call-saved GPRs are included as operands and are 193 // marked as live on entry. 194 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 195 unsigned Reg = CSI[I].getReg(); 196 if (SystemZ::GR64BitRegClass.contains(Reg)) 197 addSavedGPR(MBB, MIB, Reg, true); 198 } 199 200 // ...likewise GPR varargs. 201 if (IsVarArg) 202 for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 203 addSavedGPR(MBB, MIB, SystemZ::ArgGPRs[I], true); 204 } 205 206 // Save FPRs/VRs in the normal TargetInstrInfo way. 207 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 208 unsigned Reg = CSI[I].getReg(); 209 if (SystemZ::FP64BitRegClass.contains(Reg)) { 210 MBB.addLiveIn(Reg); 211 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(), 212 &SystemZ::FP64BitRegClass, TRI); 213 } 214 if (SystemZ::VR128BitRegClass.contains(Reg)) { 215 MBB.addLiveIn(Reg); 216 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(), 217 &SystemZ::VR128BitRegClass, TRI); 218 } 219 } 220 221 return true; 222 } 223 224 bool SystemZFrameLowering:: 225 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 226 MachineBasicBlock::iterator MBBI, 227 std::vector<CalleeSavedInfo> &CSI, 228 const TargetRegisterInfo *TRI) const { 229 if (CSI.empty()) 230 return false; 231 232 MachineFunction &MF = *MBB.getParent(); 233 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 234 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 235 bool HasFP = hasFP(MF); 236 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 237 238 // Restore FPRs/VRs in the normal TargetInstrInfo way. 239 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 240 unsigned Reg = CSI[I].getReg(); 241 if (SystemZ::FP64BitRegClass.contains(Reg)) 242 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), 243 &SystemZ::FP64BitRegClass, TRI); 244 if (SystemZ::VR128BitRegClass.contains(Reg)) 245 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), 246 &SystemZ::VR128BitRegClass, TRI); 247 } 248 249 // Restore call-saved GPRs (but not call-clobbered varargs, which at 250 // this point might hold return values). 251 unsigned LowGPR = ZFI->getLowSavedGPR(); 252 unsigned HighGPR = ZFI->getHighSavedGPR(); 253 unsigned StartOffset = RegSpillOffsets[LowGPR]; 254 if (LowGPR) { 255 // If we saved any of %r2-%r5 as varargs, we should also be saving 256 // and restoring %r6. If we're saving %r6 or above, we should be 257 // restoring it too. 258 assert(LowGPR != HighGPR && "Should be loading %r15 and something else"); 259 260 // Build an LMG instruction. 261 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG)); 262 263 // Add the explicit register operands. 264 MIB.addReg(LowGPR, RegState::Define); 265 MIB.addReg(HighGPR, RegState::Define); 266 267 // Add the address. 268 MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D); 269 MIB.addImm(StartOffset); 270 271 // Do a second scan adding regs as being defined by instruction 272 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 273 unsigned Reg = CSI[I].getReg(); 274 if (Reg != LowGPR && Reg != HighGPR && 275 SystemZ::GR64BitRegClass.contains(Reg)) 276 MIB.addReg(Reg, RegState::ImplicitDefine); 277 } 278 } 279 280 return true; 281 } 282 283 void SystemZFrameLowering:: 284 processFunctionBeforeFrameFinalized(MachineFunction &MF, 285 RegScavenger *RS) const { 286 MachineFrameInfo &MFFrame = MF.getFrameInfo(); 287 // Get the size of our stack frame to be allocated ... 288 uint64_t StackSize = (MFFrame.estimateStackSize(MF) + 289 SystemZMC::CallFrameSize); 290 // ... and the maximum offset we may need to reach into the 291 // caller's frame to access the save area or stack arguments. 292 int64_t MaxArgOffset = SystemZMC::CallFrameSize; 293 for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) 294 if (MFFrame.getObjectOffset(I) >= 0) { 295 int64_t ArgOffset = SystemZMC::CallFrameSize + 296 MFFrame.getObjectOffset(I) + 297 MFFrame.getObjectSize(I); 298 MaxArgOffset = std::max(MaxArgOffset, ArgOffset); 299 } 300 301 uint64_t MaxReach = StackSize + MaxArgOffset; 302 if (!isUInt<12>(MaxReach)) { 303 // We may need register scavenging slots if some parts of the frame 304 // are outside the reach of an unsigned 12-bit displacement. 305 // Create 2 for the case where both addresses in an MVC are 306 // out of range. 307 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false)); 308 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false)); 309 } 310 } 311 312 // Emit instructions before MBBI (in MBB) to add NumBytes to Reg. 313 static void emitIncrement(MachineBasicBlock &MBB, 314 MachineBasicBlock::iterator &MBBI, 315 const DebugLoc &DL, 316 unsigned Reg, int64_t NumBytes, 317 const TargetInstrInfo *TII) { 318 while (NumBytes) { 319 unsigned Opcode; 320 int64_t ThisVal = NumBytes; 321 if (isInt<16>(NumBytes)) 322 Opcode = SystemZ::AGHI; 323 else { 324 Opcode = SystemZ::AGFI; 325 // Make sure we maintain 8-byte stack alignment. 326 int64_t MinVal = -uint64_t(1) << 31; 327 int64_t MaxVal = (int64_t(1) << 31) - 8; 328 if (ThisVal < MinVal) 329 ThisVal = MinVal; 330 else if (ThisVal > MaxVal) 331 ThisVal = MaxVal; 332 } 333 MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg) 334 .addReg(Reg).addImm(ThisVal); 335 // The CC implicit def is dead. 336 MI->getOperand(3).setIsDead(); 337 NumBytes -= ThisVal; 338 } 339 } 340 341 void SystemZFrameLowering::emitPrologue(MachineFunction &MF, 342 MachineBasicBlock &MBB) const { 343 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 344 MachineFrameInfo &MFFrame = MF.getFrameInfo(); 345 auto *ZII = 346 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); 347 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 348 MachineBasicBlock::iterator MBBI = MBB.begin(); 349 MachineModuleInfo &MMI = MF.getMMI(); 350 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 351 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo(); 352 bool HasFP = hasFP(MF); 353 354 // Debug location must be unknown since the first debug location is used 355 // to determine the end of the prologue. 356 DebugLoc DL; 357 358 // The current offset of the stack pointer from the CFA. 359 int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP; 360 361 if (ZFI->getLowSavedGPR()) { 362 // Skip over the GPR saves. 363 if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG) 364 ++MBBI; 365 else 366 llvm_unreachable("Couldn't skip over GPR saves"); 367 368 // Add CFI for the GPR saves. 369 for (auto &Save : CSI) { 370 unsigned Reg = Save.getReg(); 371 if (SystemZ::GR64BitRegClass.contains(Reg)) { 372 int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[Reg]; 373 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 374 nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); 375 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 376 .addCFIIndex(CFIIndex); 377 } 378 } 379 } 380 381 uint64_t StackSize = MFFrame.getStackSize(); 382 // We need to allocate the ABI-defined 160-byte base area whenever 383 // we allocate stack space for our own use and whenever we call another 384 // function. 385 if (StackSize || MFFrame.hasVarSizedObjects() || MFFrame.hasCalls()) { 386 StackSize += SystemZMC::CallFrameSize; 387 MFFrame.setStackSize(StackSize); 388 } 389 390 if (StackSize) { 391 // Determine if we want to store a backchain. 392 bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain"); 393 394 // If we need backchain, save current stack pointer. R1 is free at this 395 // point. 396 if (StoreBackchain) 397 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR)) 398 .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D); 399 400 // Allocate StackSize bytes. 401 int64_t Delta = -int64_t(StackSize); 402 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII); 403 404 // Add CFI for the allocation. 405 unsigned CFIIndex = MF.addFrameInst( 406 MCCFIInstruction::createDefCfaOffset(nullptr, SPOffsetFromCFA + Delta)); 407 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 408 .addCFIIndex(CFIIndex); 409 SPOffsetFromCFA += Delta; 410 411 if (StoreBackchain) 412 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG)) 413 .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D).addImm(0).addReg(0); 414 } 415 416 if (HasFP) { 417 // Copy the base of the frame to R11. 418 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D) 419 .addReg(SystemZ::R15D); 420 421 // Add CFI for the new frame location. 422 unsigned HardFP = MRI->getDwarfRegNum(SystemZ::R11D, true); 423 unsigned CFIIndex = MF.addFrameInst( 424 MCCFIInstruction::createDefCfaRegister(nullptr, HardFP)); 425 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 426 .addCFIIndex(CFIIndex); 427 428 // Mark the FramePtr as live at the beginning of every block except 429 // the entry block. (We'll have marked R11 as live on entry when 430 // saving the GPRs.) 431 for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I) 432 I->addLiveIn(SystemZ::R11D); 433 } 434 435 // Skip over the FPR/VR saves. 436 SmallVector<unsigned, 8> CFIIndexes; 437 for (auto &Save : CSI) { 438 unsigned Reg = Save.getReg(); 439 if (SystemZ::FP64BitRegClass.contains(Reg)) { 440 if (MBBI != MBB.end() && 441 (MBBI->getOpcode() == SystemZ::STD || 442 MBBI->getOpcode() == SystemZ::STDY)) 443 ++MBBI; 444 else 445 llvm_unreachable("Couldn't skip over FPR save"); 446 } else if (SystemZ::VR128BitRegClass.contains(Reg)) { 447 if (MBBI != MBB.end() && 448 MBBI->getOpcode() == SystemZ::VST) 449 ++MBBI; 450 else 451 llvm_unreachable("Couldn't skip over VR save"); 452 } else 453 continue; 454 455 // Add CFI for the this save. 456 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); 457 unsigned IgnoredFrameReg; 458 int64_t Offset = 459 getFrameIndexReference(MF, Save.getFrameIdx(), IgnoredFrameReg); 460 461 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 462 nullptr, DwarfReg, SPOffsetFromCFA + Offset)); 463 CFIIndexes.push_back(CFIIndex); 464 } 465 // Complete the CFI for the FPR/VR saves, modelling them as taking effect 466 // after the last save. 467 for (auto CFIIndex : CFIIndexes) { 468 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 469 .addCFIIndex(CFIIndex); 470 } 471 } 472 473 void SystemZFrameLowering::emitEpilogue(MachineFunction &MF, 474 MachineBasicBlock &MBB) const { 475 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 476 auto *ZII = 477 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo()); 478 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 479 MachineFrameInfo &MFFrame = MF.getFrameInfo(); 480 481 // Skip the return instruction. 482 assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks"); 483 484 uint64_t StackSize = MFFrame.getStackSize(); 485 if (ZFI->getLowSavedGPR()) { 486 --MBBI; 487 unsigned Opcode = MBBI->getOpcode(); 488 if (Opcode != SystemZ::LMG) 489 llvm_unreachable("Expected to see callee-save register restore code"); 490 491 unsigned AddrOpNo = 2; 492 DebugLoc DL = MBBI->getDebugLoc(); 493 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm(); 494 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 495 496 // If the offset is too large, use the largest stack-aligned offset 497 // and add the rest to the base register (the stack or frame pointer). 498 if (!NewOpcode) { 499 uint64_t NumBytes = Offset - 0x7fff8; 500 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(), 501 NumBytes, ZII); 502 Offset -= NumBytes; 503 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 504 assert(NewOpcode && "No restore instruction available"); 505 } 506 507 MBBI->setDesc(ZII->get(NewOpcode)); 508 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset); 509 } else if (StackSize) { 510 DebugLoc DL = MBBI->getDebugLoc(); 511 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII); 512 } 513 } 514 515 bool SystemZFrameLowering::hasFP(const MachineFunction &MF) const { 516 return (MF.getTarget().Options.DisableFramePointerElim(MF) || 517 MF.getFrameInfo().hasVarSizedObjects() || 518 MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP()); 519 } 520 521 bool 522 SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 523 // The ABI requires us to allocate 160 bytes of stack space for the callee, 524 // with any outgoing stack arguments being placed above that. It seems 525 // better to make that area a permanent feature of the frame even if 526 // we're using a frame pointer. 527 return true; 528 } 529 530 MachineBasicBlock::iterator SystemZFrameLowering:: 531 eliminateCallFramePseudoInstr(MachineFunction &MF, 532 MachineBasicBlock &MBB, 533 MachineBasicBlock::iterator MI) const { 534 switch (MI->getOpcode()) { 535 case SystemZ::ADJCALLSTACKDOWN: 536 case SystemZ::ADJCALLSTACKUP: 537 assert(hasReservedCallFrame(MF) && 538 "ADJSTACKDOWN and ADJSTACKUP should be no-ops"); 539 return MBB.erase(MI); 540 break; 541 542 default: 543 llvm_unreachable("Unexpected call frame instruction"); 544 } 545 } 546