const ThumbRegisterInfo *RegInfo =
static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
- // If MBBI is a return instruction, we may be able to directly restore
- // LR in the PC.
- // This is possible if we do not need to emit any SP update.
- // Otherwise, we need a temporary register to pop the value
- // and copy that value into LR.
+ // When we need a special fix up for POP, this means that
+ // we either cannot use PC in POP or we have to update
+ // SP after poping the return address.
+ // In other words, we cannot use a pop {pc} like construction
+ // here, no matter what.
auto MBBI = MBB.getFirstTerminator();
- if (!ArgRegsSaveSize && MBBI != MBB.end() &&
- MBBI->getOpcode() == ARM::tBX_RET) {
- if (!DoIt)
- return true;
- MachineInstrBuilder MIB =
- AddDefaultPred(
- BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII.get(ARM::tPOP_RET)))
- .addReg(ARM::PC, RegState::Define);
- MIB.copyImplicitOps(&*MBBI);
- // erase the old tBX_RET instruction
- MBB.erase(MBBI);
- return true;
- }
// Look for a temporary register to use.
// First, compute the liveness information.
; --------
; CHECK-V4T: add sp,
; CHECK-V4T-NEXT: pop {[[SAVED]]}
-; We do not have any SP update to insert so we can just optimize
-; the pop sequence.
-; CHECK-V4T-NEXT: pop {pc}
+; The ISA for v4 does not support pop pc, so make sure we do not emit
+; one even when we do not need to update SP.
+; CHECK-V4T-NOT: pop {pc}
+; We may only use lo register to pop, but in that case, all the scratch
+; ones are used.
+; r12 is the only register we are allowed to clobber for AAPCS.
+; Use it to save a lo register.
+; CHECK-V4T-NEXT: mov [[TEMP_REG:r12]], [[POP_REG:r[0-7]]]
+; Pop the value of LR.
+; CHECK-V4T-NEXT: pop {[[POP_REG]]}
+; Copy the value of LR in the right register.
+; CHECK-V4T-NEXT: mov lr, [[POP_REG]]
+; Restore the value that was in the register we used to pop the value of LR.
+; CHECK-V4T-NEXT: mov [[POP_REG]], [[TEMP_REG]]
+; Return.
+; CHECK-V4T-NEXT: bx lr
; CHECK-V5T: pop {[[SAVED]], pc}
}
; Epilogue
; --------
; CHECK-V4T: pop {[[SAVED]]}
-; CHECK-V4T: pop {pc}
+; The ISA for v4 does not support pop pc, so make sure we do not emit
+; one even when we do not need to update SP.
+; CHECK-V4T-NOT: pop {pc}
+; Pop the value of LR into a scratch lo register other than r0 (it is
+; used for the return value).
+; CHECK-V4T-NEXT: pop {[[POP_REG:r[1-3]]]}
+; CHECK-V4T-NEXT: bx [[POP_REG]]
; CHECK-V5T: pop {[[SAVED]], pc}
}