diff options
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcFrameLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcFrameLowering.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp index a740de9123c9..000418be9a9e 100644 --- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp @@ -218,8 +218,9 @@ void SparcFrameLowering::emitEpilogue(MachineFunction &MF, const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); DebugLoc dl = MBBI->getDebugLoc(); - assert(MBBI->getOpcode() == SP::RETL && - "Can only put epilog before 'retl' instruction!"); + assert((MBBI->getOpcode() == SP::RETL || MBBI->getOpcode() == SP::TAIL_CALL || + MBBI->getOpcode() == SP::TAIL_CALLri) && + "Can only put epilog before 'retl' or 'tail_call' instruction!"); if (!FuncInfo->isLeafProc()) { BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0) .addReg(SP::G0); @@ -228,10 +229,19 @@ void SparcFrameLowering::emitEpilogue(MachineFunction &MF, MachineFrameInfo &MFI = MF.getFrameInfo(); int NumBytes = (int) MFI.getStackSize(); - if (NumBytes == 0) - return; + if (NumBytes != 0) + emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri); - emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri); + // Preserve return address in %o7 + if (MBBI->getOpcode() == SP::TAIL_CALL) { + MBB.addLiveIn(SP::O7); + BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::G1) + .addReg(SP::G0) + .addReg(SP::O7); + BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::O7) + .addReg(SP::G0) + .addReg(SP::G1); + } } bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { @@ -316,10 +326,11 @@ bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const MachineRegisterInfo &MRI = MF.getRegInfo(); MachineFrameInfo &MFI = MF.getFrameInfo(); - return !(MFI.hasCalls() // has calls - || MRI.isPhysRegUsed(SP::L0) // Too many registers needed - || MRI.isPhysRegUsed(SP::O6) // %sp is used - || hasFP(MF)); // need %fp + return !(MFI.hasCalls() // has calls + || MRI.isPhysRegUsed(SP::L0) // Too many registers needed + || MRI.isPhysRegUsed(SP::O6) // %sp is used + || hasFP(MF) // need %fp + || MF.hasInlineAsm()); // has inline assembly } void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const { |
