void XCoreFrameInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); 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 (FrameSize) { XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); if (FP) { // Restore R10 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); FPSpillOffset += FrameSize*4; loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); } bool restoreLR = XFI->getUsesLR(); if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); LRSpillOffset += FrameSize*4; loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); restoreLR = false; } if (restoreLR) { // Fold prologue into return instruction assert(MBBI->getOpcode() == XCore::RETSP_u6 || MBBI->getOpcode() == XCore::RETSP_lu6); int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); MBB.erase(MBBI); } else { int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); } } }
void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo(); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI->getDebugLoc(); unsigned RetOpcode = MBBI->getOpcode(); // Work out frame sizes. // We will adjust the SP in stages towards the final FrameSize. int RemainingAdj = MFI->getStackSize(); assert(RemainingAdj%4 == 0 && "Misaligned frame size"); RemainingAdj /= 4; if (RetOpcode == XCore::EH_RETURN) { // 'Restore' the exception info the unwinder has placed into the stack // slots. SmallVector<StackSlotInfo,2> SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering()); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); // Return to the landing pad. unsigned EhStackReg = MBBI->getOperand(0).getReg(); unsigned EhHandlerReg = MBBI->getOperand(1).getReg(); BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg); BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg); MBB.erase(MBBI); // Erase the previous return instruction. return; } bool restoreLR = XFI->hasLRSpillSlot(); 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<StackSlotInfo,2> SpillList; GetSpillList(SpillList, MFI, XFI, restoreLR, FP); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); 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(RetOpcode == XCore::RETSP_u6 || RetOpcode == 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); // Erase the previous return instruction. } else { 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. }
void XCoreFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = &MF.getMMI(); const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo(); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. DebugLoc dl; if (MFI->getMaxAlignment() > getStackAlignment()) report_fatal_error("emitPrologue unsupported alignment: " + Twine(MFI->getMaxAlignment())); 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. assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size"); const int FrameSize = MFI->getStackSize() / 4; int Adjusted = 0; bool saveLR = XFI->hasLRSpillSlot(); bool UseENTSP = saveLR && FrameSize && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); if (UseENTSP) saveLR = false; bool FP = hasFP(MF); bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 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; MBB.addLiveIn(XCore::LR); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)); MIB.addImm(Adjusted); MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(), true); if (emitFrameMoves) { EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0); } } // If necessary, save LR and FP to the stack, as we EXTSP. SmallVector<StackSlotInfo,2> SpillList; GetSpillList(SpillList, MFI, XFI, saveLR, FP); // We want the nearest (negative) offsets first, so reverse list. std::reverse(SpillList.begin(), SpillList.end()); for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 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(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(SpillList[i].Reg, true); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset); } } // 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) { // Set the FP from the SP. BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); if (emitFrameMoves) EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, MRI->getDwarfRegNum(FramePtr, true)); } if (emitFrameMoves) { // Frame moves for callee saved. for (const auto &SpillLabel : XFI->getSpillLabels()) { MachineBasicBlock::iterator Pos = SpillLabel.first; ++Pos; const CalleeSavedInfo &CSI = SpillLabel.second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); EmitCfiOffset(MBB, Pos, dl, TII, MMI, DRegNum, Offset); } if (XFI->hasEHSpillSlot()) { // The unwinder requires stack slot & CFI offsets for the exception info. // We do not save/spill these registers. SmallVector<StackSlotInfo,2> SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering()); assert(SpillList.size()==2 && "Unexpected SpillList size"); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, MRI->getDwarfRegNum(SpillList[0].Reg, true), SpillList[0].Offset); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, MRI->getDwarfRegNum(SpillList[1].Reg, true), SpillList[1].Offset); } } }
void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI->getDebugLoc(); // Work out frame sizes. // 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(); 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 (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(MBBI->getOpcode() == XCore::RETSP_u6 || 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); // Erase the previous return instruction. } else { 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. }
void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = &MF.getMMI(); const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); if (MFI->getMaxAlignment() > getStackAlignment()) report_fatal_error("emitPrologue unsupported alignment: " + Twine(MFI->getMaxAlignment())); const AttributeSet &PAL = MF.getFunction()->getAttributes(); if (PAL.hasAttrSomewhere(Attribute::Nest)) BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); // Work out frame sizes. // 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(); bool UseENTSP = saveLR && FrameSize && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); if (UseENTSP) saveLR = false; bool FP = hasFP(MF); bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 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) { 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) { // Set the FP from the SP. BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); if (emitFrameMoves) EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, MRI->getDwarfRegNum(FramePtr, true)); } if (emitFrameMoves) { // Frame moves for callee saved. std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = XFI->getSpillLabels(); for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { MCSymbol *SpillLabel = SpillLabels[I].first; CalleeSavedInfo &CSI = SpillLabels[I].second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, Offset, SpillLabel); } } }
void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); bool FP = hasFP(MF); // 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. cerr << "emitPrologue Frame size too big: " << FrameSize << "\n"; abort(); } bool emitFrameMoves = needsFrameMoves(MF); // Do we need to allocate space on the stack? if (FrameSize) { bool saveLR = XFI->getUsesLR(); 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, TII.get(Opcode)).addImm(FrameSize); if (emitFrameMoves) { std::vector<MachineMove> &Moves = MMI->getFrameMoves(); // Show update of SP. unsigned FrameLabelId = MMI->NextLabelID(); BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); MachineLocation SPDst(MachineLocation::VirtualFP); MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); if (LRSavedOnEntry) { MachineLocation CSDst(MachineLocation::VirtualFP, 0); MachineLocation CSSrc(XCore::LR); Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); } } if (saveLR) { int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4); MBB.addLiveIn(XCore::LR); if (emitFrameMoves) { unsigned SaveLRLabelId = MMI->NextLabelID(); BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId); MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); MachineLocation CSSrc(XCore::LR); MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId, CSDst, CSSrc)); } } } if (FP) { // Save R10 to the stack. int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4); // R10 is live-in. It is killed at the spill. MBB.addLiveIn(XCore::R10); if (emitFrameMoves) { unsigned SaveR10LabelId = MMI->NextLabelID(); BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId); MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); MachineLocation CSSrc(XCore::R10); MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId, CSDst, CSSrc)); } // Set the FP from the SP. unsigned FramePtr = XCore::R10; BuildMI(MBB, MBBI, TII.get(XCore::LDAWSP_ru6), FramePtr) .addImm(0); if (emitFrameMoves) { // Show FP is now valid. unsigned FrameLabelId = MMI->NextLabelID(); BuildMI(MBB, MBBI, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); MachineLocation SPDst(FramePtr); MachineLocation SPSrc(MachineLocation::VirtualFP); MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); } } if (emitFrameMoves) { // Frame moves for callee saved. std::vector<MachineMove> &Moves = MMI->getFrameMoves(); std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels = XFI->getSpillLabels(); for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { unsigned SpillLabel = SpillLabels[I].first; CalleeSavedInfo &CSI = SpillLabels[I].second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); unsigned Reg = CSI.getReg(); MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSSrc(Reg); Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); } } }
void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = &MF.getMMI(); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); bool FP = hasFP(MF); const AttributeSet &PAL = MF.getFunction()->getAttributes(); if (PAL.hasAttrSomewhere(Attribute::Nest)) loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII); // 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); bool saveLR = XFI->getUsesLR(); // Do we need to allocate space on the stack? if (FrameSize) { int Opcode; if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; MBB.addLiveIn(XCore::LR); saveLR = false; } else { Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; } BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); if (emitFrameMoves) { // Show update of SP. MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); } } if (saveLR) { int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); MBB.addLiveIn(XCore::LR); if (emitFrameMoves) { MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); } } 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); } // 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); } } }
void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = &MF.getMMI(); const XCoreRegisterInfo *RegInfo = static_cast<const XCoreRegisterInfo*>(MF.getTarget().getRegisterInfo()); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); bool FP = hasFP(MF); bool Nested = MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::Nest); if (Nested) { loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII); } // 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 = RegInfo->needsFrameMoves(MF); // Do we need to allocate space on the stack? if (FrameSize) { bool saveLR = XFI->getUsesLR(); 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); if (emitFrameMoves) { std::vector<MachineMove> &Moves = MMI->getFrameMoves(); // Show update of SP. MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); MachineLocation SPDst(MachineLocation::VirtualFP); MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); if (LRSavedOnEntry) { MachineLocation CSDst(MachineLocation::VirtualFP, 0); MachineLocation CSSrc(XCore::LR); Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); } } if (saveLR) { int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); MBB.addLiveIn(XCore::LR); if (emitFrameMoves) { MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); MachineLocation CSSrc(XCore::LR); MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); } } } 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); MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); MachineLocation CSSrc(XCore::R10); MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc)); } // 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); MachineLocation SPDst(FramePtr); MachineLocation SPSrc(MachineLocation::VirtualFP); MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc)); } } if (emitFrameMoves) { // Frame moves for callee saved. std::vector<MachineMove> &Moves = MMI->getFrameMoves(); std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = XFI->getSpillLabels(); for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { MCSymbol *SpillLabel = SpillLabels[I].first; CalleeSavedInfo &CSI = SpillLabels[I].second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); unsigned Reg = CSI.getReg(); MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSSrc(Reg); Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); } } }