mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-26 07:29:55 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97867 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
75f0d6953a
commit
e68bd74245
@ -778,9 +778,19 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
|
static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
|
||||||
return (MI->getOpcode() == ARM::tRestore &&
|
if (MI->getOpcode() == ARM::tRestore &&
|
||||||
MI->getOperand(1).isFI() &&
|
MI->getOperand(1).isFI() &&
|
||||||
isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
|
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,
|
void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
@ -794,13 +804,13 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||||
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
|
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
|
||||||
int NumBytes = (int)MFI->getStackSize();
|
int NumBytes = (int)MFI->getStackSize();
|
||||||
|
const unsigned *CSRegs = getCalleeSavedRegs();
|
||||||
|
|
||||||
if (!AFI->hasStackFrame()) {
|
if (!AFI->hasStackFrame()) {
|
||||||
if (NumBytes != 0)
|
if (NumBytes != 0)
|
||||||
emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
|
emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
|
||||||
} else {
|
} else {
|
||||||
// Unwind MBBI to point to first LDR / VLDRD.
|
// Unwind MBBI to point to first LDR / VLDRD.
|
||||||
const unsigned *CSRegs = getCalleeSavedRegs();
|
|
||||||
if (MBBI != MBB.begin()) {
|
if (MBBI != MBB.begin()) {
|
||||||
do
|
do
|
||||||
--MBBI;
|
--MBBI;
|
||||||
@ -836,6 +846,9 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (VARegSaveSize) {
|
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.
|
// Epilogue for vararg functions: pop LR to R3 and branch off it.
|
||||||
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
|
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
|
||||||
.addReg(0) // No write back.
|
.addReg(0) // No write back.
|
||||||
@ -845,6 +858,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
|
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
|
BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg))
|
||||||
.addReg(ARM::R3, RegState::Kill);
|
.addReg(ARM::R3, RegState::Kill);
|
||||||
|
// erase the old tBX_RET instruction
|
||||||
MBB.erase(MBBI);
|
MBB.erase(MBBI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user