[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / llvm / lib / Target / SystemZ / SystemZFrameLowering.cpp
blob3cdf6bf98ee0880da30589b7f44b6af44fb75fdc
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 //===----------------------------------------------------------------------===//
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"
21 using namespace llvm;
23 namespace {
24 // The ABI-defined register save slots, relative to the CFA (i.e.
25 // incoming stack pointer + SystemZMC::CallFrameSize).
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 }
46 } // end anonymous namespace
48 SystemZFrameLowering::SystemZFrameLowering()
49 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(8),
50 0, Align(8), false /* StackRealignable */),
51 RegSpillOffsets(0) {
52 // Due to the SystemZ ABI, the DWARF CFA (Canonical Frame Address) is not
53 // equal to the incoming stack pointer, but to incoming stack pointer plus
54 // 160. Instead of using a Local Area Offset, the Register save area will
55 // be occupied by fixed frame objects, and all offsets are actually
56 // relative to CFA.
58 // Create a mapping from register number to save slot offset.
59 // These offsets are relative to the start of the register save area.
60 RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
61 for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I)
62 RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset;
65 static bool usePackedStack(MachineFunction &MF) {
66 bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack");
67 bool IsVarArg = MF.getFunction().isVarArg();
68 bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC;
69 bool BackChain = MF.getFunction().hasFnAttribute("backchain");
70 bool FramAddressTaken = MF.getFrameInfo().isFrameAddressTaken();
71 if (HasPackedStackAttr && BackChain)
72 report_fatal_error("packed-stack with backchain is currently unsupported.");
73 return HasPackedStackAttr && !IsVarArg && CallConv && !BackChain &&
74 !FramAddressTaken;
77 bool SystemZFrameLowering::
78 assignCalleeSavedSpillSlots(MachineFunction &MF,
79 const TargetRegisterInfo *TRI,
80 std::vector<CalleeSavedInfo> &CSI) const {
81 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
82 MachineFrameInfo &MFFrame = MF.getFrameInfo();
83 bool IsVarArg = MF.getFunction().isVarArg();
84 if (CSI.empty())
85 return true; // Early exit if no callee saved registers are modified!
87 unsigned LowGPR = 0;
88 unsigned HighGPR = SystemZ::R15D;
89 int StartSPOffset = SystemZMC::CallFrameSize;
90 int CurrOffset;
91 if (!usePackedStack(MF)) {
92 for (auto &CS : CSI) {
93 unsigned Reg = CS.getReg();
94 int Offset = RegSpillOffsets[Reg];
95 if (Offset) {
96 if (SystemZ::GR64BitRegClass.contains(Reg) && StartSPOffset > Offset) {
97 LowGPR = Reg;
98 StartSPOffset = Offset;
100 Offset -= SystemZMC::CallFrameSize;
101 int FrameIdx = MFFrame.CreateFixedSpillStackObject(8, Offset);
102 CS.setFrameIdx(FrameIdx);
103 } else
104 CS.setFrameIdx(INT32_MAX);
107 // Save the range of call-saved registers, for use by the
108 // prologue/epilogue inserters.
109 ZFI->setRestoreGPRRegs(LowGPR, HighGPR, StartSPOffset);
110 if (IsVarArg) {
111 // Also save the GPR varargs, if any. R6D is call-saved, so would
112 // already be included, but we also need to handle the call-clobbered
113 // argument registers.
114 unsigned FirstGPR = ZFI->getVarArgsFirstGPR();
115 if (FirstGPR < SystemZ::NumArgGPRs) {
116 unsigned Reg = SystemZ::ArgGPRs[FirstGPR];
117 int Offset = RegSpillOffsets[Reg];
118 if (StartSPOffset > Offset) {
119 LowGPR = Reg; StartSPOffset = Offset;
123 ZFI->setSpillGPRRegs(LowGPR, HighGPR, StartSPOffset);
125 CurrOffset = -SystemZMC::CallFrameSize;
126 } else {
127 // Packed stack: put all the GPRs at the top of the Register save area.
128 uint32_t LowGR64Num = UINT32_MAX;
129 for (auto &CS : CSI) {
130 unsigned Reg = CS.getReg();
131 if (SystemZ::GR64BitRegClass.contains(Reg)) {
132 unsigned GR64Num = SystemZMC::getFirstReg(Reg);
133 int Offset = -8 * (15 - GR64Num + 1);
134 if (LowGR64Num > GR64Num) {
135 LowGR64Num = GR64Num;
136 StartSPOffset = SystemZMC::CallFrameSize + Offset;
138 int FrameIdx = MFFrame.CreateFixedSpillStackObject(8, Offset);
139 CS.setFrameIdx(FrameIdx);
140 } else
141 CS.setFrameIdx(INT32_MAX);
143 if (LowGR64Num < UINT32_MAX)
144 LowGPR = SystemZMC::GR64Regs[LowGR64Num];
146 // Save the range of call-saved registers, for use by the
147 // prologue/epilogue inserters.
148 ZFI->setRestoreGPRRegs(LowGPR, HighGPR, StartSPOffset);
149 ZFI->setSpillGPRRegs(LowGPR, HighGPR, StartSPOffset);
151 CurrOffset = LowGPR ? -(SystemZMC::CallFrameSize - StartSPOffset) : 0;
154 // Create fixed stack objects for the remaining registers.
155 for (auto &CS : CSI) {
156 if (CS.getFrameIdx() != INT32_MAX)
157 continue;
158 unsigned Reg = CS.getReg();
159 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
160 unsigned Size = TRI->getSpillSize(*RC);
161 CurrOffset -= Size;
162 assert(CurrOffset % 8 == 0 &&
163 "8-byte alignment required for for all register save slots");
164 int FrameIdx = MFFrame.CreateFixedSpillStackObject(Size, CurrOffset);
165 CS.setFrameIdx(FrameIdx);
168 return true;
171 void SystemZFrameLowering::determineCalleeSaves(MachineFunction &MF,
172 BitVector &SavedRegs,
173 RegScavenger *RS) const {
174 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
176 MachineFrameInfo &MFFrame = MF.getFrameInfo();
177 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
178 bool HasFP = hasFP(MF);
179 SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
180 bool IsVarArg = MF.getFunction().isVarArg();
182 // va_start stores incoming FPR varargs in the normal way, but delegates
183 // the saving of incoming GPR varargs to spillCalleeSavedRegisters().
184 // Record these pending uses, which typically include the call-saved
185 // argument register R6D.
186 if (IsVarArg)
187 for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
188 SavedRegs.set(SystemZ::ArgGPRs[I]);
190 // If there are any landing pads, entering them will modify r6/r7.
191 if (!MF.getLandingPads().empty()) {
192 SavedRegs.set(SystemZ::R6D);
193 SavedRegs.set(SystemZ::R7D);
196 // If the function requires a frame pointer, record that the hard
197 // frame pointer will be clobbered.
198 if (HasFP)
199 SavedRegs.set(SystemZ::R11D);
201 // If the function calls other functions, record that the return
202 // address register will be clobbered.
203 if (MFFrame.hasCalls())
204 SavedRegs.set(SystemZ::R14D);
206 // If we are saving GPRs other than the stack pointer, we might as well
207 // save and restore the stack pointer at the same time, via STMG and LMG.
208 // This allows the deallocation to be done by the LMG, rather than needing
209 // a separate %r15 addition.
210 const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
211 for (unsigned I = 0; CSRegs[I]; ++I) {
212 unsigned Reg = CSRegs[I];
213 if (SystemZ::GR64BitRegClass.contains(Reg) && SavedRegs.test(Reg)) {
214 SavedRegs.set(SystemZ::R15D);
215 break;
220 // Add GPR64 to the save instruction being built by MIB, which is in basic
221 // block MBB. IsImplicit says whether this is an explicit operand to the
222 // instruction, or an implicit one that comes between the explicit start
223 // and end registers.
224 static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB,
225 unsigned GPR64, bool IsImplicit) {
226 const TargetRegisterInfo *RI =
227 MBB.getParent()->getSubtarget().getRegisterInfo();
228 Register GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
229 bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32);
230 if (!IsLive || !IsImplicit) {
231 MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive));
232 if (!IsLive)
233 MBB.addLiveIn(GPR64);
237 bool SystemZFrameLowering::
238 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
239 MachineBasicBlock::iterator MBBI,
240 const std::vector<CalleeSavedInfo> &CSI,
241 const TargetRegisterInfo *TRI) const {
242 if (CSI.empty())
243 return false;
245 MachineFunction &MF = *MBB.getParent();
246 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
247 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
248 bool IsVarArg = MF.getFunction().isVarArg();
249 DebugLoc DL;
251 // Save GPRs
252 SystemZ::GPRRegs SpillGPRs = ZFI->getSpillGPRRegs();
253 if (SpillGPRs.LowGPR) {
254 assert(SpillGPRs.LowGPR != SpillGPRs.HighGPR &&
255 "Should be saving %r15 and something else");
257 // Build an STMG instruction.
258 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG));
260 // Add the explicit register operands.
261 addSavedGPR(MBB, MIB, SpillGPRs.LowGPR, false);
262 addSavedGPR(MBB, MIB, SpillGPRs.HighGPR, false);
264 // Add the address.
265 MIB.addReg(SystemZ::R15D).addImm(SpillGPRs.GPROffset);
267 // Make sure all call-saved GPRs are included as operands and are
268 // marked as live on entry.
269 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
270 unsigned Reg = CSI[I].getReg();
271 if (SystemZ::GR64BitRegClass.contains(Reg))
272 addSavedGPR(MBB, MIB, Reg, true);
275 // ...likewise GPR varargs.
276 if (IsVarArg)
277 for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I)
278 addSavedGPR(MBB, MIB, SystemZ::ArgGPRs[I], true);
281 // Save FPRs/VRs in the normal TargetInstrInfo way.
282 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
283 unsigned Reg = CSI[I].getReg();
284 if (SystemZ::FP64BitRegClass.contains(Reg)) {
285 MBB.addLiveIn(Reg);
286 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(),
287 &SystemZ::FP64BitRegClass, TRI);
289 if (SystemZ::VR128BitRegClass.contains(Reg)) {
290 MBB.addLiveIn(Reg);
291 TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(),
292 &SystemZ::VR128BitRegClass, TRI);
296 return true;
299 bool SystemZFrameLowering::
300 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
301 MachineBasicBlock::iterator MBBI,
302 std::vector<CalleeSavedInfo> &CSI,
303 const TargetRegisterInfo *TRI) const {
304 if (CSI.empty())
305 return false;
307 MachineFunction &MF = *MBB.getParent();
308 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
309 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
310 bool HasFP = hasFP(MF);
311 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
313 // Restore FPRs/VRs in the normal TargetInstrInfo way.
314 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
315 unsigned Reg = CSI[I].getReg();
316 if (SystemZ::FP64BitRegClass.contains(Reg))
317 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(),
318 &SystemZ::FP64BitRegClass, TRI);
319 if (SystemZ::VR128BitRegClass.contains(Reg))
320 TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(),
321 &SystemZ::VR128BitRegClass, TRI);
324 // Restore call-saved GPRs (but not call-clobbered varargs, which at
325 // this point might hold return values).
326 SystemZ::GPRRegs RestoreGPRs = ZFI->getRestoreGPRRegs();
327 if (RestoreGPRs.LowGPR) {
328 // If we saved any of %r2-%r5 as varargs, we should also be saving
329 // and restoring %r6. If we're saving %r6 or above, we should be
330 // restoring it too.
331 assert(RestoreGPRs.LowGPR != RestoreGPRs.HighGPR &&
332 "Should be loading %r15 and something else");
334 // Build an LMG instruction.
335 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG));
337 // Add the explicit register operands.
338 MIB.addReg(RestoreGPRs.LowGPR, RegState::Define);
339 MIB.addReg(RestoreGPRs.HighGPR, RegState::Define);
341 // Add the address.
342 MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
343 MIB.addImm(RestoreGPRs.GPROffset);
345 // Do a second scan adding regs as being defined by instruction
346 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
347 unsigned Reg = CSI[I].getReg();
348 if (Reg != RestoreGPRs.LowGPR && Reg != RestoreGPRs.HighGPR &&
349 SystemZ::GR64BitRegClass.contains(Reg))
350 MIB.addReg(Reg, RegState::ImplicitDefine);
354 return true;
357 void SystemZFrameLowering::
358 processFunctionBeforeFrameFinalized(MachineFunction &MF,
359 RegScavenger *RS) const {
360 MachineFrameInfo &MFFrame = MF.getFrameInfo();
362 if (!usePackedStack(MF))
363 // Always create the full incoming register save area.
364 getOrCreateFramePointerSaveIndex(MF);
366 // Get the size of our stack frame to be allocated ...
367 uint64_t StackSize = (MFFrame.estimateStackSize(MF) +
368 SystemZMC::CallFrameSize);
369 // ... and the maximum offset we may need to reach into the
370 // caller's frame to access the save area or stack arguments.
371 int64_t MaxArgOffset = 0;
372 for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I)
373 if (MFFrame.getObjectOffset(I) >= 0) {
374 int64_t ArgOffset = MFFrame.getObjectOffset(I) +
375 MFFrame.getObjectSize(I);
376 MaxArgOffset = std::max(MaxArgOffset, ArgOffset);
379 uint64_t MaxReach = StackSize + MaxArgOffset;
380 if (!isUInt<12>(MaxReach)) {
381 // We may need register scavenging slots if some parts of the frame
382 // are outside the reach of an unsigned 12-bit displacement.
383 // Create 2 for the case where both addresses in an MVC are
384 // out of range.
385 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false));
386 RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, 8, false));
390 // Emit instructions before MBBI (in MBB) to add NumBytes to Reg.
391 static void emitIncrement(MachineBasicBlock &MBB,
392 MachineBasicBlock::iterator &MBBI,
393 const DebugLoc &DL,
394 unsigned Reg, int64_t NumBytes,
395 const TargetInstrInfo *TII) {
396 while (NumBytes) {
397 unsigned Opcode;
398 int64_t ThisVal = NumBytes;
399 if (isInt<16>(NumBytes))
400 Opcode = SystemZ::AGHI;
401 else {
402 Opcode = SystemZ::AGFI;
403 // Make sure we maintain 8-byte stack alignment.
404 int64_t MinVal = -uint64_t(1) << 31;
405 int64_t MaxVal = (int64_t(1) << 31) - 8;
406 if (ThisVal < MinVal)
407 ThisVal = MinVal;
408 else if (ThisVal > MaxVal)
409 ThisVal = MaxVal;
411 MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg)
412 .addReg(Reg).addImm(ThisVal);
413 // The CC implicit def is dead.
414 MI->getOperand(3).setIsDead();
415 NumBytes -= ThisVal;
419 void SystemZFrameLowering::emitPrologue(MachineFunction &MF,
420 MachineBasicBlock &MBB) const {
421 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
422 MachineFrameInfo &MFFrame = MF.getFrameInfo();
423 auto *ZII =
424 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
425 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
426 MachineBasicBlock::iterator MBBI = MBB.begin();
427 MachineModuleInfo &MMI = MF.getMMI();
428 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
429 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
430 bool HasFP = hasFP(MF);
432 // In GHC calling convention C stack space, including the ABI-defined
433 // 160-byte base area, is (de)allocated by GHC itself. This stack space may
434 // be used by LLVM as spill slots for the tail recursive GHC functions. Thus
435 // do not allocate stack space here, too.
436 if (MF.getFunction().getCallingConv() == CallingConv::GHC) {
437 if (MFFrame.getStackSize() > 2048 * sizeof(long)) {
438 report_fatal_error(
439 "Pre allocated stack space for GHC function is too small");
441 if (HasFP) {
442 report_fatal_error(
443 "In GHC calling convention a frame pointer is not supported");
445 MFFrame.setStackSize(MFFrame.getStackSize() + SystemZMC::CallFrameSize);
446 return;
449 // Debug location must be unknown since the first debug location is used
450 // to determine the end of the prologue.
451 DebugLoc DL;
453 // The current offset of the stack pointer from the CFA.
454 int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP;
456 if (ZFI->getSpillGPRRegs().LowGPR) {
457 // Skip over the GPR saves.
458 if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG)
459 ++MBBI;
460 else
461 llvm_unreachable("Couldn't skip over GPR saves");
463 // Add CFI for the GPR saves.
464 for (auto &Save : CSI) {
465 unsigned Reg = Save.getReg();
466 if (SystemZ::GR64BitRegClass.contains(Reg)) {
467 int FI = Save.getFrameIdx();
468 int64_t Offset = MFFrame.getObjectOffset(FI);
469 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
470 nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
471 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
472 .addCFIIndex(CFIIndex);
477 uint64_t StackSize = MFFrame.getStackSize();
478 // We need to allocate the ABI-defined 160-byte base area whenever
479 // we allocate stack space for our own use and whenever we call another
480 // function.
481 bool HasStackObject = false;
482 for (unsigned i = 0, e = MFFrame.getObjectIndexEnd(); i != e; ++i)
483 if (!MFFrame.isDeadObjectIndex(i)) {
484 HasStackObject = true;
485 break;
487 if (HasStackObject || MFFrame.hasCalls())
488 StackSize += SystemZMC::CallFrameSize;
489 // Don't allocate the incoming reg save area.
490 StackSize = StackSize > SystemZMC::CallFrameSize
491 ? StackSize - SystemZMC::CallFrameSize
492 : 0;
493 MFFrame.setStackSize(StackSize);
495 if (StackSize) {
496 // Determine if we want to store a backchain.
497 bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
499 // If we need backchain, save current stack pointer. R1 is free at this
500 // point.
501 if (StoreBackchain)
502 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR))
503 .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
505 // Allocate StackSize bytes.
506 int64_t Delta = -int64_t(StackSize);
507 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII);
509 // Add CFI for the allocation.
510 unsigned CFIIndex = MF.addFrameInst(
511 MCCFIInstruction::createDefCfaOffset(nullptr, SPOffsetFromCFA + Delta));
512 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
513 .addCFIIndex(CFIIndex);
514 SPOffsetFromCFA += Delta;
516 if (StoreBackchain)
517 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
518 .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D).addImm(0)
519 .addReg(0);
522 if (HasFP) {
523 // Copy the base of the frame to R11.
524 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D)
525 .addReg(SystemZ::R15D);
527 // Add CFI for the new frame location.
528 unsigned HardFP = MRI->getDwarfRegNum(SystemZ::R11D, true);
529 unsigned CFIIndex = MF.addFrameInst(
530 MCCFIInstruction::createDefCfaRegister(nullptr, HardFP));
531 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
532 .addCFIIndex(CFIIndex);
534 // Mark the FramePtr as live at the beginning of every block except
535 // the entry block. (We'll have marked R11 as live on entry when
536 // saving the GPRs.)
537 for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I)
538 I->addLiveIn(SystemZ::R11D);
541 // Skip over the FPR/VR saves.
542 SmallVector<unsigned, 8> CFIIndexes;
543 for (auto &Save : CSI) {
544 unsigned Reg = Save.getReg();
545 if (SystemZ::FP64BitRegClass.contains(Reg)) {
546 if (MBBI != MBB.end() &&
547 (MBBI->getOpcode() == SystemZ::STD ||
548 MBBI->getOpcode() == SystemZ::STDY))
549 ++MBBI;
550 else
551 llvm_unreachable("Couldn't skip over FPR save");
552 } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
553 if (MBBI != MBB.end() &&
554 MBBI->getOpcode() == SystemZ::VST)
555 ++MBBI;
556 else
557 llvm_unreachable("Couldn't skip over VR save");
558 } else
559 continue;
561 // Add CFI for the this save.
562 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
563 unsigned IgnoredFrameReg;
564 int64_t Offset =
565 getFrameIndexReference(MF, Save.getFrameIdx(), IgnoredFrameReg);
567 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
568 nullptr, DwarfReg, SPOffsetFromCFA + Offset));
569 CFIIndexes.push_back(CFIIndex);
571 // Complete the CFI for the FPR/VR saves, modelling them as taking effect
572 // after the last save.
573 for (auto CFIIndex : CFIIndexes) {
574 BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
575 .addCFIIndex(CFIIndex);
579 void SystemZFrameLowering::emitEpilogue(MachineFunction &MF,
580 MachineBasicBlock &MBB) const {
581 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
582 auto *ZII =
583 static_cast<const SystemZInstrInfo *>(MF.getSubtarget().getInstrInfo());
584 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
585 MachineFrameInfo &MFFrame = MF.getFrameInfo();
587 // See SystemZFrameLowering::emitPrologue
588 if (MF.getFunction().getCallingConv() == CallingConv::GHC)
589 return;
591 // Skip the return instruction.
592 assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks");
594 uint64_t StackSize = MFFrame.getStackSize();
595 if (ZFI->getRestoreGPRRegs().LowGPR) {
596 --MBBI;
597 unsigned Opcode = MBBI->getOpcode();
598 if (Opcode != SystemZ::LMG)
599 llvm_unreachable("Expected to see callee-save register restore code");
601 unsigned AddrOpNo = 2;
602 DebugLoc DL = MBBI->getDebugLoc();
603 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
604 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
606 // If the offset is too large, use the largest stack-aligned offset
607 // and add the rest to the base register (the stack or frame pointer).
608 if (!NewOpcode) {
609 uint64_t NumBytes = Offset - 0x7fff8;
610 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
611 NumBytes, ZII);
612 Offset -= NumBytes;
613 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
614 assert(NewOpcode && "No restore instruction available");
617 MBBI->setDesc(ZII->get(NewOpcode));
618 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
619 } else if (StackSize) {
620 DebugLoc DL = MBBI->getDebugLoc();
621 emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII);
625 bool SystemZFrameLowering::hasFP(const MachineFunction &MF) const {
626 return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
627 MF.getFrameInfo().hasVarSizedObjects() ||
628 MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP());
631 bool
632 SystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
633 // The ABI requires us to allocate 160 bytes of stack space for the callee,
634 // with any outgoing stack arguments being placed above that. It seems
635 // better to make that area a permanent feature of the frame even if
636 // we're using a frame pointer.
637 return true;
640 int SystemZFrameLowering::getFrameIndexReference(const MachineFunction &MF,
641 int FI,
642 unsigned &FrameReg) const {
643 // Our incoming SP is actually SystemZMC::CallFrameSize below the CFA, so
644 // add that difference here.
645 int64_t Offset =
646 TargetFrameLowering::getFrameIndexReference(MF, FI, FrameReg);
647 return Offset + SystemZMC::CallFrameSize;
650 MachineBasicBlock::iterator SystemZFrameLowering::
651 eliminateCallFramePseudoInstr(MachineFunction &MF,
652 MachineBasicBlock &MBB,
653 MachineBasicBlock::iterator MI) const {
654 switch (MI->getOpcode()) {
655 case SystemZ::ADJCALLSTACKDOWN:
656 case SystemZ::ADJCALLSTACKUP:
657 assert(hasReservedCallFrame(MF) &&
658 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
659 return MBB.erase(MI);
660 break;
662 default:
663 llvm_unreachable("Unexpected call frame instruction");
667 int SystemZFrameLowering::
668 getOrCreateFramePointerSaveIndex(MachineFunction &MF) const {
669 SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
670 int FI = ZFI->getFramePointerSaveIndex();
671 if (!FI) {
672 MachineFrameInfo &MFFrame = MF.getFrameInfo();
673 FI = MFFrame.CreateFixedObject(8, -SystemZMC::CallFrameSize, false);
674 ZFI->setFramePointerSaveIndex(FI);
676 return FI;