aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMFrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp46
1 files changed, 41 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 0cff686481..f2e7ebef66 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -225,6 +225,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
if (GPRCS1Size > 0) MBBI++;
// @LOCALMOD-START
+ unsigned TotalCfaAdjust = GPRCS1Size;
if (needsFrameMoves && GPRCS1Size > 0) {
// we just skipped the initial callee save reg instructions, e.g.
// push {r4, r5, r6, lr}
@@ -234,7 +235,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(AfterRegSave);
// record the fact that the stack has moved
MachineLocation dst(MachineLocation::VirtualFP);
- MachineLocation src(MachineLocation::VirtualFP, -GPRCS1Size);
+ MachineLocation src(MachineLocation::VirtualFP, -TotalCfaAdjust);
MMI.getFrameMoves().push_back(MachineMove(AfterRegSave, dst, src));
// for each callee saved register record where it has been saved
int offset = 0;
@@ -317,6 +318,41 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
// instructions in the prologue.
while (MBBI->getOpcode() == ARM::VSTMDDB_UPD)
MBBI++;
+
+ // @LOCALMOD-BEGIN
+ if(needsFrameMoves) {
+ MCSymbol *AfterRegSave = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(ARM::PROLOG_LABEL)).addSym(AfterRegSave);
+ if (!HasFP) {
+ // CFA offset needs to be updated if it is relative to the SP (which as
+ // just moved). Otherwise it is relative to FP, which has not changed.
+ TotalCfaAdjust += DPRCSSize;
+ MachineLocation dst(MachineLocation::VirtualFP);
+ MachineLocation src(MachineLocation::VirtualFP, -TotalCfaAdjust);
+ MMI.getFrameMoves().push_back(MachineMove(AfterRegSave, dst, src));
+ }
+ // for each callee saved register record where it has been saved
+ int offset = -GPRCS1Size;
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ unsigned Reg = CSI[i].getReg();
+ switch (Reg) {
+ case ARM::D8:
+ case ARM::D9:
+ case ARM::D10:
+ case ARM::D11:
+ case ARM::D12:
+ case ARM::D13:
+ case ARM::D14:
+ case ARM::D15:
+ offset -= 8;
+ MachineLocation dst(MachineLocation::VirtualFP, offset);
+ MachineLocation src(Reg);
+ MMI.getFrameMoves().push_back(MachineMove(AfterRegSave, dst, src));
+ break;
+ }
+ }
+ }
+ // @LOCALMOD-END
}
// Move past the aligned DPRCS2 area.
@@ -346,14 +382,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
AFI->setShouldRestoreSPFromFP(true);
// @LOCALMOD-START
- // we only track sp changes if do not have the fp to figure out where
- // stack frame lives
+ // CFA offset needs to be updated if it is relative to the SP (which as
+ // just moved). Otherwise it is relative to FP, which has not changed.
if (needsFrameMoves && !HasFP) {
+ TotalCfaAdjust += NumBytes;
MCSymbol *AfterStackUpdate = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl,
TII.get(ARM::PROLOG_LABEL)).addSym(AfterStackUpdate);
MachineLocation dst(MachineLocation::VirtualFP);
- MachineLocation src(MachineLocation::VirtualFP, - NumBytes - GPRCS1Size);
+ MachineLocation src(MachineLocation::VirtualFP, -TotalCfaAdjust);
MMI.getFrameMoves().push_back(MachineMove(AfterStackUpdate, dst, src));
}
// @LOCALMOD-END
@@ -1510,4 +1547,3 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
}
MBB.erase(I);
}
-