diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Thumb1FrameLowering.cpp | 34 |
3 files changed, 38 insertions, 16 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index bf39aebaf44..63b14ee98d7 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -391,16 +391,12 @@ bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { const MachineRegisterInfo *MRI = &MF.getRegInfo(); - const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); const ARMFrameLowering *TFI = getFrameLowering(MF); // We can't realign the stack if: // 1. Dynamic stack realignment is explicitly disabled, - // 2. This is a Thumb1 function (it's not useful, so we don't bother), or - // 3. There are VLAs in the function and the base pointer is disabled. + // 2. There are VLAs in the function and the base pointer is disabled. if (!TargetRegisterInfo::canRealignStack(MF)) return false; - if (AFI->isThumb1OnlyFunction()) - return false; // Stack realignment requires a frame pointer. If we already started // register allocation with frame pointer elimination, it is too late now. if (!MRI->canReserveReg(getFramePointerReg(MF.getSubtarget<ARMSubtarget>()))) diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index 4af744f5ec3..ce4add974d6 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -1610,14 +1610,14 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, if (AFI->getArgRegsSaveSize() > 0) SavedRegs.set(ARM::LR); - // Spill R4 if Thumb1 epilogue has to restore SP from FP. We don't know - // for sure what the stack size will be, but for this, an estimate is good - // enough. If there anything changes it, it'll be a spill, which implies - // we've used all the registers and so R4 is already used, so not marking - // it here will be OK. + // Spill R4 if Thumb1 epilogue has to restore SP from FP or the function + // requires stack alignment. We don't know for sure what the stack size + // will be, but for this, an estimate is good enough. If there anything + // changes it, it'll be a spill, which implies we've used all the registers + // and so R4 is already used, so not marking it here will be OK. // FIXME: It will be better just to find spare register here. - unsigned StackSize = MFI.estimateStackSize(MF); - if (MFI.hasVarSizedObjects() || StackSize > 508) + if (MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) || + MFI.estimateStackSize(MF) > 508) SavedRegs.set(ARM::R4); } diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp index 13068992e8f..4f330e3a884 100644 --- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -352,10 +352,36 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF, AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); AFI->setDPRCalleeSavedAreaSize(DPRCSSize); - // Thumb1 does not currently support dynamic stack realignment. Report a - // fatal error rather then silently generate bad code. - if (RegInfo->needsStackRealignment(MF)) - report_fatal_error("Dynamic stack realignment not supported for thumb1."); + if (RegInfo->needsStackRealignment(MF)) { + const unsigned NrBitsToZero = countTrailingZeros(MFI.getMaxAlignment()); + // Emit the following sequence, using R4 as a temporary, since we cannot use + // SP as a source or destination register for the shifts: + // mov r4, sp + // lsrs r4, r4, #NrBitsToZero + // lsls r4, r4, #NrBitsToZero + // mov sp, r4 + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::R4) + .addReg(ARM::SP, RegState::Kill) + .add(predOps(ARMCC::AL)); + + BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSRri), ARM::R4) + .addDef(ARM::CPSR) + .addReg(ARM::R4, RegState::Kill) + .addImm(NrBitsToZero) + .add(predOps(ARMCC::AL)); + + BuildMI(MBB, MBBI, dl, TII.get(ARM::tLSLri), ARM::R4) + .addDef(ARM::CPSR) + .addReg(ARM::R4, RegState::Kill) + .addImm(NrBitsToZero) + .add(predOps(ARMCC::AL)); + + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), ARM::SP) + .addReg(ARM::R4, RegState::Kill) + .add(predOps(ARMCC::AL)); + + 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 |