Changes in directory llvm/lib/Target/ARM:
ARMInstrThumb.td updated: 1.11 -> 1.12 ARMRegisterInfo.cpp updated: 1.51 -> 1.52 --- Log message: Special epilogue for vararg functions. We cannot do a pop to pc because there follows a sp increment for the va register save region. Instead issue a separate pop to another register, increment sp, and then return: pop {r4, r5, r6, r7} pop {r3} add sp, #3 * 4 bx r3 --- Diffs of the changes: (+24 -5) ARMInstrThumb.td | 5 ++++- ARMRegisterInfo.cpp | 24 ++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) Index: llvm/lib/Target/ARM/ARMInstrThumb.td diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.11 llvm/lib/Target/ARM/ARMInstrThumb.td:1.12 --- llvm/lib/Target/ARM/ARMInstrThumb.td:1.11 Wed Jan 31 14:12:31 2007 +++ llvm/lib/Target/ARM/ARMInstrThumb.td Wed Jan 31 19:49:46 2007 @@ -165,8 +165,11 @@ // Control Flow Instructions. // -let isReturn = 1, isTerminator = 1 in +let isReturn = 1, isTerminator = 1 in { def tBX_RET : TI<(ops), "bx lr", [(ARMretflag)]>; + // Alternative return instruction used by vararg functions. + def tBX_RET_vararg : TI<(ops GPR:$dst), "bx $dst", []>; +} // FIXME: remove when we have a way to marking a MI with these properties. let isLoad = 1, isReturn = 1, isTerminator = 1 in Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.51 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.52 --- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.51 Wed Jan 31 17:17:29 2007 +++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp Wed Jan 31 19:49:46 2007 @@ -104,11 +104,15 @@ if (!AFI->isThumbFunction() || CSI.empty()) return false; + bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; MachineInstr *PopMI = new MachineInstr(TII.get(ARM::tPOP)); MBB.insert(MI, PopMI); for (unsigned i = CSI.size(); i != 0; --i) { unsigned Reg = CSI[i-1].getReg(); if (Reg == ARM::LR) { + // Special epilogue for vararg functions. See emitEpilogue + if (isVarArg) + continue; Reg = ARM::PC; PopMI->setInstrDescriptor(TII.get(ARM::tPOP_RET)); MBB.erase(MI); @@ -1115,9 +1119,15 @@ NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + AFI->getGPRCalleeSavedArea2Size() + AFI->getDPRCalleeSavedAreaSize()); - if (isThumb) - emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII); - else { + if (isThumb) { + if (MBBI->getOpcode() == ARM::tBX_RET && + &MBB.front() != MBBI && + prior(MBBI)->getOpcode() == ARM::tPOP) { + MachineBasicBlock::iterator PMBBI = prior(MBBI); + emitSPUpdate(MBB, PMBBI, NumBytes, isThumb, TII); + } else + emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII); + } else { // Darwin ABI requires FP to point to the stack slot that contains the // previous FP. if (STI.isTargetDarwin() || hasFP(MF)) { @@ -1149,8 +1159,14 @@ emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII); } - if (VARegSaveSize) + if (VARegSaveSize) { + // Epilogue for vararg functions: pop LR to R3 and branch off it. + // FIXME: Verify this is still ok when R3 is no longer being reserved. + BuildMI(MBB, MBBI, TII.get(ARM::tPOP)).addReg(ARM::R3); emitSPUpdate(MBB, MBBI, VARegSaveSize, isThumb, TII); + BuildMI(MBB, MBBI, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); + MBB.erase(MBBI); + } } unsigned ARMRegisterInfo::getRARegister() const { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits