diff options
Diffstat (limited to 'lib/Target/ARM/Thumb1FrameLowering.cpp')
-rw-r--r-- | lib/Target/ARM/Thumb1FrameLowering.cpp | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp index c258870e48..ad1edc8dd8 100644 --- a/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -21,7 +21,7 @@ using namespace llvm; -bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { +bool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{ const MachineFrameInfo *FFI = MF.getFrameInfo(); unsigned CFSize = FFI->getMaxCallFrameSize(); // It's not always a good idea to include the call frame as part of the @@ -133,9 +133,9 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { // Adjust FP so it point to the stack slot that contains the previous FP. if (hasFP(MF)) { - BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) .addFrameIndex(FramePtrSpillFI).addImm(0) - .setMIFlags(MachineInstr::FrameSetup); + .setMIFlags(MachineInstr::FrameSetup)); if (NumBytes > 508) // If offset is > 508 then sp cannot be adjusted in a single instruction, // try restoring from fp instead. @@ -155,6 +155,33 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); AFI->setDPRCalleeSavedAreaSize(DPRCSSize); + // If we need dynamic stack realignment, do it here. Be paranoid and make + // sure if we also have VLAs, we have a base pointer for frame access. + if (RegInfo->needsStackRealignment(MF)) { + // We cannot use sp as source/dest register here, thus we're emitting the + // following sequence: + // mov r4, sp + // lsrs r4, r4, Log2MaxAlign + // lsls r4, r4, Log2MaxAlign + // mov sp, r4 + unsigned MaxAlign = MFI->getMaxAlignment(); + unsigned Log2MaxAlign = Log2_32(MaxAlign); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4) + .addReg(ARM::SP, RegState::Kill)); + AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), + ARM::R4)) + .addReg(ARM::R4, RegState::Kill) + .addImm(Log2MaxAlign)); + AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), + ARM::R4)) + .addReg(ARM::R4, RegState::Kill) + .addImm(Log2MaxAlign)); + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP) + .addReg(ARM::R4, RegState::Kill)); + + AFI->setShouldRestoreSPFromFP(true); + } + // If we need a base pointer, set it up here. It's whatever the value // of the stack pointer is at this point. Any variable size objects // will be allocated after this, so we can still use the base pointer |