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
llvm-svn: 33739
This commit is contained in:
parent
df4e992af8
commit
e7e966de5e
|
|
@ -165,8 +165,11 @@ def tPICADD : TIt<(ops GPR:$dst, GPR:$lhs, pclabel:$cp),
|
||||||
// Control Flow Instructions.
|
// Control Flow Instructions.
|
||||||
//
|
//
|
||||||
|
|
||||||
let isReturn = 1, isTerminator = 1 in
|
let isReturn = 1, isTerminator = 1 in {
|
||||||
def tBX_RET : TI<(ops), "bx lr", [(ARMretflag)]>;
|
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.
|
// FIXME: remove when we have a way to marking a MI with these properties.
|
||||||
let isLoad = 1, isReturn = 1, isTerminator = 1 in
|
let isLoad = 1, isReturn = 1, isTerminator = 1 in
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,15 @@ bool ARMRegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||||
if (!AFI->isThumbFunction() || CSI.empty())
|
if (!AFI->isThumbFunction() || CSI.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
|
||||||
MachineInstr *PopMI = new MachineInstr(TII.get(ARM::tPOP));
|
MachineInstr *PopMI = new MachineInstr(TII.get(ARM::tPOP));
|
||||||
MBB.insert(MI, PopMI);
|
MBB.insert(MI, PopMI);
|
||||||
for (unsigned i = CSI.size(); i != 0; --i) {
|
for (unsigned i = CSI.size(); i != 0; --i) {
|
||||||
unsigned Reg = CSI[i-1].getReg();
|
unsigned Reg = CSI[i-1].getReg();
|
||||||
if (Reg == ARM::LR) {
|
if (Reg == ARM::LR) {
|
||||||
|
// Special epilogue for vararg functions. See emitEpilogue
|
||||||
|
if (isVarArg)
|
||||||
|
continue;
|
||||||
Reg = ARM::PC;
|
Reg = ARM::PC;
|
||||||
PopMI->setInstrDescriptor(TII.get(ARM::tPOP_RET));
|
PopMI->setInstrDescriptor(TII.get(ARM::tPOP_RET));
|
||||||
MBB.erase(MI);
|
MBB.erase(MI);
|
||||||
|
|
@ -1115,9 +1119,15 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
||||||
AFI->getGPRCalleeSavedArea2Size() +
|
AFI->getGPRCalleeSavedArea2Size() +
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
if (isThumb)
|
if (isThumb) {
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
if (MBBI->getOpcode() == ARM::tBX_RET &&
|
||||||
else {
|
&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
|
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||||
// previous FP.
|
// previous FP.
|
||||||
if (STI.isTargetDarwin() || hasFP(MF)) {
|
if (STI.isTargetDarwin() || hasFP(MF)) {
|
||||||
|
|
@ -1149,8 +1159,14 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII);
|
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);
|
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 {
|
unsigned ARMRegisterInfo::getRARegister() const {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue