mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
Generate the DWARF stack frame decode operations in the function prologue for ARM/Thumb functions.
Patch by Keith Walker! llvm-svn: 201423
This commit is contained in:
parent
fa58a631ae
commit
10498a713c
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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() -
|
||||
|
@ -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() -
|
||||
|
99
test/CodeGen/ARM/debug-frame-large-stack.ll
Normal file
99
test/CodeGen/ARM/debug-frame-large-stack.ll
Normal file
@ -0,0 +1,99 @@
|
||||
; RUN: llc -filetype=asm -o - < %s -mtriple arm-arm-none-eabi -disable-fp-elim| FileCheck %s --check-prefix=CHECK-ARM
|
||||
; RUN: llc -filetype=asm -o - < %s -mtriple arm-arm-none-eabi | FileCheck %s --check-prefix=CHECK-ARM-FP-ELIM
|
||||
|
||||
define void @test1() {
|
||||
%tmp = alloca [ 64 x i32 ] , align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!8, !9}
|
||||
!llvm.ident = !{!10}
|
||||
|
||||
!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/large.c] [DW_LANG_C99]
|
||||
!1 = metadata !{metadata !"large.c", metadata !"/tmp"}
|
||||
!2 = metadata !{}
|
||||
!3 = metadata !{metadata !4}
|
||||
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"test1", metadata !"test1", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @test1, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [test1]
|
||||
!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/large.c]
|
||||
!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
|
||||
!7 = metadata !{null}
|
||||
!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
|
||||
!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
|
||||
!10 = metadata !{metadata !"clang version 3.5 "}
|
||||
!11 = metadata !{i32 2, i32 0, metadata !4, null}
|
||||
|
||||
; CHECK-ARM-LABEL: test1:
|
||||
; CHECK-ARM: .cfi_startproc
|
||||
; CHECK-ARM: sub sp, sp, #256
|
||||
; CHECK-ARM: .cfi_endproc
|
||||
|
||||
; CHECK-ARM-FP_ELIM-LABEL: test1:
|
||||
; CHECK-ARM-FP_ELIM: .cfi_startproc
|
||||
; CHECK-ARM-FP_ELIM: sub sp, sp, #256
|
||||
; CHECK-ARM-FP_ELIM: .cfi_endproc
|
||||
|
||||
define void @test2() {
|
||||
%tmp = alloca [ 4168 x i8 ] , align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-ARM-LABEL: test2:
|
||||
; CHECK-ARM: .cfi_startproc
|
||||
; CHECK-ARM: push {r4, r5}
|
||||
; CHECK-ARM: .cfi_def_cfa_offset 8
|
||||
; CHECK-ARM: .cfi_offset r5, -4
|
||||
; CHECK-ARM: .cfi_offset r4, -8
|
||||
; CHECK-ARM: sub sp, sp, #72
|
||||
; CHECK-ARM: sub sp, sp, #4096
|
||||
; CHECK-ARM: .cfi_def_cfa_offset 4176
|
||||
; CHECK-ARM: .cfi_endproc
|
||||
|
||||
; CHECK-ARM-FP_ELIM-LABEL: test2:
|
||||
; CHECK-ARM-FP_ELIM: .cfi_startproc
|
||||
; CHECK-ARM-FP_ELIM: push {r4, r5}
|
||||
; CHECK-ARM-FP_ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-ARM-FP_ELIM: .cfi_offset 54, -4
|
||||
; CHECK-ARM-FP_ELIM: .cfi_offset r4, -8
|
||||
; CHECK-ARM-FP_ELIM: sub sp, sp, #72
|
||||
; CHECK-ARM-FP_ELIM: sub sp, sp, #4096
|
||||
; CHECK-ARM-FP_ELIM: .cfi_def_cfa_offset 4176
|
||||
; CHECK-ARM-FP_ELIM: .cfi_endproc
|
||||
|
||||
define i32 @test3() {
|
||||
%retval = alloca i32, align 4
|
||||
%tmp = alloca i32, align 4
|
||||
%a = alloca [805306369 x i8], align 16
|
||||
store i32 0, i32* %tmp
|
||||
%tmp1 = load i32* %tmp
|
||||
ret i32 %tmp1
|
||||
}
|
||||
|
||||
; CHECK-ARM-LABEL: test3:
|
||||
; CHECK-ARM: .cfi_startproc
|
||||
; CHECK-ARM: push {r4, r5, r11}
|
||||
; CHECK-ARM: .cfi_def_cfa_offset 12
|
||||
; CHECK-ARM: .cfi_offset r11, -4
|
||||
; CHECK-ARM: .cfi_offset r5, -8
|
||||
; CHECK-ARM: .cfi_offset r4, -12
|
||||
; CHECK-ARM: add r11, sp, #8
|
||||
; CHECK-ARM: .cfi_def_cfa r11, 4
|
||||
; CHECK-ARM: sub sp, sp, #20
|
||||
; CHECK-ARM: sub sp, sp, #805306368
|
||||
; CHECK-ARM: bic sp, sp, #15
|
||||
; CHECK-ARM: .cfi_endproc
|
||||
|
||||
; CHECK-ARM-FP-ELIM-LABEL: test3:
|
||||
; CHECK-ARM-FP-ELIM: .cfi_startproc
|
||||
; CHECK-ARM-FP-ELIM: push {r4, r5, r11}
|
||||
; CHECK-ARM-FP-ELIM: .cfi_def_cfa_offset 12
|
||||
; CHECK-ARM-FP-ELIM: .cfi_offset r11, -4
|
||||
; CHECK-ARM-FP-ELIM: .cfi_offset r5, -8
|
||||
; CHECK-ARM-FP-ELIM: .cfi_offset r4, -12
|
||||
; CHECK-ARM-FP-ELIM: add r11, sp, #8
|
||||
; CHECK-ARM-FP-ELIM: .cfi_def_cfa r11, 4
|
||||
; CHECK-ARM-FP-ELIM: sub sp, sp, #20
|
||||
; CHECK-ARM-FP-ELIM: sub sp, sp, #805306368
|
||||
; CHECK-ARM-FP-ELIM: bic sp, sp, #15
|
||||
; CHECK-ARM-FP-ELIM: .cfi_endproc
|
||||
|
97
test/CodeGen/ARM/debug-frame-no-debug.ll
Normal file
97
test/CodeGen/ARM/debug-frame-no-debug.ll
Normal file
@ -0,0 +1,97 @@
|
||||
; ARM EHABI integrated test
|
||||
|
||||
; This test case checks that the ARM DWARF stack frame directives
|
||||
; are not generated if compiling with no debug information.
|
||||
|
||||
; RUN: llc -mtriple arm-unknown-linux-gnueabi \
|
||||
; RUN: -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM
|
||||
|
||||
; RUN: llc -mtriple thumb-unknown-linux-gnueabi \
|
||||
; RUN: -disable-fp-elim -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-THUMB-FP
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Test 1
|
||||
;-------------------------------------------------------------------------------
|
||||
; This is the LLVM assembly generated from following C++ code:
|
||||
;
|
||||
; extern void print(int, int, int, int, int);
|
||||
; extern void print(double, double, double, double, double);
|
||||
;
|
||||
; void test(int a, int b, int c, int d, int e,
|
||||
; double m, double n, double p, double q, double r) {
|
||||
; try {
|
||||
; print(a, b, c, d, e);
|
||||
; } catch (...) {
|
||||
; print(m, n, p, q, r);
|
||||
; }
|
||||
; }
|
||||
|
||||
declare void @_Z5printiiiii(i32, i32, i32, i32, i32)
|
||||
|
||||
declare void @_Z5printddddd(double, double, double, double, double)
|
||||
|
||||
define void @_Z4testiiiiiddddd(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e,
|
||||
double %m, double %n, double %p,
|
||||
double %q, double %r) {
|
||||
entry:
|
||||
invoke void @_Z5printiiiii(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e)
|
||||
to label %try.cont unwind label %lpad
|
||||
|
||||
lpad:
|
||||
%0 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
catch i8* null
|
||||
%1 = extractvalue { i8*, i32 } %0, 0
|
||||
%2 = tail call i8* @__cxa_begin_catch(i8* %1)
|
||||
invoke void @_Z5printddddd(double %m, double %n, double %p,
|
||||
double %q, double %r)
|
||||
to label %invoke.cont2 unwind label %lpad1
|
||||
|
||||
invoke.cont2:
|
||||
tail call void @__cxa_end_catch()
|
||||
br label %try.cont
|
||||
|
||||
try.cont:
|
||||
ret void
|
||||
|
||||
lpad1:
|
||||
%3 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
cleanup
|
||||
invoke void @__cxa_end_catch()
|
||||
to label %eh.resume unwind label %terminate.lpad
|
||||
|
||||
eh.resume:
|
||||
resume { i8*, i32 } %3
|
||||
|
||||
terminate.lpad:
|
||||
%4 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
catch i8* null
|
||||
%5 = extractvalue { i8*, i32 } %4, 0
|
||||
tail call void @__clang_call_terminate(i8* %5)
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @__clang_call_terminate(i8*)
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
declare i8* @__cxa_begin_catch(i8*)
|
||||
|
||||
declare void @__cxa_end_catch()
|
||||
|
||||
declare void @_ZSt9terminatev()
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-FP-ELIM-NOT: .cfi_startproc
|
||||
; CHECK-FP-ELIM: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
; CHECK-FP-ELIM-NOT: .cfi_def_cfa_offset 36
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-THUMB-FP-NOT: .cfi_startproc
|
||||
; CHECK-THUMB-FP: push {r4, r5, r6, r7, lr}
|
||||
; CHECK-THUMB-FP-NOT: .cfi_def_cfa_offset 20
|
||||
|
141
test/CodeGen/ARM/debug-frame-vararg.ll
Normal file
141
test/CodeGen/ARM/debug-frame-vararg.ll
Normal file
@ -0,0 +1,141 @@
|
||||
; RUN: llc -mtriple arm-unknown-linux-gnueabi -filetype asm -o - %s | FileCheck %s --check-prefix=CHECK-FP
|
||||
; RUN: llc -mtriple arm-unknown-linux-gnueabi -filetype asm -o - %s -disable-fp-elim | FileCheck %s --check-prefix=CHECK-FP-ELIM
|
||||
; RUN: llc -mtriple thumb-unknown-linux-gnueabi -filetype asm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-FP
|
||||
; RUN: llc -mtriple thumb-unknown-linux-gnueabi -filetype asm -o - %s -disable-fp-elim | FileCheck %s --check-prefix=CHECK-THUMB-FP-ELIM
|
||||
|
||||
; Tests that the initial space allocated to the varargs on the stack is
|
||||
; taken into account in the the .cfi_ directives.
|
||||
|
||||
; Generated from the C program:
|
||||
; #include <stdarg.h>
|
||||
;
|
||||
; extern int foo(int);
|
||||
;
|
||||
; int sum(int count, ...) {
|
||||
; va_list vl;
|
||||
; va_start(vl, count);
|
||||
; int sum = 0;
|
||||
; for (int i = 0; i < count; i++) {
|
||||
; sum += foo(va_arg(vl, int));
|
||||
; }
|
||||
; va_end(vl);
|
||||
; }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!9, !10}
|
||||
!llvm.ident = !{!11}
|
||||
|
||||
!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/var.c] [DW_LANG_C99]
|
||||
!1 = metadata !{metadata !"var.c", metadata !"/tmp"}
|
||||
!2 = metadata !{}
|
||||
!3 = metadata !{metadata !4}
|
||||
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"sum", metadata !"sum", metadata !"", i32 5, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32, ...)* @sum, null, null, metadata !2, i32 5} ; [ DW_TAG_subprogram ] [line 5] [def] [sum]
|
||||
!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/var.c]
|
||||
!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
|
||||
!7 = metadata !{metadata !8, metadata !8}
|
||||
!8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
|
||||
!9 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
|
||||
!10 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
|
||||
!11 = metadata !{metadata !"clang version 3.5 "}
|
||||
!12 = metadata !{i32 786689, metadata !4, metadata !"count", metadata !5, i32 16777221, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [count] [line 5]
|
||||
!13 = metadata !{i32 5, i32 0, metadata !4, null}
|
||||
!14 = metadata !{i32 786688, metadata !4, metadata !"vl", metadata !5, i32 6, metadata !15, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [vl] [line 6]
|
||||
!15 = metadata !{i32 786454, metadata !16, null, metadata !"va_list", i32 30, i64 0, i64 0, i64 0, i32 0, metadata !17} ; [ DW_TAG_typedef ] [va_list] [line 30, size 0, align 0, offset 0] [from __builtin_va_list]
|
||||
!16 = metadata !{metadata !"/linux-x86_64-high/gcc_4.7.2/dbg/llvm/bin/../lib/clang/3.5/include/stdarg.h", metadata !"/tmp"}
|
||||
!17 = metadata !{i32 786454, metadata !1, null, metadata !"__builtin_va_list", i32 6, i64 0, i64 0, i64 0, i32 0, metadata !18} ; [ DW_TAG_typedef ] [__builtin_va_list] [line 6, size 0, align 0, offset 0] [from __va_list]
|
||||
!18 = metadata !{i32 786451, metadata !1, null, metadata !"__va_list", i32 6, i64 32, i64 32, i32 0, i32 0, null, metadata !19, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [__va_list] [line 6, size 32, align 32, offset 0] [def] [from ]
|
||||
!19 = metadata !{metadata !20}
|
||||
!20 = metadata !{i32 786445, metadata !1, metadata !18, metadata !"__ap", i32 6, i64 32, i64 32, i64 0, i32 0, metadata !21} ; [ DW_TAG_member ] [__ap] [line 6, size 32, align 32, offset 0] [from ]
|
||||
!21 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 32, i64 32, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] [line 0, size 32, align 32, offset 0] [from ]
|
||||
!22 = metadata !{i32 6, i32 0, metadata !4, null}
|
||||
!23 = metadata !{i32 7, i32 0, metadata !4, null}
|
||||
!24 = metadata !{i32 786688, metadata !4, metadata !"sum", metadata !5, i32 8, metadata !8, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [sum] [line 8]
|
||||
!25 = metadata !{i32 8, i32 0, metadata !4, null} ; [ DW_TAG_imported_declaration ]
|
||||
!26 = metadata !{i32 786688, metadata !27, metadata !"i", metadata !5, i32 9, metadata !8, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [i] [line 9]
|
||||
!27 = metadata !{i32 786443, metadata !1, metadata !4, i32 9, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/tmp/var.c]
|
||||
!28 = metadata !{i32 9, i32 0, metadata !27, null}
|
||||
!29 = metadata !{i32 10, i32 0, metadata !30, null}
|
||||
!30 = metadata !{i32 786443, metadata !1, metadata !27, i32 9, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/var.c]
|
||||
!31 = metadata !{i32 11, i32 0, metadata !30, null}
|
||||
!32 = metadata !{i32 12, i32 0, metadata !4, null}
|
||||
!33 = metadata !{i32 13, i32 0, metadata !4, null}
|
||||
|
||||
; CHECK-FP-LABEL: sum
|
||||
; CHECK-FP: .cfi_startproc
|
||||
; CHECK-FP: sub sp, sp, #16
|
||||
; CHECK-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-FP: push {r4, lr}
|
||||
; CHECK-FP: .cfi_def_cfa_offset 24
|
||||
; CHECK-FP: .cfi_offset lr, -20
|
||||
; CHECK-FP: .cfi_offset r4, -24
|
||||
; CHECK-FP: sub sp, sp, #8
|
||||
; CHECK-FP: .cfi_def_cfa_offset 32
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: sum
|
||||
; CHECK-FP-ELIM: .cfi_startproc
|
||||
; CHECK-FP-ELIM: sub sp, sp, #16
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-FP-ELIM: push {r4, r11, lr}
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 28
|
||||
; CHECK-FP-ELIM: .cfi_offset lr, -20
|
||||
; CHECK-FP-ELIM: .cfi_offset r11, -24
|
||||
; CHECK-FP-ELIM: .cfi_offset r4, -28
|
||||
; CHECK-FP-ELIM: add r11, sp, #4
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa r11, 24
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: sum
|
||||
; CHECK-THUMB-FP: .cfi_startproc
|
||||
; CHECK-THUMB-FP: sub sp, #16
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-FP: push {r4, r5, r7, lr}
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 32
|
||||
; CHECK-THUMB-FP: .cfi_offset lr, -20
|
||||
; CHECK-THUMB-FP: .cfi_offset r7, -24
|
||||
; CHECK-THUMB-FP: .cfi_offset r5, -28
|
||||
; CHECK-THUMB-FP: .cfi_offset r4, -32
|
||||
; CHECK-THUMB-FP: sub sp, #8
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 40
|
||||
|
||||
; CHECK-THUMB-FP-ELIM-LABEL: sum
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-FP-ELIM: sub sp, #16
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-FP-ELIM: push {r4, r5, r7, lr}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 32
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset lr, -20
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r7, -24
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r5, -28
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r4, -32
|
||||
; CHECK-THUMB-FP-ELIM: add r7, sp, #8
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa r7, 24
|
||||
|
||||
define i32 @sum(i32 %count, ...) {
|
||||
entry:
|
||||
%vl = alloca i8*, align 4
|
||||
%vl1 = bitcast i8** %vl to i8*
|
||||
call void @llvm.va_start(i8* %vl1)
|
||||
%cmp4 = icmp sgt i32 %count, 0
|
||||
br i1 %cmp4, label %for.body, label %for.end
|
||||
|
||||
for.body: ; preds = %entry, %for.body
|
||||
%i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
|
||||
%ap.cur = load i8** %vl, align 4
|
||||
%ap.next = getelementptr i8* %ap.cur, i32 4
|
||||
store i8* %ap.next, i8** %vl, align 4
|
||||
%0 = bitcast i8* %ap.cur to i32*
|
||||
%1 = load i32* %0, align 4
|
||||
%call = call i32 @foo(i32 %1) #1
|
||||
%inc = add nsw i32 %i.05, 1
|
||||
%exitcond = icmp eq i32 %inc, %count
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
call void @llvm.va_end(i8* %vl1)
|
||||
ret i32 undef
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(i8*) nounwind
|
||||
|
||||
declare i32 @foo(i32)
|
||||
|
||||
declare void @llvm.va_end(i8*) nounwind
|
551
test/CodeGen/ARM/debug-frame.ll
Normal file
551
test/CodeGen/ARM/debug-frame.ll
Normal file
@ -0,0 +1,551 @@
|
||||
; ARM EHABI integrated test
|
||||
|
||||
; This test case checks whether the ARM DWARF stack frame directives
|
||||
; are properly generated or not.
|
||||
|
||||
; We have to check several cases:
|
||||
; (1) arm with -disable-fp-elim
|
||||
; (2) arm without -disable-fp-elim
|
||||
; (3) armv7 with -disable-fp-elim
|
||||
; (4) armv7 without -disable-fp-elim
|
||||
; (5) thumb with -disable-fp-elim
|
||||
; (6) thumb without -disable-fp-elim
|
||||
; (7) thumbv7 with -disable-fp-elim
|
||||
; (8) thumbv7 without -disable-fp-elim
|
||||
|
||||
; RUN: llc -mtriple arm-unknown-linux-gnueabi \
|
||||
; RUN: -disable-fp-elim -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-FP
|
||||
|
||||
; RUN: llc -mtriple arm-unknown-linux-gnueabi \
|
||||
; RUN: -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM
|
||||
|
||||
; RUN: llc -mtriple armv7-unknown-linux-gnueabi \
|
||||
; RUN: -disable-fp-elim -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-V7-FP
|
||||
|
||||
; RUN: llc -mtriple armv7-unknown-linux-gnueabi \
|
||||
; RUN: -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-V7-FP-ELIM
|
||||
|
||||
; RUN: llc -mtriple thumb-unknown-linux-gnueabi \
|
||||
; RUN: -disable-fp-elim -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-THUMB-FP
|
||||
|
||||
; RUN: llc -mtriple thumb-unknown-linux-gnueabi \
|
||||
; RUN: -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-THUMB-FP-ELIM
|
||||
|
||||
; RUN: llc -mtriple thumbv7-unknown-linux-gnueabi \
|
||||
; RUN: -disable-fp-elim -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-THUMB-V7-FP
|
||||
|
||||
; RUN: llc -mtriple thumbv7-unknown-linux-gnueabi \
|
||||
; RUN: -filetype=asm -o - %s \
|
||||
; RUN: | FileCheck %s --check-prefix=CHECK-THUMB-V7-FP-ELIM
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Test 1
|
||||
;-------------------------------------------------------------------------------
|
||||
; This is the LLVM assembly generated from following C++ code:
|
||||
;
|
||||
; extern void print(int, int, int, int, int);
|
||||
; extern void print(double, double, double, double, double);
|
||||
;
|
||||
; void test(int a, int b, int c, int d, int e,
|
||||
; double m, double n, double p, double q, double r) {
|
||||
; try {
|
||||
; print(a, b, c, d, e);
|
||||
; } catch (...) {
|
||||
; print(m, n, p, q, r);
|
||||
; }
|
||||
; }
|
||||
|
||||
declare void @_Z5printiiiii(i32, i32, i32, i32, i32)
|
||||
|
||||
declare void @_Z5printddddd(double, double, double, double, double)
|
||||
|
||||
define void @_Z4testiiiiiddddd(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e,
|
||||
double %m, double %n, double %p,
|
||||
double %q, double %r) {
|
||||
entry:
|
||||
invoke void @_Z5printiiiii(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e)
|
||||
to label %try.cont unwind label %lpad
|
||||
|
||||
lpad:
|
||||
%0 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
catch i8* null
|
||||
%1 = extractvalue { i8*, i32 } %0, 0
|
||||
%2 = tail call i8* @__cxa_begin_catch(i8* %1)
|
||||
invoke void @_Z5printddddd(double %m, double %n, double %p,
|
||||
double %q, double %r)
|
||||
to label %invoke.cont2 unwind label %lpad1
|
||||
|
||||
invoke.cont2:
|
||||
tail call void @__cxa_end_catch()
|
||||
br label %try.cont
|
||||
|
||||
try.cont:
|
||||
ret void
|
||||
|
||||
lpad1:
|
||||
%3 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
cleanup
|
||||
invoke void @__cxa_end_catch()
|
||||
to label %eh.resume unwind label %terminate.lpad
|
||||
|
||||
eh.resume:
|
||||
resume { i8*, i32 } %3
|
||||
|
||||
terminate.lpad:
|
||||
%4 = landingpad { i8*, i32 }
|
||||
personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
|
||||
catch i8* null
|
||||
%5 = extractvalue { i8*, i32 } %4, 0
|
||||
tail call void @__clang_call_terminate(i8* %5)
|
||||
unreachable
|
||||
}
|
||||
|
||||
declare void @__clang_call_terminate(i8*)
|
||||
|
||||
declare i32 @__gxx_personality_v0(...)
|
||||
|
||||
declare i8* @__cxa_begin_catch(i8*)
|
||||
|
||||
declare void @__cxa_end_catch()
|
||||
|
||||
declare void @_ZSt9terminatev()
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!10, !11}
|
||||
!llvm.ident = !{!12}
|
||||
|
||||
!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/tmp/exp.cpp] [DW_LANG_C_plus_plus]
|
||||
!1 = metadata !{metadata !"exp.cpp", metadata !"/tmp"}
|
||||
!2 = metadata !{}
|
||||
!3 = metadata !{metadata !4}
|
||||
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"test", metadata !"test", metadata !"_Z4testiiiiiddddd", i32 4, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i32, i32, i32, i32, i32, double, double, double, double, double)* @_Z4testiiiiiddddd, null, null, metadata !2, i32 5} ; [ DW_TAG_subprogram ] [line 4] [def] [scope 5] [test]
|
||||
!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/exp.cpp]
|
||||
!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
|
||||
!7 = metadata !{null, metadata !8, metadata !8, metadata !8, metadata !8, metadata !8, metadata !9, metadata !9, metadata !9, metadata !9, metadata !9}
|
||||
!8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
|
||||
!9 = metadata !{i32 786468, null, null, metadata !"double", i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
|
||||
!10 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
|
||||
!11 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
|
||||
!12 = metadata !{metadata !"clang version 3.5 "}
|
||||
!13 = metadata !{i32 786689, metadata !4, metadata !"a", metadata !5, i32 16777220, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [a] [line 4]
|
||||
!14 = metadata !{i32 4, i32 0, metadata !4, null}
|
||||
!15 = metadata !{i32 786689, metadata !4, metadata !"b", metadata !5, i32 33554436, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [b] [line 4]
|
||||
!16 = metadata !{i32 786689, metadata !4, metadata !"c", metadata !5, i32 50331652, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [c] [line 4]
|
||||
!17 = metadata !{i32 786689, metadata !4, metadata !"d", metadata !5, i32 67108868, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [d] [line 4]
|
||||
!18 = metadata !{i32 786689, metadata !4, metadata !"e", metadata !5, i32 83886084, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [e] [line 4]
|
||||
!19 = metadata !{i32 786689, metadata !4, metadata !"m", metadata !5, i32 100663301, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [m] [line 5]
|
||||
!20 = metadata !{i32 5, i32 0, metadata !4, null}
|
||||
!21 = metadata !{i32 786689, metadata !4, metadata !"n", metadata !5, i32 117440517, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [n] [line 5]
|
||||
!22 = metadata !{i32 786689, metadata !4, metadata !"p", metadata !5, i32 134217733, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [p] [line 5]
|
||||
!23 = metadata !{i32 786689, metadata !4, metadata !"q", metadata !5, i32 150994949, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [q] [line 5]
|
||||
!24 = metadata !{i32 786689, metadata !4, metadata !"r", metadata !5, i32 167772165, metadata !9, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [r] [line 5]
|
||||
!25 = metadata !{i32 7, i32 0, metadata !26, null}
|
||||
!26 = metadata !{i32 786443, metadata !1, metadata !4, i32 6, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/tmp/exp.cpp]
|
||||
!27 = metadata !{i32 8, i32 0, metadata !26, null} ; [ DW_TAG_imported_declaration ]
|
||||
!28 = metadata !{i32 11, i32 0, metadata !26, null}
|
||||
!29 = metadata !{i32 9, i32 0, metadata !30, null}
|
||||
!30 = metadata !{i32 786443, metadata !1, metadata !4, i32 8, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/exp.cpp]
|
||||
!31 = metadata !{i32 10, i32 0, metadata !30, null}
|
||||
!32 = metadata !{i32 10, i32 0, metadata !4, null}
|
||||
!33 = metadata !{i32 11, i32 0, metadata !4, null}
|
||||
!34 = metadata !{i32 11, i32 0, metadata !30, null}
|
||||
|
||||
; CHECK-FP-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-FP: .cfi_startproc
|
||||
; CHECK-FP: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
; CHECK-FP: .cfi_def_cfa_offset 36
|
||||
; CHECK-FP: .cfi_offset lr, -4
|
||||
; CHECK-FP: .cfi_offset r11, -8
|
||||
; CHECK-FP: .cfi_offset r10, -12
|
||||
; CHECK-FP: .cfi_offset r9, -16
|
||||
; CHECK-FP: .cfi_offset r8, -20
|
||||
; CHECK-FP: .cfi_offset r7, -24
|
||||
; CHECK-FP: .cfi_offset r6, -28
|
||||
; CHECK-FP: .cfi_offset r5, -32
|
||||
; CHECK-FP: .cfi_offset r4, -36
|
||||
; CHECK-FP: add r11, sp, #28
|
||||
; CHECK-FP: .cfi_def_cfa r11, 8
|
||||
; CHECK-FP: sub sp, sp, #28
|
||||
; CHECK-FP: .cfi_endproc
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-FP-ELIM: .cfi_startproc
|
||||
; CHECK-FP-ELIM: push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 36
|
||||
; CHECK-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-FP-ELIM: .cfi_offset r10, -12
|
||||
; CHECK-FP-ELIM: .cfi_offset r9, -16
|
||||
; CHECK-FP-ELIM: .cfi_offset r8, -20
|
||||
; CHECK-FP-ELIM: .cfi_offset r7, -24
|
||||
; CHECK-FP-ELIM: .cfi_offset r6, -28
|
||||
; CHECK-FP-ELIM: .cfi_offset r5, -32
|
||||
; CHECK-FP-ELIM: .cfi_offset r4, -36
|
||||
; CHECK-FP-ELIM: sub sp, sp, #28
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 64
|
||||
; CHECK-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-V7-FP: .cfi_startproc
|
||||
; CHECK-V7-FP: push {r4, r11, lr}
|
||||
; CHECK-V7-FP: .cfi_def_cfa_offset 12
|
||||
; CHECK-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP: .cfi_offset r11, -8
|
||||
; CHECK-V7-FP: .cfi_offset r4, -12
|
||||
; CHECK-V7-FP: add r11, sp, #4
|
||||
; CHECK-V7-FP: .cfi_def_cfa r11, 8
|
||||
; CHECK-V7-FP: vpush {d8, d9, d10, d11, d12}
|
||||
; CHECK-V7-FP: .cfi_offset d12, -24
|
||||
; CHECK-V7-FP: .cfi_offset d11, -32
|
||||
; CHECK-V7-FP: .cfi_offset d10, -40
|
||||
; CHECK-V7-FP: .cfi_offset d9, -48
|
||||
; CHECK-V7-FP: .cfi_offset d8, -56
|
||||
; CHECK-V7-FP: sub sp, sp, #28
|
||||
; CHECK-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-V7-FP-ELIM: push {r4, lr}
|
||||
; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset r4, -8
|
||||
; CHECK-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12}
|
||||
; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 48
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset d12, -16
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset d11, -24
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset d10, -32
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset d9, -40
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset d8, -48
|
||||
; CHECK-V7-FP-ELIM: sub sp, sp, #24
|
||||
; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 72
|
||||
; CHECK-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-THUMB-FP: .cfi_startproc
|
||||
; CHECK-THUMB-FP: push {r4, r5, r6, r7, lr}
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 20
|
||||
; CHECK-THUMB-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP: .cfi_offset r6, -12
|
||||
; CHECK-THUMB-FP: .cfi_offset r5, -16
|
||||
; CHECK-THUMB-FP: .cfi_offset r4, -20
|
||||
; CHECK-THUMB-FP: add r7, sp, #12
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa r7, 8
|
||||
; CHECK-THUMB-FP: sub sp, #60
|
||||
; CHECK-THUMB-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-ELIM-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-FP-ELIM: push {r4, r5, r6, r7, lr}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 20
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r6, -12
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r5, -16
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r4, -20
|
||||
; CHECK-THUMB-FP-ELIM: sub sp, #60
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 80
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-THUMB-V7-FP: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP: push.w {r4, r7, r11, lr}
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r11, -8
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r7, -12
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r4, -16
|
||||
; CHECK-THUMB-V7-FP: add r7, sp, #4
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa r7, 12
|
||||
; CHECK-THUMB-V7-FP: vpush {d8, d9, d10, d11, d12}
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset d12, -24
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset d11, -32
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset d10, -40
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset d9, -48
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset d8, -56
|
||||
; CHECK-THUMB-V7-FP: sub sp, #24
|
||||
; CHECK-THUMB-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-ELIM-LABEL: _Z4testiiiiiddddd:
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP-ELIM: push {r4, lr}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r4, -8
|
||||
; CHECK-THUMB-V7-FP-ELIM: vpush {d8, d9, d10, d11, d12}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 48
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d12, -16
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d11, -24
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d10, -32
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d9, -40
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset d8, -48
|
||||
; CHECK-THUMB-V7-FP-ELIM: sub sp, #24
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 72
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Test 2
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
declare void @throw_exception_2()
|
||||
|
||||
define void @test2() {
|
||||
entry:
|
||||
tail call void @throw_exception_2()
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-FP-LABEL: test2:
|
||||
; CHECK-FP: .cfi_startproc
|
||||
; CHECK-FP: push {r11, lr}
|
||||
; CHECK-FP: .cfi_def_cfa_offset 8
|
||||
; CHECK-FP: .cfi_offset lr, -4
|
||||
; CHECK-FP: .cfi_offset r11, -8
|
||||
; CHECK-FP: mov r11, sp
|
||||
; CHECK-FP: .cfi_def_cfa_register r11
|
||||
; CHECK-FP: pop {r11, lr}
|
||||
; CHECK-FP: mov pc, lr
|
||||
; CHECK-FP: .cfi_endproc
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: test2:
|
||||
; CHECK-FP-ELIM: .cfi_startproc
|
||||
; CHECK-FP-ELIM: push {r11, lr}
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-FP-ELIM: pop {r11, lr}
|
||||
; CHECK-FP-ELIM: mov pc, lr
|
||||
; CHECK-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-LABEL: test2:
|
||||
; CHECK-V7-FP: .cfi_startproc
|
||||
; CHECK-V7-FP: push {r11, lr}
|
||||
; CHECK-V7-FP: .cfi_def_cfa_offset 8
|
||||
; CHECK-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP: .cfi_offset r11, -8
|
||||
; CHECK-V7-FP: mov r11, sp
|
||||
; CHECK-V7-FP: .cfi_def_cfa_register r11
|
||||
; CHECK-V7-FP: pop {r11, pc}
|
||||
; CHECK-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-ELIM-LABEL: test2:
|
||||
; CHECK-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-V7-FP-ELIM: push {r11, lr}
|
||||
; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-V7-FP-ELIM: pop {r11, pc}
|
||||
; CHECK-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: test2:
|
||||
; CHECK-THUMB-FP: .cfi_startproc
|
||||
; CHECK-THUMB-FP: push {r7, lr}
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 8
|
||||
; CHECK-THUMB-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP: add r7, sp, #0
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_register r7
|
||||
; CHECK-THUMB-FP: pop {r7, pc}
|
||||
; CHECK-THUMB-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-ELIM-LABEL: test2:
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-FP-ELIM: push {r7, lr}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP-ELIM: pop {r7, pc}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-LABEL: test2:
|
||||
; CHECK-THUMB-V7-FP: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP: push {r7, lr}
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa_offset 8
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-V7-FP: mov r7, sp
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa_register r7
|
||||
; CHECK-THUMB-V7-FP: pop {r7, pc}
|
||||
; CHECK-THUMB-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-ELIM-LABEL: test2:
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP-ELIM: push.w {r11, lr}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 8
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-THUMB-V7-FP-ELIM: pop.w {r11, pc}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Test 3
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
declare void @throw_exception_3(i32)
|
||||
|
||||
define i32 @test3(i32 %a, i32 %b, i32 %c, i32 %d,
|
||||
i32 %e, i32 %f, i32 %g, i32 %h) {
|
||||
entry:
|
||||
%add = add nsw i32 %b, %a
|
||||
%add1 = add nsw i32 %add, %c
|
||||
%add2 = add nsw i32 %add1, %d
|
||||
tail call void @throw_exception_3(i32 %add2)
|
||||
%add3 = add nsw i32 %f, %e
|
||||
%add4 = add nsw i32 %add3, %g
|
||||
%add5 = add nsw i32 %add4, %h
|
||||
tail call void @throw_exception_3(i32 %add5)
|
||||
%add6 = add nsw i32 %add5, %add2
|
||||
ret i32 %add6
|
||||
}
|
||||
|
||||
; CHECK-FP-LABEL: test3:
|
||||
; CHECK-FP: .cfi_startproc
|
||||
; CHECK-FP: push {r4, r5, r11, lr}
|
||||
; CHECK-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-FP: .cfi_offset lr, -4
|
||||
; CHECK-FP: .cfi_offset r11, -8
|
||||
; CHECK-FP: .cfi_offset r5, -12
|
||||
; CHECK-FP: .cfi_offset r4, -16
|
||||
; CHECK-FP: add r11, sp, #8
|
||||
; CHECK-FP: .cfi_def_cfa r11, 8
|
||||
; CHECK-FP: pop {r4, r5, r11, lr}
|
||||
; CHECK-FP: mov pc, lr
|
||||
; CHECK-FP: .cfi_endproc
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: test3:
|
||||
; CHECK-FP-ELIM: .cfi_startproc
|
||||
; CHECK-FP-ELIM: push {r4, r5, r11, lr}
|
||||
; CHECK-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-FP-ELIM: .cfi_offset r5, -12
|
||||
; CHECK-FP-ELIM: .cfi_offset r4, -16
|
||||
; CHECK-FP-ELIM: pop {r4, r5, r11, lr}
|
||||
; CHECK-FP-ELIM: mov pc, lr
|
||||
; CHECK-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-LABEL: test3:
|
||||
; CHECK-V7-FP: .cfi_startproc
|
||||
; CHECK-V7-FP: push {r4, r5, r11, lr}
|
||||
; CHECK-V7-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP: .cfi_offset r11, -8
|
||||
; CHECK-V7-FP: .cfi_offset r5, -12
|
||||
; CHECK-V7-FP: .cfi_offset r4, -16
|
||||
; CHECK-V7-FP: add r11, sp, #8
|
||||
; CHECK-V7-FP: .cfi_def_cfa r11, 8
|
||||
; CHECK-V7-FP: pop {r4, r5, r11, pc}
|
||||
; CHECK-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-V7-FP-ELIM-LABEL: test3:
|
||||
; CHECK-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-V7-FP-ELIM: push {r4, r5, r11, lr}
|
||||
; CHECK-V7-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset r5, -12
|
||||
; CHECK-V7-FP-ELIM: .cfi_offset r4, -16
|
||||
; CHECK-V7-FP-ELIM: pop {r4, r5, r11, pc}
|
||||
; CHECK-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: test3:
|
||||
; CHECK-THUMB-FP: .cfi_startproc
|
||||
; CHECK-THUMB-FP: push {r4, r5, r7, lr}
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP: .cfi_offset r5, -12
|
||||
; CHECK-THUMB-FP: .cfi_offset r4, -16
|
||||
; CHECK-THUMB-FP: add r7, sp, #8
|
||||
; CHECK-THUMB-FP: .cfi_def_cfa r7, 8
|
||||
; CHECK-THUMB-FP: pop {r4, r5, r7, pc}
|
||||
; CHECK-THUMB-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-FP-ELIM-LABEL: test3:
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-FP-ELIM: push {r4, r5, r7, lr}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r5, -12
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_offset r4, -16
|
||||
; CHECK-THUMB-FP-ELIM: pop {r4, r5, r7, pc}
|
||||
; CHECK-THUMB-FP-ELIM: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-LABEL: test3:
|
||||
; CHECK-THUMB-V7-FP: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP: push {r4, r5, r7, lr}
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r7, -8
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r5, -12
|
||||
; CHECK-THUMB-V7-FP: .cfi_offset r4, -16
|
||||
; CHECK-THUMB-V7-FP: add r7, sp, #8
|
||||
; CHECK-THUMB-V7-FP: .cfi_def_cfa r7, 8
|
||||
; CHECK-THUMB-V7-FP: pop {r4, r5, r7, pc}
|
||||
; CHECK-THUMB-V7-FP: .cfi_endproc
|
||||
|
||||
; CHECK-THUMB-V7-FP-ELIM-LABEL: test3:
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_startproc
|
||||
; CHECK-THUMB-V7-FP-ELIM: push.w {r4, r5, r11, lr}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_def_cfa_offset 16
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset lr, -4
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r11, -8
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r5, -12
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_offset r4, -16
|
||||
; CHECK-THUMB-V7-FP-ELIM: pop.w {r4, r5, r11, pc}
|
||||
; CHECK-THUMB-V7-FP-ELIM: .cfi_endproc
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Test 4
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
define void @test4() nounwind {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-FP-LABEL: test4:
|
||||
; CHECK-FP: mov pc, lr
|
||||
; CHECK-FP-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-FP-ELIM-LABEL: test4:
|
||||
; CHECK-FP-ELIM: mov pc, lr
|
||||
; CHECK-FP-ELIM-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-V7-FP-LABEL: test4:
|
||||
; CHECK-V7-FP: bx lr
|
||||
; CHECK-V7-FP-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-V7-FP-ELIM-LABEL: test4:
|
||||
; CHECK-V7-FP-ELIM: bx lr
|
||||
; CHECK-V7-FP-ELIM-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-THUMB-FP-LABEL: test4:
|
||||
; CHECK-THUMB-FP: bx lr
|
||||
; CHECK-THUMB-FP-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-THUMB-FP-ELIM-LABEL: test4:
|
||||
; CHECK-THUMB-FP-ELIM: bx lr
|
||||
; CHECK-THUMB-FP-ELIM-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-THUMB-V7-FP-LABEL: test4:
|
||||
; CHECK-THUMB-V7-FP: bx lr
|
||||
; CHECK-THUMB-V7-FP-NOT: .cfi_def_cfa_offset
|
||||
|
||||
; CHECK-THUMB-V7-FP-ELIM-LABEL: test4:
|
||||
; CHECK-THUMB-V7-FP-ELIM: bx lr
|
||||
; CHECK-THUMB-V7-FP-ELIM-NOT: .cfi_def_cfa_offset
|
||||
|
@ -3,9 +3,12 @@
|
||||
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
|
||||
target triple = "thumbv7-apple-macosx10.6.7"
|
||||
|
||||
;CHECK: Ldebug_loc0:
|
||||
;CHECK-NEXT: .long Ltmp0
|
||||
;CHECK-NEXT: .long Ltmp1
|
||||
;CHECK-LABEL: Lfunc_begin0:
|
||||
;CHECK: Ltmp[[K:[0-9]+]]:
|
||||
;CHECK: Ltmp[[L:[0-9]+]]:
|
||||
;CHECK-LABEL: Ldebug_loc0:
|
||||
;CHECK-NEXT: .long Ltmp[[K]]
|
||||
;CHECK-NEXT: .long Ltmp[[L]]
|
||||
;CHECK-NEXT: Lset[[N:[0-9]+]] = Ltmp{{[0-9]+}}-Ltmp[[M:[0-9]+]] @ Loc expr size
|
||||
;CHECK-NEXT: .short Lset[[N]]
|
||||
;CHECK-NEXT: Ltmp[[M]]:
|
||||
|
@ -9,7 +9,7 @@
|
||||
; statement shouldn't be implicitly defined.
|
||||
|
||||
; CHECK-LABEL: func:
|
||||
; CHECK: Ltmp1: @ Block address taken
|
||||
; CHECK: Ltmp3: @ Block address taken
|
||||
; CHECK-NOT: @ implicit-def: R0
|
||||
; CHECK: @ 4-byte Reload
|
||||
|
||||
|
@ -69,7 +69,7 @@ L1: ; preds = %L2, %bb2
|
||||
store i8* blockaddress(@foo, %L5), i8** @nextaddr, align 4
|
||||
ret i32 %res.3
|
||||
}
|
||||
; ARM: .long Ltmp0-(LPC{{.*}}+8)
|
||||
; THUMB: .long Ltmp0-(LPC{{.*}}+4)
|
||||
; ARM: .long Ltmp1-(LPC{{.*}}+8)
|
||||
; THUMB: .long Ltmp1-(LPC{{.*}}+4)
|
||||
; THUMB: .long _nextaddr-([[NEXTADDR_PCBASE]]+4)
|
||||
; THUMB2: .long Ltmp0
|
||||
; THUMB2: .long Ltmp1
|
||||
|
@ -23,8 +23,8 @@ define arm_aapcscc void @irq_fn() alignstack(8) "interrupt"="IRQ" {
|
||||
|
||||
; CHECK-A-THUMB-LABEL: irq_fn:
|
||||
; CHECK-A-THUMB: push.w {r0, r1, r2, r3, r4, r7, r12, lr}
|
||||
; CHECK-A-THUMB: mov r4, sp
|
||||
; CHECK-A-THUMB: add r7, sp, #20
|
||||
; CHECK-A-THUMB: mov r4, sp
|
||||
; CHECK-A-THUMB: bic r4, r4, #7
|
||||
; CHECK-A-THUMB: bl bar
|
||||
; CHECK-A-THUMB: sub.w r4, r7, #20
|
||||
|
Loading…
Reference in New Issue
Block a user