mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-30 19:55:11 +00:00
Add support for dynamic stack realignment when in thumb1 mode.
rdar://10288916 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142337 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
895ede819f
commit
fe04757f5e
@ -626,13 +626,10 @@ bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
|||||||
|
|
||||||
bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
|
||||||
// We can't realign the stack if:
|
// We can't realign the stack if:
|
||||||
// 1. Dynamic stack realignment is explicitly disabled,
|
// 1. Dynamic stack realignment is explicitly disabled,
|
||||||
// 2. This is a Thumb1 function (it's not useful, so we don't bother), or
|
// 2. There are VLAs in the function and the base pointer is disabled.
|
||||||
// 3. There are VLAs in the function and the base pointer is disabled.
|
return (RealignStack && (!MFI->hasVarSizedObjects() || EnableBasePointer));
|
||||||
return (RealignStack && !AFI->isThumb1OnlyFunction() &&
|
|
||||||
(!MFI->hasVarSizedObjects() || EnableBasePointer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ARMBaseRegisterInfo::
|
bool ARMBaseRegisterInfo::
|
||||||
|
@ -881,10 +881,12 @@ ARMFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
// for sure what the stack size will be, but for this, an estimate is good
|
// 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
|
// 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
|
// we've used all the registers and so R4 is already used, so not marking
|
||||||
// it here will be OK.
|
// it here will be OK. Also spill R4 if Thumb1 function requires stack
|
||||||
|
// realignment.
|
||||||
// FIXME: It will be better just to find spare register here.
|
// FIXME: It will be better just to find spare register here.
|
||||||
unsigned StackSize = estimateStackSize(MF);
|
unsigned StackSize = estimateStackSize(MF);
|
||||||
if (MFI->hasVarSizedObjects() || StackSize > 508)
|
if (MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF) ||
|
||||||
|
StackSize > 508)
|
||||||
MF.getRegInfo().setPhysRegUsed(ARM::R4);
|
MF.getRegInfo().setPhysRegUsed(ARM::R4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,10 +155,32 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
||||||
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
|
||||||
|
|
||||||
// Thumb1 does not currently support dynamic stack realignment. Report a
|
// If we need dynamic stack realignment, do it here. Be paranoid and make
|
||||||
// fatal error rather then silently generate bad code.
|
// sure if we also have VLAs, we have a base pointer for frame access.
|
||||||
if (RegInfo->needsStackRealignment(MF))
|
if (RegInfo->needsStackRealignment(MF)) {
|
||||||
report_fatal_error("Dynamic stack realignment not supported for thumb1.");
|
// 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
|
// 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
|
// of the stack pointer is at this point. Any variable size objects
|
||||||
|
40
test/CodeGen/ARM/thumb1-dynrealign.ll
Normal file
40
test/CodeGen/ARM/thumb1-dynrealign.ll
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
; 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*)
|
Loading…
Reference in New Issue
Block a user