aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-09-06 14:25:01 -0700
committerDerek Schuff <dschuff@chromium.org>2013-09-06 14:25:01 -0700
commit45f9be95ab8e334e7e4b4328ee297d032e64b788 (patch)
treef5eabe8e5e26caa70352747f04f3282938f9281d
parent9b86d1e242fec1dce22eda36b8f2eb3d6f1cc380 (diff)
Emit MachineMoves for ARM floating point callee-saved registers
Currently when a function uses floating-point callee-saved registers, it does not emit unwind info for adjusting the CFA and showing the locations of the saved registers on the stack. This results in the unwinder getting a bad value for the return address when it attempts to unwind past the function's frame, which breaks gdb backtracing and exception handling unwinding. Add to the existing MachineMoves describing the CFA and register locations to handle the float registers BUG= https://code.google.com/p/nativeclient/issues/detail?id=3670 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/23691041
-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);
}
-