void Z80FrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MI = MBB.getFirstTerminator(); DebugLoc DL = MBB.findDebugLoc(MI); MachineFrameInfo &MFI = MF.getFrameInfo(); int StackSize = int(MFI.getStackSize()); const TargetRegisterClass *ScratchRC = Is24Bit ? &Z80::A24RegClass : &Z80::A16RegClass; TargetRegisterClass::iterator ScratchReg = ScratchRC->begin(); for (; MI->readsRegister(TRI->getSubReg(*ScratchReg, Z80::sub_low), TRI); ++ScratchReg) assert(ScratchReg != ScratchRC->end() && "Could not allocate a scratch register!"); assert((hasFP(MF) || *ScratchReg != TRI->getFrameRegister(MF)) && "Cannot allocate csr as scratch register!"); // skip callee-saved restores while (MI != MBB.begin()) if (!(--MI)->getFlag(MachineInstr::FrameDestroy)) { ++MI; break; } // consume stack adjustment while (MI != MBB.begin()) { MachineBasicBlock::iterator PI = std::prev(MI); unsigned Opc = PI->getOpcode(); if ((Opc == Z80::POP24r || Opc == Z80::POP16r) && PI->getOperand(0).isDead()) { StackSize += SlotSize; } else if (Opc == Z80::LD24SP || Opc == Z80::LD16SP) { bool Is24Bit = Opc == Z80::LD24SP; unsigned Reg = PI->getOperand(0).getReg(); if (PI == MBB.begin()) break; MachineBasicBlock::iterator AI = std::prev(PI); Opc = AI->getOpcode(); if (AI == MBB.begin() || Opc != (Is24Bit ? Z80::ADD24SP : Z80::ADD16SP) || AI->getOperand(0).getReg() != Reg || AI->getOperand(1).getReg() != Reg) break; MachineBasicBlock::iterator LI = std::prev(AI); Opc = LI->getOpcode(); if (Opc != (Is24Bit ? Z80::LD24ri : Z80::LD16ri) || LI->getOperand(0).getReg() != Reg) break; StackSize += LI->getOperand(1).getImm(); LI->removeFromParent(); AI->removeFromParent(); } else break; PI->removeFromParent(); } bool HasFP = hasFP(MF); BuildStackAdjustment(MF, MBB, MI, DL, *ScratchReg, StackSize, HasFP ? StackSize : -1, MFI.hasVarSizedObjects()); if (HasFP) BuildMI(MBB, MI, DL, TII.get(Is24Bit ? Z80::POP24r : Z80::POP16r), TRI->getFrameRegister(MF)); }