diff options
| author | Jim Grosbach <grosbach@apple.com> | 2010-03-06 03:28:39 +0000 |
|---|---|---|
| committer | Jim Grosbach <grosbach@apple.com> | 2010-03-06 03:28:39 +0000 |
| commit | 24c9b550b228ef60b18ab06bb1db38f95aa8b53b (patch) | |
| tree | 1cf4b715336d6743909b71279b6aa61a137df7e9 /llvm | |
| parent | d8b43d0e5974a595e76055bc9adec338cd8743fd (diff) | |
| download | bcm5719-llvm-24c9b550b228ef60b18ab06bb1db38f95aa8b53b.tar.gz bcm5719-llvm-24c9b550b228ef60b18ab06bb1db38f95aa8b53b.zip | |
Thumb1 epilogue code generation needs to take into account that callee-saved
registers may be restored via a pop instruction, not just a tRestore.
This fixes nightly test 471.omnetep for Thumb1.
llvm-svn: 97867
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/Thumb1RegisterInfo.cpp | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/Thumb1RegisterInfo.cpp b/llvm/lib/Target/ARM/Thumb1RegisterInfo.cpp index b61ce29aab8..163d1e9a0dd 100644 --- a/llvm/lib/Target/ARM/Thumb1RegisterInfo.cpp +++ b/llvm/lib/Target/ARM/Thumb1RegisterInfo.cpp @@ -778,9 +778,19 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { } static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { - return (MI->getOpcode() == ARM::tRestore && - MI->getOperand(1).isFI() && - isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); + if (MI->getOpcode() == ARM::tRestore && + MI->getOperand(1).isFI() && + isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)) + return true; + else if (MI->getOpcode() == ARM::tPOP) { + // The first three operands are predicates and such. The last two are + // imp-def and imp-use of SP. Check everything in between. + for (int i = 3, e = MI->getNumOperands() - 2; i != e; ++i) + if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs)) + return false; + return true; + } + return false; } void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF, @@ -794,13 +804,13 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF, ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); int NumBytes = (int)MFI->getStackSize(); + const unsigned *CSRegs = getCalleeSavedRegs(); if (!AFI->hasStackFrame()) { if (NumBytes != 0) emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes); } else { // Unwind MBBI to point to first LDR / VLDRD. - const unsigned *CSRegs = getCalleeSavedRegs(); if (MBBI != MBB.begin()) { do --MBBI; @@ -836,6 +846,9 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF, } if (VARegSaveSize) { + // Move back past the callee-saved register restoration + while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs)) + ++MBBI; // Epilogue for vararg functions: pop LR to R3 and branch off it. AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))) .addReg(0) // No write back. @@ -845,6 +858,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)) .addReg(ARM::R3, RegState::Kill); + // erase the old tBX_RET instruction MBB.erase(MBBI); } } |

