diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index 8ea9788b1a8..4a0d8a4b50a 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -44,6 +44,21 @@ static inline bool isImmU16(unsigned val) { return val < (1 << 16); } +// Helper structure with compare function for handling stack slots. +namespace { +struct StackSlotInfo { + int FI; + int Offset; + unsigned Reg; + StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){}; +}; +} // end anonymous namespace + +static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) { + return a.Offset < b.Offset; +} + + static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, @@ -119,55 +134,73 @@ static void IfNeededLDAWSP(MachineBasicBlock &MBB, /// during the emitPrologue/emitEpilogue. /// Registers are ordered according to their frame offset. /// As offsets are negative, the largest offsets will be first. -static void GetSpillList(SmallVectorImpl > &SpillList, +static void GetSpillList(SmallVectorImpl &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP) { if (fetchLR) { int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - SpillList.push_back(std::pair(Offset, XCore::LR)); + SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(), + Offset, + XCore::LR)); } if (fetchFP) { int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - SpillList.push_back(std::pair(Offset, FramePtr)); + SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(), + Offset, + FramePtr)); } - std::sort(SpillList.begin(), SpillList.end()); + std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); } /// Creates an ordered list of EH info register 'spills'. /// These slots are only used by the unwinder and calls to llvm.eh.return(). /// Registers are ordered according to their frame offset. /// As offsets are negative, the largest offsets will be first. -static void GetEHSpillList(SmallVectorImpl > &SpillList, +static void GetEHSpillList(SmallVectorImpl &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, const TargetLowering *TL) { assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots"); const int* EHSlot = XFI->getEHSpillSlot(); - SpillList.push_back( - std::pair(MFI->getObjectOffset(EHSlot[0]), - TL->getExceptionPointerRegister())); - SpillList.push_back( - std::pair(MFI->getObjectOffset(EHSlot[1]), - TL->getExceptionSelectorRegister())); - std::sort(SpillList.begin(), SpillList.end()); + SpillList.push_back(StackSlotInfo(EHSlot[0], + MFI->getObjectOffset(EHSlot[0]), + TL->getExceptionPointerRegister())); + SpillList.push_back(StackSlotInfo(EHSlot[0], + MFI->getObjectOffset(EHSlot[1]), + TL->getExceptionSelectorRegister())); + std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); } + +static MachineMemOperand * +getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) { + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), + flags, MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + return MMO; +} + + /// Restore clobbered registers with their spill slot value. /// The SP will be adjusted at the same time, thus the SpillList must be ordered /// with the largest (negative) offsets first. static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, - SmallVectorImpl > &SpillList) { + SmallVectorImpl &SpillList) { for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { - unsigned SpilledReg = SpillList[i].second; - int SpillOffset = SpillList[i].first; - assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); - assert(SpillOffset <= 0 && "Unexpected positive stack offset"); - int OffsetFromTop = - SpillOffset/4; + assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); + assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillList[i].Offset/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); + BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg) + .addImm(Offset) + .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, + MachineMemOperand::MOLoad)); } } @@ -203,6 +236,7 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { const AttributeSet &PAL = MF.getFunction()->getAttributes(); if (PAL.hasAttrSomewhere(Attribute::Nest)) BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); + // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack(). // Work out frame sizes. // We will adjust the SP in stages towards the final FrameSize. @@ -234,26 +268,27 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { } // If necessary, save LR and FP to the stack, as we EXTSP. - SmallVector,2> SpillList; + SmallVector SpillList; GetSpillList(SpillList, MFI, XFI, saveLR, FP); // We want the nearest (negative) offsets first, so reverse list. - std::reverse(SpillList.begin(),SpillList.end()); + std::reverse(SpillList.begin(), SpillList.end()); for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { - unsigned SpillReg = SpillList[i].second; - int SpillOffset = SpillList[i].first; - assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); - assert(SpillOffset <= 0 && "Unexpected positive stack offset"); - int OffsetFromTop = - SpillOffset/4; + assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); + assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillList[i].Offset/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; - MBB.addLiveIn(SpillReg); - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addReg(SpillReg, RegState::Kill) - .addImm(Offset); + MBB.addLiveIn(SpillList[i].Reg); + BuildMI(MBB, MBBI, dl, TII.get(Opcode)) + .addReg(SpillList[i].Reg, RegState::Kill) + .addImm(Offset) + .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, + MachineMemOperand::MOStore)); if (emitFrameMoves) { - unsigned DRegNum = MRI->getDwarfRegNum(SpillReg, true); - EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillOffset, NULL); + unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true); + EmitCfiOffset(MBB,MBBI,dl,TII,MMI, DRegNum, SpillList[i].Offset, NULL); } } @@ -284,15 +319,15 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { if (XFI->hasEHSpillSlot()) { // The unwinder requires stack slot & CFI offsets for the exception info. // We do not save/spill these registers. - SmallVector,2> SpillList; + SmallVector SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); assert(SpillList.size()==2 && "Unexpected SpillList size"); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, - MRI->getDwarfRegNum(SpillList[0].second,true), - SpillList[0].first, NULL); + MRI->getDwarfRegNum(SpillList[0].Reg, true), + SpillList[0].Offset, NULL); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, - MRI->getDwarfRegNum(SpillList[1].second,true), - SpillList[1].first, NULL); + MRI->getDwarfRegNum(SpillList[1].Reg, true), + SpillList[1].Offset, NULL); } } } @@ -315,7 +350,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, if (RetOpcode == XCore::EH_RETURN) { // 'Restore' the exception info the unwinder has placed into the stack slots. - SmallVector,2> SpillList; + SmallVector SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); @@ -339,7 +374,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); // If necessary, restore LR and FP from the stack, as we EXTSP. - SmallVector,2> SpillList; + SmallVector SpillList; GetSpillList(SpillList, MFI, XFI, restoreLR, FP); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp index 33b97fba8dc..cea3bbf1750 100644 --- a/lib/Target/XCore/XCoreInstrInfo.cpp +++ b/lib/Target/XCore/XCoreInstrInfo.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCContext.h" @@ -374,10 +375,18 @@ void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), + MachineMemOperand::MOStore, + MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); BuildMI(MBB, I, DL, get(XCore::STWFI)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FrameIndex) - .addImm(0); + .addImm(0) + .addMemOperand(MMO); } void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, @@ -388,9 +397,17 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, { DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), + MachineMemOperand::MOLoad, + MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) .addFrameIndex(FrameIndex) - .addImm(0); + .addImm(0) + .addMemOperand(MMO); } /// ReverseBranchCondition - Return the inverse opcode of the diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index d5a96d70b5e..d85d7176515 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -67,13 +67,15 @@ static void InsertFPImmInst(MachineBasicBlock::iterator II, case XCore::LDWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) .addReg(FrameReg) - .addImm(Offset); + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::STWFI: BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) .addReg(FrameReg) - .addImm(Offset); + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::LDAWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) @@ -93,7 +95,6 @@ static void InsertFPConstInst(MachineBasicBlock::iterator II, MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); DebugLoc dl = MI.getDebugLoc(); - unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); RS->setUsed(ScratchOffset); TII.loadImmediate(MBB, II, ScratchOffset, Offset); @@ -102,13 +103,15 @@ static void InsertFPConstInst(MachineBasicBlock::iterator II, case XCore::LDWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) .addReg(FrameReg) - .addReg(ScratchOffset, RegState::Kill); + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::STWFI: BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) .addReg(FrameReg) - .addReg(ScratchOffset, RegState::Kill); + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::LDAWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) @@ -127,18 +130,21 @@ static void InsertSPImmInst(MachineBasicBlock::iterator II, MachineBasicBlock &MBB = *MI.getParent(); DebugLoc dl = MI.getDebugLoc(); bool isU6 = isImmU6(Offset); + switch (MI.getOpcode()) { int NewOpcode; case XCore::LDWFI: NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) - .addImm(Offset); + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::STWFI: NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; BuildMI(MBB, II, dl, TII.get(NewOpcode)) .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) - .addImm(Offset); + .addImm(Offset) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::LDAWFI: NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; @@ -174,13 +180,15 @@ static void InsertSPConstInst(MachineBasicBlock::iterator II, case XCore::LDWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) .addReg(ScratchBase, RegState::Kill) - .addReg(ScratchOffset, RegState::Kill); + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::STWFI: BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) .addReg(ScratchBase, RegState::Kill) - .addReg(ScratchOffset, RegState::Kill); + .addReg(ScratchOffset, RegState::Kill) + .addMemOperand(*MI.memoperands_begin()); break; case XCore::LDAWFI: BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)