bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
// We can't realign the stack if:
// 1. Dynamic stack realignment is explicitly disabled,
- // 2. There are VLAs in the function and the base pointer is disabled.
- return (RealignStack && (!MFI->hasVarSizedObjects() || EnableBasePointer));
+ // 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.
+ return (RealignStack && !AFI->isThumb1OnlyFunction() &&
+ (!MFI->hasVarSizedObjects() || EnableBasePointer));
}
bool ARMBaseRegisterInfo::
// 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. Also spill R4 if Thumb1 function requires stack
- // realignment.
+ // it here will be OK.
// FIXME: It will be better just to find spare register here.
unsigned StackSize = estimateStackSize(MF);
- if (MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
- StackSize > 508)
+ if (MFI->hasVarSizedObjects() || StackSize > 508)
MF.getRegInfo().setPhysRegUsed(ARM::R4);
}
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);
- }
+ // 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 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
+++ /dev/null
-; RUN: llc < %s -mtriple=thumbv6-apple-darwin | FileCheck %s
-
-; Normal load from SP
-define void @SP(i32 %i) nounwind uwtable ssp {
-entry:
-; CHECK: @SP
-; CHECK: push {r7, lr}
-; CHECK-NEXT: mov r7, sp
-; CHECK-NEXT: sub sp, #4
-; CHECK-NEXT: mov r1, sp
-; CHECK-NEXT: str r0, [r1]
-; CHECK-NEXT: mov r0, sp
-; CHECK-NEXT: blx _SP_
-; CHECK-NEXT: add sp, #4
-; CHECK-NEXT: pop {r7, pc}
- %i.addr = alloca i32, align 4
- store i32 %i, i32* %i.addr, align 4
- call void @SP_(i32* %i.addr)
- ret void
-}
-
-declare void @SP_(i32*)
-
-; Dynamic stack realignment
-define void @FP(double %a) nounwind uwtable ssp {
-entry:
-; CHECK: mov r4, sp
-; CHECK-NEXT: lsrs r4, r4, #3
-; CHECK-NEXT: lsls r4, r4, #3
-; CHECK-NEXT: mov sp, r4
-; Restore from FP
-; CHECK: subs r4, r7, #4
-; CHECK: mov sp, r4
- %a.addr = alloca double, align 8
- store double %a, double* %a.addr, align 8
- call void @FP_(double* %a.addr)
- ret void
-}
-
-declare void @FP_(double*)