diff options
Diffstat (limited to 'lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r-- | lib/Target/ARM/ARMFrameLowering.cpp | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index 2629496cc5..72ec16bbe2 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -24,6 +24,9 @@ #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" +// @LOCALMOD-START +#include "llvm/CodeGen/MachineModuleInfo.h" +// @LOCALMOD-END using namespace llvm; @@ -151,6 +154,14 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { int FramePtrSpillFI = 0; int D8SpillFI = 0; + // @LOCALMOD-START + MachineModuleInfo &MMI = MF.getMMI(); + // This condition was gleaned from x86 / PowerPC / XCore + bool needsFrameMoves = MMI.hasDebugInfo() || + !MF.getFunction()->doesNotThrow() || + MF.getFunction()->needsUnwindTableEntry(); + // @LOCALMOD-END + // Allocate the vararg register save area. This is not counted in NumBytes. if (VARegSaveSize) emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize, @@ -205,6 +216,42 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { // Move past area 1. if (GPRCS1Size > 0) MBBI++; + // @LOCALMOD-START + if (needsFrameMoves && GPRCS1Size > 0) { + // we just skipped the initial callee save reg instructions, e.g. + // push {r4, r5, r6, lr} + // NOTE: this likely is not the right thing to do for darwin as it does not + // treat all callee save regs uniformly + MCSymbol *AfterRegSave = MMI.getContext().CreateTempSymbol(); + 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); + MMI.getFrameMoves().push_back(MachineMove(AfterRegSave, dst, src)); + // for each callee saved register record where it has been saved + int offset = 0; + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + switch (Reg) { + case ARM::R4: + case ARM::R5: + case ARM::R6: + case ARM::R7: + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + case ARM::LR: + offset -= 4; + MachineLocation dst(MachineLocation::VirtualFP, offset); + MachineLocation src(Reg); + MMI.getFrameMoves().push_back(MachineMove(AfterRegSave, dst, src)); + break; + } + } + } + // @LOCALMOD-END + // Set FP to point to the stack slot that contains the previous FP. // For iOS, FP is R7, which has now been stored in spill area 1. // Otherwise, if this is not iOS, all the callee-saved registers go @@ -218,8 +265,29 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { .addFrameIndex(FramePtrSpillFI).addImm(0) .setMIFlag(MachineInstr::FrameSetup); AddDefaultCC(AddDefaultPred(MIB)); + // @LOCALMOD-START + if (needsFrameMoves) { + // we just emitted the fp pointer setup instruction, e.g. + // add r11, sp, #8 + MCSymbol *AfterFramePointerInit = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, + TII.get(ARM::PROLOG_LABEL)).addSym(AfterFramePointerInit); + // record the fact that the frame pointer is now tracking the "cfa" + // Note, gcc and llvm have a slightly different notion of where the + // frame pointer should be pointing. gcc points after the return address + // and llvm one word further down (two words = 8). + // This should be fine as long as we are consistent. + // NOTE: this is related to the offset computed for + // ISD::FRAME_TO_ARGS_OFFSET + MachineLocation dst(MachineLocation::VirtualFP); + MachineLocation src(FramePtr, 8); + MMI.getFrameMoves().push_back(MachineMove(AfterFramePointerInit, dst, src)); + } + // @LOCALMOD-END } + + // Move past area 2. if (GPRCS2Size > 0) MBBI++; @@ -268,6 +336,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const { // an inconsistent state (pointing to the middle of callee-saved area). // The interrupt handler can end up clobbering the registers. AFI->setShouldRestoreSPFromFP(true); + + // @LOCALMOD-START + // we only track sp changes if do not have the fp to figure out where + // stack frame lives + if (needsFrameMoves && !HasFP) { + 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); + MMI.getFrameMoves().push_back(MachineMove(AfterStackUpdate, dst, src)); + } + // @LOCALMOD-END } if (STI.isTargetELF() && hasFP(MF)) @@ -658,7 +739,8 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) continue; - if (Reg == ARM::LR && !isTailCall && !isVarArg && STI.hasV5TOps()) { + if (Reg == ARM::LR && !isTailCall && !isVarArg && STI.hasV5TOps() && + false /* @LOCALMOD */) { Reg = ARM::PC; LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET; // Fold the return instruction into the LDM. |