diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-09-06 14:25:01 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-09-06 14:25:01 -0700 |
commit | 45f9be95ab8e334e7e4b4328ee297d032e64b788 (patch) | |
tree | f5eabe8e5e26caa70352747f04f3282938f9281d | |
parent | 9b86d1e242fec1dce22eda36b8f2eb3d6f1cc380 (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.cpp | 46 |
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); } - |