11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZFrameLowering.cpp - Frame lowering for SystemZ -------------===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZFrameLowering.h" 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZCallingConv.h" 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrBuilder.h" 13cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "SystemZInstrInfo.h" 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZMachineFunctionInfo.h" 15cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "SystemZRegisterInfo.h" 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/MachineModuleInfo.h" 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/MachineRegisterInfo.h" 187271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford#include "llvm/CodeGen/RegisterScavenging.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/IR/Function.h" 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2352c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandifordnamespace { 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The ABI-defined register save slots, relative to the incoming stack 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// pointer. 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic const TargetFrameLowering::SpillSlot SpillOffsetTable[] = { 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R2D, 0x10 }, 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R3D, 0x18 }, 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R4D, 0x20 }, 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R5D, 0x28 }, 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R6D, 0x30 }, 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R7D, 0x38 }, 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R8D, 0x40 }, 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R9D, 0x48 }, 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R10D, 0x50 }, 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R11D, 0x58 }, 3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R12D, 0x60 }, 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R13D, 0x68 }, 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R14D, 0x70 }, 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::R15D, 0x78 }, 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::F0D, 0x80 }, 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::F2D, 0x88 }, 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::F4D, 0x90 }, 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines { SystemZ::F6D, 0x98 } 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 48cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesSystemZFrameLowering::SystemZFrameLowering() 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8, 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines -SystemZMC::CallFrameSize, 8) { 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create a mapping from register number to save slot offset. 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = array_lengthof(SpillOffsetTable); I != E; ++I) 5452c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford RegSpillOffsets[SpillOffsetTable[I].Reg] = SpillOffsetTable[I].Offset; 5552c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford} 5652c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford 5752c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandifordconst TargetFrameLowering::SpillSlot * 5852c28b07f039da61a20f21275793c8d3b9b97fe9Richard SandifordSystemZFrameLowering::getCalleeSavedSpillSlots(unsigned &NumEntries) const { 5952c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford NumEntries = array_lengthof(SpillOffsetTable); 6052c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford return SpillOffsetTable; 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZFrameLowering:: 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandprocessFunctionBeforeCalleeSavedScan(MachineFunction &MF, 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegScavenger *RS) const { 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool HasFP = hasFP(MF); 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsVarArg = MF.getFunction()->isVarArg(); 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // va_start stores incoming FPR varargs in the normal way, but delegates 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the saving of incoming GPR varargs to spillCalleeSavedRegisters(). 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Record these pending uses, which typically include the call-saved 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // argument register R6D. 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsVarArg) 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.setPhysRegUsed(SystemZ::ArgGPRs[I]); 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the function requires a frame pointer, record that the hard 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // frame pointer will be clobbered. 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HasFP) 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.setPhysRegUsed(SystemZ::R11D); 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the function calls other functions, record that the return 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // address register will be clobbered. 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MFFrame->hasCalls()) 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.setPhysRegUsed(SystemZ::R14D); 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we are saving GPRs other than the stack pointer, we might as well 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // save and restore the stack pointer at the same time, via STMG and LMG. 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // This allows the deallocation to be done by the LMG, rather than needing 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // a separate %r15 addition. 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF); 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0; CSRegs[I]; ++I) { 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSRegs[I]; 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR64BitRegClass.contains(Reg) && MRI.isPhysRegUsed(Reg)) { 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.setPhysRegUsed(SystemZ::R15D); 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Add GPR64 to the save instruction being built by MIB, which is in basic 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// block MBB. IsImplicit says whether this is an explicit operand to the 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// instruction, or an implicit one that comes between the explicit start 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// and end registers. 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned GPR64, bool IsImplicit) { 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const TargetRegisterInfo *RI = MBB.getParent()->getTarget().getRegisterInfo(); 112745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32); 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsLive = MBB.isLiveIn(GPR64) || MBB.isLiveIn(GPR32); 1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!IsLive || !IsImplicit) { 1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(GPR64, getImplRegState(IsImplicit) | getKillRegState(!IsLive)); 1161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!IsLive) 1171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB.addLiveIn(GPR64); 1181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZFrameLowering:: 1221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandspillCalleeSavedRegisters(MachineBasicBlock &MBB, 1231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 1241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const std::vector<CalleeSavedInfo> &CSI, 1251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 1261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CSI.empty()) 1271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 1281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB.getParent(); 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); 1311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsVarArg = MF.getFunction()->isVarArg(); 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 1341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Scan the call-saved GPRs and find the bounds of the register spill area. 1361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowGPR = 0; 1371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighGPR = SystemZ::R15D; 1381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned StartOffset = -1U; 1391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 1401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSI[I].getReg(); 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR64BitRegClass.contains(Reg)) { 1421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = RegSpillOffsets[Reg]; 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Offset && "Unexpected GPR save"); 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (StartOffset > Offset) { 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowGPR = Reg; 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StartOffset = Offset; 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15152c28b07f039da61a20f21275793c8d3b9b97fe9Richard Sandiford // Save the range of call-saved registers, for use by the epilogue inserter. 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ZFI->setLowSavedGPR(LowGPR); 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ZFI->setHighSavedGPR(HighGPR); 1541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Include the GPR varargs, if any. R6D is call-saved, so would 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // be included by the loop above, but we also need to handle the 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // call-clobbered argument registers. 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsVarArg) { 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned FirstGPR = ZFI->getVarArgsFirstGPR(); 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (FirstGPR < SystemZ::NumArgGPRs) { 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = SystemZ::ArgGPRs[FirstGPR]; 1621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = RegSpillOffsets[Reg]; 1631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (StartOffset > Offset) { 1641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowGPR = Reg; StartOffset = Offset; 1651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Save GPRs 1701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (LowGPR) { 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LowGPR != HighGPR && "Should be saving %r15 and something else"); 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Build an STMG instruction. 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STMG)); 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the explicit register operands. 177cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines addSavedGPR(MBB, MIB, LowGPR, false); 178cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines addSavedGPR(MBB, MIB, HighGPR, false); 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the address. 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(SystemZ::R15D).addImm(StartOffset); 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure all call-saved GPRs are included as operands and are 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // marked as live on entry. 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSI[I].getReg(); 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR64BitRegClass.contains(Reg)) 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines addSavedGPR(MBB, MIB, Reg, true); 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ...likewise GPR varargs. 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsVarArg) 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = ZFI->getVarArgsFirstGPR(); I < SystemZ::NumArgGPRs; ++I) 194cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines addSavedGPR(MBB, MIB, SystemZ::ArgGPRs[I], true); 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Save FPRs in the normal TargetInstrInfo way. 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSI[I].getReg(); 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::FP64BitRegClass.contains(Reg)) { 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB.addLiveIn(Reg); 2021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TII->storeRegToStackSlot(MBB, MBBI, Reg, true, CSI[I].getFrameIdx(), 2031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::FP64BitRegClass, TRI); 2041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZFrameLowering:: 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandrestoreCalleeSavedRegisters(MachineBasicBlock &MBB, 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const std::vector<CalleeSavedInfo> &CSI, 2141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CSI.empty()) 2161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 2171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB.getParent(); 2191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); 2201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool HasFP = hasFP(MF); 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Restore FPRs in the normal TargetInstrInfo way. 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSI[I].getReg(); 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::FP64BitRegClass.contains(Reg)) 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TII->loadRegFromStackSlot(MBB, MBBI, Reg, CSI[I].getFrameIdx(), 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::FP64BitRegClass, TRI); 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Restore call-saved GPRs (but not call-clobbered varargs, which at 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // this point might hold return values). 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowGPR = ZFI->getLowSavedGPR(); 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighGPR = ZFI->getHighSavedGPR(); 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned StartOffset = RegSpillOffsets[LowGPR]; 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (LowGPR) { 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we saved any of %r2-%r5 as varargs, we should also be saving 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // and restoring %r6. If we're saving %r6 or above, we should be 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // restoring it too. 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LowGPR != HighGPR && "Should be loading %r15 and something else"); 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Build an LMG instruction. 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(SystemZ::LMG)); 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the explicit register operands. 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(LowGPR, RegState::Define); 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(HighGPR, RegState::Define); 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the address. 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(HasFP ? SystemZ::R11D : SystemZ::R15D); 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addImm(StartOffset); 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Do a second scan adding regs as being defined by instruction 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 2561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = CSI[I].getReg(); 2571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Reg != LowGPR && Reg != HighGPR) 2581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MIB.addReg(Reg, RegState::ImplicitDefine); 2591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2657271ac2c0318043688ddc8686dd23777dca62c59Richard Sandifordvoid SystemZFrameLowering:: 2667271ac2c0318043688ddc8686dd23777dca62c59Richard SandifordprocessFunctionBeforeFrameFinalized(MachineFunction &MF, 2677271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford RegScavenger *RS) const { 2687271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford MachineFrameInfo *MFFrame = MF.getFrameInfo(); 2697271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford uint64_t MaxReach = (MFFrame->estimateStackSize(MF) + 2707271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford SystemZMC::CallFrameSize * 2); 27147734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford if (!isUInt<12>(MaxReach)) { 27247734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford // We may need register scavenging slots if some parts of the frame 2737271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford // are outside the reach of an unsigned 12-bit displacement. 27447734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford // Create 2 for the case where both addresses in an MVC are 27547734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford // out of range. 2767271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford RS->addScavengingFrameIndex(MFFrame->CreateStackObject(8, 8, false)); 27747734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford RS->addScavengingFrameIndex(MFFrame->CreateStackObject(8, 8, false)); 27847734db936bd3b434d60f9daee5b34bc722ee3baRichard Sandiford } 2797271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford} 2807271ac2c0318043688ddc8686dd23777dca62c59Richard Sandiford 2811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Emit instructions before MBBI (in MBB) to add NumBytes to Reg. 2821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void emitIncrement(MachineBasicBlock &MBB, 2831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator &MBBI, 2841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const DebugLoc &DL, 2851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg, int64_t NumBytes, 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetInstrInfo *TII) { 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (NumBytes) { 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t ThisVal = NumBytes; 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(NumBytes)) 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::AGHI; 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else { 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::AGFI; 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure we maintain 8-byte stack alignment. 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t MinVal = -int64_t(1) << 31; 2961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t MaxVal = (int64_t(1) << 31) - 8; 2971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ThisVal < MinVal) 2981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ThisVal = MinVal; 2991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (ThisVal > MaxVal) 3001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ThisVal = MaxVal; 3011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII->get(Opcode), Reg) 3031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Reg).addImm(ThisVal); 304dbd8eb26ce1e7de9b69f5c46f45ba011a706c9b9Richard Sandiford // The CC implicit def is dead. 3051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(3).setIsDead(); 3061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumBytes -= ThisVal; 3071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZFrameLowering::emitPrologue(MachineFunction &MF) const { 3111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock &MBB = MF.front(); 3121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *ZII = 3141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); 3151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI = MBB.begin(); 3171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineModuleInfo &MMI = MF.getMMI(); 31899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const std::vector<CalleeSavedInfo> &CSI = MFFrame->getCalleeSavedInfo(); 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool HasFP = hasFP(MF); 3211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 3221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The current offset of the stack pointer from the CFA. 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t SPOffsetFromCFA = -SystemZMC::CFAOffsetFromInitialSP; 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ZFI->getLowSavedGPR()) { 3271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Skip over the GPR saves. 3281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MBBI != MBB.end() && MBBI->getOpcode() == SystemZ::STMG) 3291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++MBBI; 3301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Couldn't skip over GPR saves"); 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add CFI for the GPR saves. 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto &Save : CSI) { 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg = Save.getReg(); 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR64BitRegClass.contains(Reg)) { 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[Reg]; 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset( 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t StackSize = getAllocatedStackSize(MF); 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (StackSize) { 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Allocate StackSize bytes. 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Delta = -int64_t(StackSize); 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII); 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add CFI for the allocation. 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCCFIInstruction::createDefCfaOffset(nullptr, SPOffsetFromCFA + Delta)); 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SPOffsetFromCFA += Delta; 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HasFP) { 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the base of the frame to R11. 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D) 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SystemZ::R15D); 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add CFI for the new frame location. 36699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned HardFP = MRI->getDwarfRegNum(SystemZ::R11D, true); 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst( 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCCFIInstruction::createDefCfaRegister(nullptr, HardFP)); 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Mark the FramePtr as live at the beginning of every block except 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the entry block. (We'll have marked R11 as live on entry when 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // saving the GPRs.) 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto I = std::next(MF.begin()), E = MF.end(); I != E; ++I) 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->addLiveIn(SystemZ::R11D); 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Skip over the FPR saves. 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVector<unsigned, 8> CFIIndexes; 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto &Save : CSI) { 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg = Save.getReg(); 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::FP64BitRegClass.contains(Reg)) { 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MBBI != MBB.end() && 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand (MBBI->getOpcode() == SystemZ::STD || 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBBI->getOpcode() == SystemZ::STDY)) 3871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++MBBI; 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Couldn't skip over FPR save"); 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add CFI for the this save. 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Offset = getFrameIndexOffset(MF, Save.getFrameIdx()); 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset( 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines nullptr, DwarfReg, SPOffsetFromCFA + Offset)); 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CFIIndexes.push_back(CFIIndex); 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Complete the CFI for the FPR saves, modelling them as taking effect 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // after the last save. 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto CFIIndex : CFIIndexes) { 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION)) 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addCFIIndex(CFIIndex); 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZFrameLowering::emitEpilogue(MachineFunction &MF, 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock &MBB) const { 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *ZII = 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>(); 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Skip the return instruction. 41580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford assert(MBBI->isReturn() && "Can only insert epilogue into returning blocks"); 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t StackSize = getAllocatedStackSize(MF); 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ZFI->getLowSavedGPR()) { 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --MBBI; 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode = MBBI->getOpcode(); 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode != SystemZ::LMG) 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Expected to see callee-save register restore code"); 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned AddrOpNo = 2; 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI->getDebugLoc(); 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm(); 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the offset is too large, use the largest stack-aligned offset 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // and add the rest to the base register (the stack or frame pointer). 4311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!NewOpcode) { 4321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t NumBytes = Offset - 0x7fff8; 4331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(), 4341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumBytes, ZII); 4351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset -= NumBytes; 4361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset); 4371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(NewOpcode && "No restore instruction available"); 4381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBBI->setDesc(ZII->get(NewOpcode)); 4411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset); 4421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (StackSize) { 4431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI->getDebugLoc(); 4441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand emitIncrement(MBB, MBBI, DL, SystemZ::R15D, StackSize, ZII); 4451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZFrameLowering::hasFP(const MachineFunction &MF) const { 4491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return (MF.getTarget().Options.DisableFramePointerElim(MF) || 4501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getFrameInfo()->hasVarSizedObjects() || 4511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>()->getManipulatesSP()); 4521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandint SystemZFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI) const { 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MachineFrameInfo *MFFrame = MF.getFrameInfo(); 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start with the offset of FI from the top of the caller-allocated frame 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // (i.e. the top of the 160 bytes allocated by the caller). This initial 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // offset is therefore negative. 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = (MFFrame->getObjectOffset(FI) + 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MFFrame->getOffsetAdjustment()); 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make the offset relative to the incoming stack pointer. 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset -= getOffsetOfLocalArea(); 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make the offset relative to the bottom of the frame. 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset += getAllocatedStackSize(MF); 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Offset; 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weiganduint64_t SystemZFrameLowering:: 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandgetAllocatedStackSize(const MachineFunction &MF) const { 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MachineFrameInfo *MFFrame = MF.getFrameInfo(); 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start with the size of the local variables and spill slots. 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t StackSize = MFFrame->getStackSize(); 4791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We need to allocate the ABI-defined 160-byte base area whenever 4811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // we allocate stack space for our own use and whenever we call another 4821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // function. 4831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (StackSize || MFFrame->hasVarSizedObjects() || MFFrame->hasCalls()) 4841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StackSize += SystemZMC::CallFrameSize; 4851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return StackSize; 4871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool 4901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 4911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The ABI requires us to allocate 160 bytes of stack space for the callee, 4921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // with any outgoing stack arguments being placed above that. It seems 4931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // better to make that area a permanent feature of the frame even if 4941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // we're using a frame pointer. 4951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 4961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZFrameLowering:: 4991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandeliminateCallFramePseudoInstr(MachineFunction &MF, 5001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock &MBB, 5011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MI) const { 5021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 5031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJCALLSTACKDOWN: 5041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJCALLSTACKUP: 5051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(hasReservedCallFrame(MF) && 5061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "ADJSTACKDOWN and ADJSTACKUP should be no-ops"); 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB.erase(MI); 5081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 5091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 5111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected call frame instruction"); 5121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 514