void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo<SystemZMachineFunctionInfo>(); unsigned RetOpcode = MBBI->getOpcode(); switch (RetOpcode) { case SystemZ::RET: break; // These are ok default: assert(0 && "Can only insert epilog into returning blocks"); } // Get the number of bytes to allocate from the FrameInfo // Note that area for callee-saved stuff is already allocated, thus we need to // 'undo' the stack movement. uint64_t StackSize = MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize(); uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); // Skip the final terminator instruction. while (MBBI != MBB.begin()) { MachineBasicBlock::iterator PI = prior(MBBI); --MBBI; if (!PI->getDesc().isTerminator()) break; } // During callee-saved restores emission stack frame was not yet finialized // (and thus - the stack size was unknown). Tune the offset having full stack // size in hands. if (StackSize || MFI->hasCalls()) { assert((MBBI->getOpcode() == SystemZ::MOV64rmm || MBBI->getOpcode() == SystemZ::MOV64rm) && "Expected to see callee-save register restore code"); assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) && "Invalid stack frame calculation!"); unsigned i = 0; MachineInstr &MI = *MBBI; while (!MI.getOperand(i).isImm()) { ++i; assert(i < MI.getNumOperands() && "Unexpected restore code!"); } uint64_t Offset = NumBytes + MI.getOperand(i).getImm(); // If Offset does not fit into 20-bit signed displacement field we need to // emit some additional code... if (Offset > 524287) { // Fold the displacement into load instruction as much as possible. NumBytes = Offset - 524287; Offset = 524287; emitSPUpdate(MBB, MBBI, NumBytes, TII); } MI.getOperand(i).ChangeToImmediate(Offset); } }
void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo(); SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo<SystemZMachineFunctionInfo>(); MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); // Get the number of bytes to allocate from the FrameInfo. // Note that area for callee-saved stuff is already allocated, thus we need to // 'undo' the stack movement. uint64_t StackSize = MFI->getStackSize(); StackSize -= SystemZMFI->getCalleeSavedFrameSize(); uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); // Skip the callee-saved push instructions. while (MBBI != MBB.end() && (MBBI->getOpcode() == SystemZ::MOV64mr || MBBI->getOpcode() == SystemZ::MOV64mrm)) ++MBBI; if (MBBI != MBB.end()) DL = MBBI->getDebugLoc(); // adjust stack pointer: R15 -= numbytes if (StackSize || MFI->hasCalls()) { assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) && "Invalid stack frame calculation!"); emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII); } if (hasFP(MF)) { // Update R11 with the new base value... BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D) .addReg(SystemZ::R15D); // Mark the FramePtr as live-in in every block except the entry. for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); I != E; ++I) I->addLiveIn(SystemZ::R11D); } }
int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const { const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo(); SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo<SystemZMachineFunctionInfo>(); int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment(); uint64_t StackSize = MFI->getStackSize(); // Fixed objects are really located in the "previous" frame. if (FI < 0) StackSize -= SystemZMFI->getCalleeSavedFrameSize(); Offset += StackSize - TFI.getOffsetOfLocalArea(); // Skip the register save area if we generated the stack frame. if (StackSize || MFI->hasCalls()) Offset -= TFI.getOffsetOfLocalArea(); return Offset; }