summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorArtyom Skrobov <Artyom.Skrobov@arm.com>2014-02-14 17:19:07 +0000
committerArtyom Skrobov <Artyom.Skrobov@arm.com>2014-02-14 17:19:07 +0000
commite228078ca6de1c5316ec53a370568ea5d824f8e5 (patch)
tree7dfa79dfdd4dc4e51be2616dae57ac8876661dae /lib
parent54136cad2ea9f322849ce49b299860454fc97368 (diff)
downloadllvm-e228078ca6de1c5316ec53a370568ea5d824f8e5.tar.gz
llvm-e228078ca6de1c5316ec53a370568ea5d824f8e5.tar.bz2
llvm-e228078ca6de1c5316ec53a370568ea5d824f8e5.tar.xz
Generate the DWARF stack frame decode operations in the function prologue for ARM/Thumb functions.
Patch by Keith Walker! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp18
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp5
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h4
-rw-r--r--lib/Target/ARM/ARMFrameLowering.cpp204
-rw-r--r--lib/Target/ARM/Thumb1FrameLowering.cpp104
5 files changed, 296 insertions, 39 deletions
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 6e79bef8d0..403feb4583 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -37,7 +37,8 @@
using namespace llvm;
ARMException::ARMException(AsmPrinter *A)
- : DwarfException(A) {}
+ : DwarfException(A),
+ shouldEmitCFI(false) {}
ARMException::~ARMException() {}
@@ -46,7 +47,11 @@ ARMTargetStreamer &ARMException::getTargetStreamer() {
return static_cast<ARMTargetStreamer &>(TS);
}
+/// endModule - Emit all exception information that should come after the
+/// content.
void ARMException::endModule() {
+ if (shouldEmitCFI)
+ Asm->OutStreamer.EmitCFISections(false, true);
}
/// beginFunction - Gather pre-function exception information. Assumes it's
@@ -56,11 +61,22 @@ void ARMException::beginFunction(const MachineFunction *MF) {
if (Asm->MF->getFunction()->needsUnwindTableEntry())
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
Asm->getFunctionNumber()));
+ // See if we need call frame info.
+ AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
+ assert(MoveType != AsmPrinter::CFI_M_EH &&
+ "non-EH CFI not yet supported in prologue with EHABI lowering");
+ if (MoveType == AsmPrinter::CFI_M_Debug) {
+ shouldEmitCFI = true;
+ Asm->OutStreamer.EmitCFIStartProc(false);
+ }
}
/// endFunction - Gather and emit post-function exception information.
///
void ARMException::endFunction(const MachineFunction *) {
+ if (shouldEmitCFI)
+ Asm->OutStreamer.EmitCFIEndProc();
+
ARMTargetStreamer &ATS = getTargetStreamer();
if (!Asm->MF->getFunction()->needsUnwindTableEntry())
ATS.emitCantUnwind();
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2f15c97f2d..63b4bb4296 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -697,7 +697,10 @@ bool AsmPrinter::needsSEHMoves() {
void AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
const MCSymbol *Label = MI.getOperand(0).getMCSymbol();
- if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI)
+ ExceptionHandling::ExceptionsType ExceptionHandlingType =
+ MAI->getExceptionHandlingType();
+ if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
+ ExceptionHandlingType != ExceptionHandling::ARM)
return;
if (needsCFIMoves() == CFI_M_None)
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 5a2ee9e490..a28eaf0c14 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -186,6 +186,10 @@ class ARMException : public DwarfException {
void EmitTypeInfos(unsigned TTypeEncoding);
ARMTargetStreamer &getTargetStreamer();
+ /// shouldEmitCFI - Per-function flag to indicate if frame CFI info
+ /// should be emitted.
+ bool shouldEmitCFI;
+
public:
//===--------------------------------------------------------------------===//
// Main entry points.
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 63f1577821..916417882b 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -19,10 +19,12 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Function.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetOptions.h"
@@ -129,11 +131,24 @@ static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB,
MIFlags, Pred, PredReg);
}
+static int sizeOfSPAdjustment(const MachineInstr *MI) {
+ assert(MI->getOpcode() == ARM::VSTMDDB_UPD);
+ int count = 0;
+ // ARM and Thumb2 push/pop insts have explicit "sp, sp" operands (+
+ // pred) so the list starts at 4.
+ for (int i = MI->getNumOperands() - 1; i >= 4; --i)
+ count += 8;
+ return count;
+}
+
void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ MachineModuleInfo &MMI = MF.getMMI();
+ MCContext &Context = MMI.getContext();
+ const MCRegisterInfo *MRI = Context.getRegisterInfo();
const ARMBaseRegisterInfo *RegInfo =
static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
const ARMBaseInstrInfo &TII =
@@ -147,6 +162,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
unsigned FramePtr = RegInfo->getFrameRegister(MF);
+ int CFAOffset = 0;
// Determine the sizes of each callee-save spill areas and record which frame
// belongs to which callee-save spill areas.
@@ -160,21 +176,46 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
return;
// Allocate the vararg register save area. This is not counted in NumBytes.
- if (ArgRegsSaveSize)
+ if (ArgRegsSaveSize) {
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
MachineInstr::FrameSetup);
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= ArgRegsSaveSize;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
if (!AFI->hasStackFrame()) {
- if (NumBytes != 0)
+ if (NumBytes != 0) {
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
MachineInstr::FrameSetup);
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= NumBytes;
+ MMI.addFrameInst(MCCFIInstruction::createDefCfaOffset(SPLabel,
+ CFAOffset));
+ }
return;
}
+ // Determine spill area sizes.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
int FI = CSI[i].getFrameIdx();
switch (Reg) {
+ case ARM::R8:
+ case ARM::R9:
+ case ARM::R10:
+ case ARM::R11:
+ case ARM::R12:
+ if (STI.isTargetMachO()) {
+ GPRCS2Size += 4;
+ break;
+ }
+ // fallthrough
case ARM::R0:
case ARM::R1:
case ARM::R2:
@@ -188,18 +229,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
FramePtrSpillFI = FI;
GPRCS1Size += 4;
break;
- case ARM::R8:
- case ARM::R9:
- case ARM::R10:
- case ARM::R11:
- case ARM::R12:
- if (Reg == FramePtr)
- FramePtrSpillFI = FI;
- if (STI.isTargetMachO())
- GPRCS2Size += 4;
- else
- GPRCS1Size += 4;
- break;
default:
// This is a DPR. Exclude the aligned DPRCS2 spills.
if (Reg == ARM::D8)
@@ -210,9 +239,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
}
// Move past area 1.
- MachineBasicBlock::iterator LastPush = MBB.end(), FramePtrPush;
+ MachineBasicBlock::iterator LastPush = MBB.end(), GPRCS1Push, GPRCS2Push,
+ DPRCSPush;
if (GPRCS1Size > 0)
- FramePtrPush = LastPush = MBBI++;
+ GPRCS1Push = LastPush = MBBI++;
// Determine starting offsets of spill areas.
bool HasFP = hasFP(MF);
@@ -230,13 +260,12 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
// Move past area 2.
- if (GPRCS2Size > 0) {
- LastPush = MBBI++;
- }
+ if (GPRCS2Size > 0)
+ GPRCS2Push = LastPush = MBBI++;
// Move past area 3.
if (DPRCSSize > 0) {
- LastPush = MBBI++;
+ DPRCSPush = MBBI;
// Since vpush register list cannot have gaps, there may be multiple vpush
// instructions in the prologue.
while (MBBI->getOpcode() == ARM::VSTMDDB_UPD)
@@ -254,11 +283,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
} else
NumBytes = DPRCSOffset;
+ unsigned adjustedGPRCS1Size = GPRCS1Size;
if (NumBytes) {
// Adjust SP after all the callee-save spills.
if (tryFoldSPUpdateIntoPushPop(STI, MF, LastPush, NumBytes)) {
- if (LastPush == FramePtrPush)
+ if (LastPush == GPRCS1Push) {
FramePtrOffsetInPush += NumBytes;
+ adjustedGPRCS1Size += NumBytes;
+ NumBytes = 0;
+ }
} else
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
MachineInstr::FrameSetup);
@@ -275,17 +308,142 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
AFI->setShouldRestoreSPFromFP(true);
}
+ if (adjustedGPRCS1Size > 0) {
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, ++GPRCS1Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= adjustedGPRCS1Size;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
+ E = CSI.end(); I != E; ++I) {
+ unsigned Reg = I->getReg();
+ int FI = I->getFrameIdx();
+ switch (Reg) {
+ case ARM::R8:
+ case ARM::R9:
+ case ARM::R10:
+ case ARM::R11:
+ case ARM::R12:
+ if (STI.isTargetMachO())
+ break;
+ // fallthrough
+ case ARM::R0:
+ case ARM::R1:
+ case ARM::R2:
+ case ARM::R3:
+ case ARM::R4:
+ case ARM::R5:
+ case ARM::R6:
+ case ARM::R7:
+ case ARM::LR:
+ MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel,
+ MRI->getDwarfRegNum(Reg, true),
+ MFI->getObjectOffset(FI) - ArgRegsSaveSize));
+ break;
+ }
+ }
+ }
+
// 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
// into spill area 1, including the FP in R11. In either case, it
// is in area one and the adjustment needs to take place just after
// that push.
- if (HasFP)
- emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, ++FramePtrPush, dl, TII,
+ if (HasFP) {
+ emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, GPRCS1Push, dl, TII,
FramePtr, ARM::SP, FramePtrOffsetInPush,
MachineInstr::FrameSetup);
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, GPRCS1Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ if (FramePtrOffsetInPush) {
+ CFAOffset += FramePtrOffsetInPush;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfa(SPLabel,
+ MRI->getDwarfRegNum(FramePtr, true), CFAOffset));
+ } else
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaRegister(SPLabel,
+ MRI->getDwarfRegNum(FramePtr, true)));
+ }
+ if (GPRCS2Size > 0) {
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, ++GPRCS2Push, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ if (!HasFP) {
+ CFAOffset -= GPRCS2Size;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
+ E = CSI.end(); I != E; ++I) {
+ unsigned Reg = I->getReg();
+ int FI = I->getFrameIdx();
+ switch (Reg) {
+ case ARM::R8:
+ case ARM::R9:
+ case ARM::R10:
+ case ARM::R11:
+ case ARM::R12:
+ if (STI.isTargetMachO()) {
+ unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+ unsigned Offset = MFI->getObjectOffset(FI) - ArgRegsSaveSize;
+ MMI.addFrameInst(
+ MCCFIInstruction::createOffset(SPLabel, DwarfReg, Offset));
+ }
+ break;
+ }
+ }
+ }
+
+ if (DPRCSSize > 0) {
+ // Since vpush register list cannot have gaps, there may be multiple vpush
+ // instructions in the prologue.
+ MCSymbol *SPLabel = NULL;
+ do {
+ MachineBasicBlock::iterator Push = DPRCSPush++;
+ if (!HasFP) {
+ SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, DPRCSPush, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= sizeOfSPAdjustment(Push);;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
+ } while (DPRCSPush->getOpcode() == ARM::VSTMDDB_UPD);
+
+ if (!SPLabel) {
+ SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, DPRCSPush, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ }
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
+ E = CSI.end(); I != E; ++I) {
+ unsigned Reg = I->getReg();
+ int FI = I->getFrameIdx();
+ if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
+ (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs())) {
+ unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
+ unsigned Offset = MFI->getObjectOffset(FI);
+ MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel, DwarfReg,
+ Offset));
+ }
+ }
+ }
+
+ if (NumBytes) {
+ if (!HasFP) {
+ MCSymbol *SPLabel = Context.CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= NumBytes;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
+ }
if (STI.isTargetELF() && hasFP(MF))
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
diff --git a/lib/Target/ARM/Thumb1FrameLowering.cpp b/lib/Target/ARM/Thumb1FrameLowering.cpp
index 2a587dd25b..c2da0b68a2 100644
--- a/lib/Target/ARM/Thumb1FrameLowering.cpp
+++ b/lib/Target/ARM/Thumb1FrameLowering.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
using namespace llvm;
@@ -83,6 +84,8 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ MachineModuleInfo &MMI = MF.getMMI();
+ const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
const Thumb1RegisterInfo *RegInfo =
static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo());
const Thumb1InstrInfo &TII =
@@ -95,6 +98,7 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
unsigned FramePtr = RegInfo->getFrameRegister(MF);
unsigned BasePtr = RegInfo->getBaseRegister();
+ int CFAOffset = 0;
// Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
NumBytes = (NumBytes + 3) & ~3;
@@ -105,14 +109,28 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
int FramePtrSpillFI = 0;
- if (ArgRegsSaveSize)
+ if (ArgRegsSaveSize) {
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize,
MachineInstr::FrameSetup);
+ MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= ArgRegsSaveSize;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
if (!AFI->hasStackFrame()) {
- if (NumBytes != 0)
+ if (NumBytes != 0) {
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
MachineInstr::FrameSetup);
+ MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= NumBytes;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
return;
}
@@ -120,6 +138,15 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
unsigned Reg = CSI[i].getReg();
int FI = CSI[i].getFrameIdx();
switch (Reg) {
+ case ARM::R8:
+ case ARM::R9:
+ case ARM::R10:
+ case ARM::R11:
+ if (STI.isTargetMachO()) {
+ GPRCS2Size += 4;
+ break;
+ }
+ // fallthrough
case ARM::R4:
case ARM::R5:
case ARM::R6:
@@ -129,17 +156,6 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
FramePtrSpillFI = FI;
GPRCS1Size += 4;
break;
- case ARM::R8:
- case ARM::R9:
- case ARM::R10:
- case ARM::R11:
- if (Reg == FramePtr)
- FramePtrSpillFI = FI;
- if (STI.isTargetMachO())
- GPRCS2Size += 4;
- else
- GPRCS1Size += 4;
- break;
default:
DPRCSSize += 8;
}
@@ -165,27 +181,87 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
NumBytes = DPRCSOffset;
int FramePtrOffsetInBlock = 0;
+ unsigned adjustedGPRCS1Size = GPRCS1Size;
if (tryFoldSPUpdateIntoPushPop(STI, MF, prior(MBBI), NumBytes)) {
FramePtrOffsetInBlock = NumBytes;
+ adjustedGPRCS1Size += NumBytes;
NumBytes = 0;
}
+ MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SPLabel);
+ if (adjustedGPRCS1Size) {
+ CFAOffset -= adjustedGPRCS1Size;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
+ E = CSI.end(); I != E; ++I) {
+ unsigned Reg = I->getReg();
+ int FI = I->getFrameIdx();
+ switch (Reg) {
+ case ARM::R8:
+ case ARM::R9:
+ case ARM::R10:
+ case ARM::R11:
+ case ARM::R12:
+ if (STI.isTargetMachO())
+ break;
+ // fallthough
+ case ARM::R0:
+ case ARM::R1:
+ case ARM::R2:
+ case ARM::R3:
+ case ARM::R4:
+ case ARM::R5:
+ case ARM::R6:
+ case ARM::R7:
+ case ARM::LR:
+ MMI.addFrameInst(MCCFIInstruction::createOffset(SPLabel,
+ MRI->getDwarfRegNum(Reg, true),
+ MFI->getObjectOffset(FI) - ArgRegsSaveSize));
+ break;
+ }
+ }
+
+
// Adjust FP so it point to the stack slot that contains the previous FP.
if (HasFP) {
FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size;
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
.addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4)
.setMIFlags(MachineInstr::FrameSetup));
+ MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ if(FramePtrOffsetInBlock) {
+ CFAOffset += FramePtrOffsetInBlock;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfa(SPLabel,
+ MRI->getDwarfRegNum(FramePtr, true), CFAOffset));
+ } else
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaRegister(SPLabel,
+ MRI->getDwarfRegNum(FramePtr, true)));
if (NumBytes > 508)
// If offset is > 508 then sp cannot be adjusted in a single instruction,
// try restoring from fp instead.
AFI->setShouldRestoreSPFromFP(true);
}
- if (NumBytes)
+ if (NumBytes) {
// Insert it after all the callee-save spills.
emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes,
MachineInstr::FrameSetup);
+ if (!HasFP) {
+ MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL))
+ .addSym(SPLabel);
+ CFAOffset -= NumBytes;
+ MMI.addFrameInst(
+ MCCFIInstruction::createDefCfaOffset(SPLabel, CFAOffset));
+ }
+ }
if (STI.isTargetELF() && HasFP)
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -