mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 01:11:44 +00:00
XCore target: Enable frames larger than 65535 to be lowered
llvm-svn: 196084
This commit is contained in:
parent
e71e08d007
commit
9c8a9af745
@ -29,6 +29,9 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static const unsigned FramePtr = XCore::R10;
|
||||
static const int MaxImmU16 = (1<<16) - 1;
|
||||
|
||||
// helper functions. FIXME: Eliminate.
|
||||
static inline bool isImmU6(unsigned val) {
|
||||
return val < (1 << 6);
|
||||
@ -38,34 +41,93 @@ static inline bool isImmU16(unsigned val) {
|
||||
return val < (1 << 16);
|
||||
}
|
||||
|
||||
static void loadFromStack(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned DstReg, int Offset, DebugLoc dl,
|
||||
const TargetInstrInfo &TII) {
|
||||
assert(Offset%4 == 0 && "Misaligned stack offset");
|
||||
Offset/=4;
|
||||
bool isU6 = isImmU6(Offset);
|
||||
if (!isU6 && !isImmU16(Offset))
|
||||
report_fatal_error("loadFromStack offset too big " + Twine(Offset));
|
||||
int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
|
||||
BuildMI(MBB, I, dl, TII.get(Opcode), DstReg)
|
||||
.addImm(Offset);
|
||||
static void EmitDefCfaRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI, DebugLoc dl,
|
||||
const TargetInstrInfo &TII,
|
||||
MachineModuleInfo *MMI, unsigned DRegNum) {
|
||||
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label);
|
||||
MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(Label, DRegNum));
|
||||
}
|
||||
|
||||
static void EmitDefCfaOffset(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI, DebugLoc dl,
|
||||
const TargetInstrInfo &TII,
|
||||
MachineModuleInfo *MMI, int Offset) {
|
||||
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label);
|
||||
MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(Label, -Offset));
|
||||
}
|
||||
|
||||
static void storeToStack(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned SrcReg, int Offset, DebugLoc dl,
|
||||
const TargetInstrInfo &TII) {
|
||||
assert(Offset%4 == 0 && "Misaligned stack offset");
|
||||
Offset/=4;
|
||||
bool isU6 = isImmU6(Offset);
|
||||
if (!isU6 && !isImmU16(Offset))
|
||||
report_fatal_error("storeToStack offset too big " + Twine(Offset));
|
||||
int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
|
||||
BuildMI(MBB, I, dl, TII.get(Opcode))
|
||||
.addReg(SrcReg)
|
||||
.addImm(Offset);
|
||||
static void EmitCfiOffset(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI, DebugLoc dl,
|
||||
const TargetInstrInfo &TII, MachineModuleInfo *MMI,
|
||||
unsigned DRegNum, int Offset, MCSymbol *Label) {
|
||||
if (!Label) {
|
||||
Label = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(Label);
|
||||
}
|
||||
MMI->addFrameInst(MCCFIInstruction::createOffset(Label, DRegNum, Offset));
|
||||
}
|
||||
|
||||
/// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
|
||||
/// frame. During these steps, it may be necessary to spill registers.
|
||||
/// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
|
||||
/// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
|
||||
/// \param OffsetFromTop the spill offset from the top of the frame.
|
||||
/// \param [in] [out] Adjusted the current SP offset from the top of the frame.
|
||||
static void IfNeededExtSP(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI, DebugLoc dl,
|
||||
const TargetInstrInfo &TII, MachineModuleInfo *MMI,
|
||||
int OffsetFromTop, int &Adjusted, int FrameSize,
|
||||
bool emitFrameMoves) {
|
||||
while (OffsetFromTop > Adjusted) {
|
||||
assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
|
||||
int remaining = FrameSize - Adjusted;
|
||||
int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
|
||||
int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
|
||||
Adjusted += OpImm;
|
||||
if (emitFrameMoves)
|
||||
EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
|
||||
}
|
||||
}
|
||||
|
||||
/// The SP register is moved in steps of 'MaxImmU16' towards the top of the
|
||||
/// frame. During these steps, it may be necessary to re-load registers.
|
||||
/// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
|
||||
/// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
|
||||
/// \param OffsetFromTop the spill offset from the top of the frame.
|
||||
/// \param [in] [out] RemainingAdj the current SP offset from the top of the frame.
|
||||
static void IfNeededLDAWSP(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI, DebugLoc dl,
|
||||
const TargetInstrInfo &TII, int OffsetFromTop,
|
||||
int &RemainingAdj) {
|
||||
while (OffsetFromTop < RemainingAdj - MaxImmU16) {
|
||||
assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
|
||||
int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
|
||||
int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
|
||||
RemainingAdj -= OpImm;
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an ordered list of registers that are spilled
|
||||
/// during the emitPrologue/emitEpilogue.
|
||||
/// Registers are ordered according to their frame offset.
|
||||
static void GetSpillList(SmallVectorImpl<std::pair<unsigned,int> > &SpillList,
|
||||
MachineFrameInfo *MFI, XCoreFunctionInfo *XFI,
|
||||
bool fetchLR, bool fetchFP) {
|
||||
int LRSpillOffset = fetchLR? MFI->getObjectOffset(XFI->getLRSpillSlot()) : 0;
|
||||
int FPSpillOffset = fetchFP? MFI->getObjectOffset(XFI->getFPSpillSlot()) : 0;
|
||||
if (fetchLR && fetchFP && LRSpillOffset > FPSpillOffset) {
|
||||
SpillList.push_back(std::make_pair<unsigned,int>(XCore::LR,LRSpillOffset));
|
||||
fetchLR = false;
|
||||
}
|
||||
if (fetchFP)
|
||||
SpillList.push_back(std::make_pair<unsigned,int>(FramePtr, FPSpillOffset));
|
||||
if (fetchLR)
|
||||
SpillList.push_back(std::make_pair<unsigned,int>(XCore::LR,LRSpillOffset));
|
||||
}
|
||||
|
||||
|
||||
@ -80,7 +142,7 @@ XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
|
||||
|
||||
bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
|
||||
MF.getFrameInfo()->hasVarSizedObjects();
|
||||
MF.getFrameInfo()->hasVarSizedObjects();
|
||||
}
|
||||
|
||||
void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
@ -98,90 +160,69 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
report_fatal_error("emitPrologue unsupported alignment: "
|
||||
+ Twine(MFI->getMaxAlignment()));
|
||||
|
||||
bool FP = hasFP(MF);
|
||||
const AttributeSet &PAL = MF.getFunction()->getAttributes();
|
||||
|
||||
if (PAL.hasAttrSomewhere(Attribute::Nest))
|
||||
loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
|
||||
|
||||
// Work out frame sizes.
|
||||
int FrameSize = MFI->getStackSize();
|
||||
assert(FrameSize%4 == 0 && "Misaligned frame size");
|
||||
FrameSize/=4;
|
||||
|
||||
bool isU6 = isImmU6(FrameSize);
|
||||
|
||||
if (!isU6 && !isImmU16(FrameSize)) {
|
||||
// FIXME could emit multiple instructions.
|
||||
report_fatal_error("emitPrologue Frame size too big: " + Twine(FrameSize));
|
||||
}
|
||||
bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
|
||||
// We will adjust the SP in stages towards the final FrameSize.
|
||||
assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size");
|
||||
const int FrameSize = MFI->getStackSize() / 4;
|
||||
int Adjusted = 0;
|
||||
|
||||
bool saveLR = XFI->getUsesLR();
|
||||
// Do we need to allocate space on the stack?
|
||||
if (FrameSize) {
|
||||
bool LRSavedOnEntry = false;
|
||||
int Opcode;
|
||||
if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) {
|
||||
Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
|
||||
MBB.addLiveIn(XCore::LR);
|
||||
saveLR = false;
|
||||
LRSavedOnEntry = true;
|
||||
} else {
|
||||
Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
|
||||
}
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
|
||||
bool UseENTSP = saveLR && FrameSize
|
||||
&& (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
|
||||
if (UseENTSP)
|
||||
saveLR = false;
|
||||
bool FP = hasFP(MF);
|
||||
bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
|
||||
|
||||
if (emitFrameMoves) {
|
||||
// Show update of SP.
|
||||
MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel);
|
||||
MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel,
|
||||
-FrameSize*4));
|
||||
if (LRSavedOnEntry) {
|
||||
unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true);
|
||||
MMI->addFrameInst(MCCFIInstruction::createOffset(FrameLabel, Reg, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (saveLR) {
|
||||
int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
|
||||
storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII);
|
||||
if (UseENTSP) {
|
||||
// Allocate space on the stack at the same time as saving LR.
|
||||
Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
|
||||
int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(Adjusted);
|
||||
MBB.addLiveIn(XCore::LR);
|
||||
|
||||
if (emitFrameMoves) {
|
||||
MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel);
|
||||
unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true);
|
||||
MMI->addFrameInst(MCCFIInstruction::createOffset(SaveLRLabel, Reg,
|
||||
LRSpillOffset));
|
||||
EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4);
|
||||
unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
|
||||
EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// If necessary, save LR and FP to the stack, as we EXTSP.
|
||||
SmallVector<std::pair<unsigned,int>,2> SpillList;
|
||||
GetSpillList(SpillList, MFI, XFI, saveLR, FP);
|
||||
for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
|
||||
unsigned SpillReg = SpillList[i].first;
|
||||
int SpillOffset = SpillList[i].second;
|
||||
assert(SpillOffset % 4 == 0 && "Misaligned stack offset");
|
||||
assert(SpillOffset <= 0 && "Unexpected positive stack offset");
|
||||
int OffsetFromTop = - SpillOffset/4;
|
||||
IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize,
|
||||
emitFrameMoves);
|
||||
int Offset = Adjusted - OffsetFromTop;
|
||||
int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addReg(SpillReg).addImm(Offset);
|
||||
MBB.addLiveIn(SpillReg);
|
||||
if (emitFrameMoves) {
|
||||
unsigned DRegNum = MRI->getDwarfRegNum(SpillReg, true);
|
||||
EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillOffset, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Complete any remaining Stack adjustment.
|
||||
IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize,
|
||||
emitFrameMoves);
|
||||
assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
|
||||
|
||||
if (FP) {
|
||||
// Save R10 to the stack.
|
||||
int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
|
||||
storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl, TII);
|
||||
// R10 is live-in. It is killed at the spill.
|
||||
MBB.addLiveIn(XCore::R10);
|
||||
if (emitFrameMoves) {
|
||||
MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label);
|
||||
unsigned Reg = MRI->getDwarfRegNum(XCore::R10, true);
|
||||
MMI->addFrameInst(MCCFIInstruction::createOffset(SaveR10Label, Reg,
|
||||
FPSpillOffset));
|
||||
}
|
||||
// Set the FP from the SP.
|
||||
unsigned FramePtr = XCore::R10;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
|
||||
if (emitFrameMoves) {
|
||||
// Show FP is now valid.
|
||||
MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel);
|
||||
unsigned Reg = MRI->getDwarfRegNum(FramePtr, true);
|
||||
MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel,
|
||||
Reg));
|
||||
}
|
||||
if (emitFrameMoves)
|
||||
EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI,
|
||||
MRI->getDwarfRegNum(FramePtr, true));
|
||||
}
|
||||
|
||||
if (emitFrameMoves) {
|
||||
@ -192,9 +233,8 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
MCSymbol *SpillLabel = SpillLabels[I].first;
|
||||
CalleeSavedInfo &CSI = SpillLabels[I].second;
|
||||
int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
|
||||
unsigned Reg = MRI->getDwarfRegNum(CSI.getReg(), true);
|
||||
MMI->addFrameInst(MCCFIInstruction::createOffset(SpillLabel, Reg,
|
||||
Offset));
|
||||
unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
|
||||
EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, Offset, SpillLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,60 +248,58 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
|
||||
DebugLoc dl = MBBI->getDebugLoc();
|
||||
|
||||
bool FP = hasFP(MF);
|
||||
if (FP) {
|
||||
// Restore the stack pointer.
|
||||
unsigned FramePtr = XCore::R10;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r))
|
||||
.addReg(FramePtr);
|
||||
}
|
||||
|
||||
// Work out frame sizes.
|
||||
int FrameSize = MFI->getStackSize();
|
||||
|
||||
assert(FrameSize%4 == 0 && "Misaligned frame size");
|
||||
|
||||
FrameSize/=4;
|
||||
|
||||
bool isU6 = isImmU6(FrameSize);
|
||||
|
||||
if (!isU6 && !isImmU16(FrameSize)) {
|
||||
// FIXME could emit multiple instructions.
|
||||
report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize));
|
||||
}
|
||||
|
||||
if (FP) {
|
||||
// Restore R10
|
||||
int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot());
|
||||
FPSpillOffset += FrameSize*4;
|
||||
loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII);
|
||||
}
|
||||
// We will adjust the SP in stages towards the final FrameSize.
|
||||
int RemainingAdj = MFI->getStackSize();
|
||||
assert(RemainingAdj%4 == 0 && "Misaligned frame size");
|
||||
RemainingAdj /= 4;
|
||||
|
||||
bool restoreLR = XFI->getUsesLR();
|
||||
if (restoreLR &&
|
||||
(FrameSize == 0 || MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0)) {
|
||||
int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot());
|
||||
LRSpillOffset += FrameSize*4;
|
||||
loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII);
|
||||
bool UseRETSP = restoreLR && RemainingAdj
|
||||
&& (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
|
||||
if (UseRETSP)
|
||||
restoreLR = false;
|
||||
bool FP = hasFP(MF);
|
||||
|
||||
if (FP) // Restore the stack pointer.
|
||||
BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
|
||||
|
||||
// If necessary, restore LR and FP from the stack, as we EXTSP.
|
||||
SmallVector<std::pair<unsigned,int>,2> SpillList;
|
||||
GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
|
||||
unsigned i = SpillList.size();
|
||||
while (i--) {
|
||||
unsigned SpilledReg = SpillList[i].first;
|
||||
int SpillOffset = SpillList[i].second;
|
||||
assert(SpillOffset % 4 == 0 && "Misaligned stack offset");
|
||||
assert(SpillOffset <= 0 && "Unexpected positive stack offset");
|
||||
int OffsetFromTop = - SpillOffset/4;
|
||||
IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
|
||||
int Offset = RemainingAdj - OffsetFromTop;
|
||||
int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpilledReg).addImm(Offset);
|
||||
}
|
||||
|
||||
if (FrameSize) {
|
||||
if (restoreLR) {
|
||||
if (RemainingAdj) {
|
||||
// Complete all but one of the remaining Stack adjustments.
|
||||
IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
|
||||
if (UseRETSP) {
|
||||
// Fold prologue into return instruction
|
||||
assert(MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0);
|
||||
assert(MBBI->getOpcode() == XCore::RETSP_u6
|
||||
|| MBBI->getOpcode() == XCore::RETSP_lu6);
|
||||
int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
|
||||
|| MBBI->getOpcode() == XCore::RETSP_lu6);
|
||||
int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
|
||||
.addImm(RemainingAdj);
|
||||
for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
|
||||
MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
|
||||
MBB.erase(MBBI);
|
||||
MBB.erase(MBBI); // Erase the previous return instruction.
|
||||
} else {
|
||||
int Opcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize);
|
||||
int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
|
||||
XCore::LDAWSP_lru6;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
|
||||
// Don't erase the return instruction.
|
||||
}
|
||||
}
|
||||
} // else Don't erase the return instruction.
|
||||
}
|
||||
|
||||
bool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
@ -278,7 +316,8 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
|
||||
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
if (MI != MBB.end())
|
||||
DL = MI->getDebugLoc();
|
||||
|
||||
for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
|
||||
it != CSI.end(); ++it) {
|
||||
|
@ -1,5 +1,15 @@
|
||||
; RUN: llc < %s -march=xcore | FileCheck %s
|
||||
; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s -check-prefix=CHECKFP
|
||||
|
||||
|
||||
; CHECKFP-LABEL: f1
|
||||
; CHECKFP: entsp 2
|
||||
; CHECKFP-NEXT: stw r10, sp[1]
|
||||
; CHECKFP-NEXT: ldaw r10, sp[0]
|
||||
; CHECKFP: set sp, r10
|
||||
; CHECKFP-NEXT: ldw r10, sp[1]
|
||||
; CHECKFP-NEXT: retsp 2
|
||||
;
|
||||
; CHECK-LABEL: f1
|
||||
; CHECK: stw lr, sp[0]
|
||||
; CHECK: ldw lr, sp[0]
|
||||
@ -10,6 +20,22 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; CHECKFP-LABEL:f3
|
||||
; CHECKFP: entsp 3
|
||||
; CHECKFP-NEXT: stw r10, sp[1]
|
||||
; CHECKFP-NEXT: ldaw r10, sp[0]
|
||||
; CHECKFP-NEXT: stw [[REG:r[4-9]+]], r10[2]
|
||||
; CHECKFP-NEXT: mov [[REG]], r0
|
||||
; CHECKFP-NEXT: extsp 1
|
||||
; CHECKFP-NEXT: bl f2
|
||||
; CHECKFP-NEXT: ldaw sp, sp[1]
|
||||
; CHECKFP-NEXT: mov r0, [[REG]]
|
||||
; CHECKFP-NEXT: ldw [[REG]], r10[2]
|
||||
; CHECKFP-NEXT: set sp, r10
|
||||
; CHECKFP-NEXT: ldw r10, sp[1]
|
||||
; CHECKFP-NEXT: retsp 3
|
||||
;
|
||||
; CHECK-LABEL: f3
|
||||
; CHECK: entsp 2
|
||||
; CHECK: stw [[REG:r[4-9]+]], sp[1]
|
||||
@ -24,3 +50,102 @@ entry:
|
||||
call void @f2()
|
||||
ret i32 %i
|
||||
}
|
||||
|
||||
|
||||
; CHECKFP-LABEL: f4
|
||||
; CHECKFP: extsp 65535
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 262140
|
||||
; CHECKFP-NEXT: extsp 34467
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 400008
|
||||
; CHECKFP-NEXT: stw r10, sp[1]
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_offset 10, -400004
|
||||
; CHECKFP-NEXT: ldaw r10, sp[0]
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_register 10
|
||||
; CHECKFP-NEXT: set sp, r10
|
||||
; CHECKFP-NEXT: ldw r10, sp[1]
|
||||
; CHECKFP-NEXT: ldaw sp, sp[65535]
|
||||
; CHECKFP-NEXT: ldaw sp, sp[34467]
|
||||
; CHECKFP-NEXT: retsp 0
|
||||
;
|
||||
; CHECK-LABEL: f4
|
||||
; CHECK: extsp 65535
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 262140
|
||||
; CHECK-NEXT: extsp 34465
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 400000
|
||||
; CHECK-NEXT: ldaw sp, sp[65535]
|
||||
; CHECK-NEXT: ldaw sp, sp[34465]
|
||||
; CHECK-NEXT: retsp 0
|
||||
define void @f4() {
|
||||
entry:
|
||||
%0 = alloca [100000 x i32], align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; CHECKFP-LABEL: f6
|
||||
; CHECKFP: entsp 65535
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 262140
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_offset 15, 0
|
||||
; CHECKFP-NEXT: extsp 65535
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 524280
|
||||
; CHECKFP-NEXT: extsp 65535
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 786420
|
||||
; CHECKFP-NEXT: extsp 3396
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_offset 800004
|
||||
; CHECKFP-NEXT: stw r10, sp[1]
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_offset 10, -800000
|
||||
; CHECKFP-NEXT: ldaw r10, sp[0]
|
||||
; CHECKFP-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECKFP-NEXT: .cfi_def_cfa_register 10
|
||||
; CHECKFP-NEXT: extsp 1
|
||||
; CHECKFP-NEXT: ldaw r0, r10[2]
|
||||
; CHECKFP-NEXT: bl f5
|
||||
; CHECKFP-NEXT: ldaw sp, sp[1]
|
||||
; CHECKFP-NEXT: set sp, r10
|
||||
; CHECKFP-NEXT: ldw r10, sp[1]
|
||||
; CHECKFP-NEXT: ldaw sp, sp[65535]
|
||||
; CHECKFP-NEXT: ldaw sp, sp[65535]
|
||||
; CHECKFP-NEXT: ldaw sp, sp[65535]
|
||||
; CHECKFP-NEXT: retsp 3396
|
||||
;
|
||||
; CHECK-LABEL: f6
|
||||
; CHECK: entsp 65535
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 262140
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_offset 15, 0
|
||||
; CHECK-NEXT: extsp 65535
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 524280
|
||||
; CHECK-NEXT: extsp 65535
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 786420
|
||||
; CHECK-NEXT: extsp 3395
|
||||
; CHECK-NEXT: .Ltmp{{[0-9]+}}
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset 800000
|
||||
; CHECK-NEXT: ldaw r0, sp[1]
|
||||
; CHECK-NEXT: bl f5
|
||||
; CHECK-NEXT: ldaw sp, sp[65535]
|
||||
; CHECK-NEXT: ldaw sp, sp[65535]
|
||||
; CHECK-NEXT: ldaw sp, sp[65535]
|
||||
; CHECK-NEXT: retsp 3395
|
||||
declare void @f5(i32*)
|
||||
define void @f6() {
|
||||
entry:
|
||||
%0 = alloca [199999 x i32], align 4
|
||||
%1 = getelementptr inbounds [199999 x i32]* %0, i32 0, i32 0
|
||||
call void @f5(i32* %1)
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user