LLVM API Documentation
00001 //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains XCore frame information that doesn't fit anywhere else 00011 // cleanly... 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "XCoreFrameLowering.h" 00016 #include "XCore.h" 00017 #include "XCoreInstrInfo.h" 00018 #include "XCoreMachineFunctionInfo.h" 00019 #include "XCoreSubtarget.h" 00020 #include "llvm/CodeGen/MachineFrameInfo.h" 00021 #include "llvm/CodeGen/MachineFunction.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/CodeGen/MachineModuleInfo.h" 00024 #include "llvm/CodeGen/MachineRegisterInfo.h" 00025 #include "llvm/CodeGen/RegisterScavenging.h" 00026 #include "llvm/IR/DataLayout.h" 00027 #include "llvm/IR/Function.h" 00028 #include "llvm/Support/ErrorHandling.h" 00029 #include "llvm/Target/TargetLowering.h" 00030 #include "llvm/Target/TargetOptions.h" 00031 #include <algorithm> // std::sort 00032 00033 using namespace llvm; 00034 00035 static const unsigned FramePtr = XCore::R10; 00036 static const int MaxImmU16 = (1<<16) - 1; 00037 00038 // helper functions. FIXME: Eliminate. 00039 static inline bool isImmU6(unsigned val) { 00040 return val < (1 << 6); 00041 } 00042 00043 static inline bool isImmU16(unsigned val) { 00044 return val < (1 << 16); 00045 } 00046 00047 // Helper structure with compare function for handling stack slots. 00048 namespace { 00049 struct StackSlotInfo { 00050 int FI; 00051 int Offset; 00052 unsigned Reg; 00053 StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){}; 00054 }; 00055 } // end anonymous namespace 00056 00057 static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) { 00058 return a.Offset < b.Offset; 00059 } 00060 00061 00062 static void EmitDefCfaRegister(MachineBasicBlock &MBB, 00063 MachineBasicBlock::iterator MBBI, DebugLoc dl, 00064 const TargetInstrInfo &TII, 00065 MachineModuleInfo *MMI, unsigned DRegNum) { 00066 unsigned CFIIndex = MMI->addFrameInst( 00067 MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum)); 00068 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 00069 .addCFIIndex(CFIIndex); 00070 } 00071 00072 static void EmitDefCfaOffset(MachineBasicBlock &MBB, 00073 MachineBasicBlock::iterator MBBI, DebugLoc dl, 00074 const TargetInstrInfo &TII, 00075 MachineModuleInfo *MMI, int Offset) { 00076 unsigned CFIIndex = 00077 MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset)); 00078 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 00079 .addCFIIndex(CFIIndex); 00080 } 00081 00082 static void EmitCfiOffset(MachineBasicBlock &MBB, 00083 MachineBasicBlock::iterator MBBI, DebugLoc dl, 00084 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 00085 unsigned DRegNum, int Offset) { 00086 unsigned CFIIndex = MMI->addFrameInst( 00087 MCCFIInstruction::createOffset(nullptr, DRegNum, Offset)); 00088 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 00089 .addCFIIndex(CFIIndex); 00090 } 00091 00092 /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the 00093 /// frame. During these steps, it may be necessary to spill registers. 00094 /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only 00095 /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6. 00096 /// \param OffsetFromTop the spill offset from the top of the frame. 00097 /// \param [in,out] Adjusted the current SP offset from the top of the frame. 00098 static void IfNeededExtSP(MachineBasicBlock &MBB, 00099 MachineBasicBlock::iterator MBBI, DebugLoc dl, 00100 const TargetInstrInfo &TII, MachineModuleInfo *MMI, 00101 int OffsetFromTop, int &Adjusted, int FrameSize, 00102 bool emitFrameMoves) { 00103 while (OffsetFromTop > Adjusted) { 00104 assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize"); 00105 int remaining = FrameSize - Adjusted; 00106 int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining; 00107 int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 00108 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm); 00109 Adjusted += OpImm; 00110 if (emitFrameMoves) 00111 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 00112 } 00113 } 00114 00115 /// The SP register is moved in steps of 'MaxImmU16' towards the top of the 00116 /// frame. During these steps, it may be necessary to re-load registers. 00117 /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only 00118 /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6. 00119 /// \param OffsetFromTop the spill offset from the top of the frame. 00120 /// \param [in,out] RemainingAdj the current SP offset from the top of the 00121 /// frame. 00122 static void IfNeededLDAWSP(MachineBasicBlock &MBB, 00123 MachineBasicBlock::iterator MBBI, DebugLoc dl, 00124 const TargetInstrInfo &TII, int OffsetFromTop, 00125 int &RemainingAdj) { 00126 while (OffsetFromTop < RemainingAdj - MaxImmU16) { 00127 assert(RemainingAdj && "OffsetFromTop is beyond FrameSize"); 00128 int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj; 00129 int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 00130 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm); 00131 RemainingAdj -= OpImm; 00132 } 00133 } 00134 00135 /// Creates an ordered list of registers that are spilled 00136 /// during the emitPrologue/emitEpilogue. 00137 /// Registers are ordered according to their frame offset. 00138 /// As offsets are negative, the largest offsets will be first. 00139 static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, 00140 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, 00141 bool fetchLR, bool fetchFP) { 00142 if (fetchLR) { 00143 int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 00144 SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(), 00145 Offset, 00146 XCore::LR)); 00147 } 00148 if (fetchFP) { 00149 int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 00150 SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(), 00151 Offset, 00152 FramePtr)); 00153 } 00154 std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); 00155 } 00156 00157 /// Creates an ordered list of EH info register 'spills'. 00158 /// These slots are only used by the unwinder and calls to llvm.eh.return(). 00159 /// Registers are ordered according to their frame offset. 00160 /// As offsets are negative, the largest offsets will be first. 00161 static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, 00162 MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, 00163 const TargetLowering *TL) { 00164 assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots"); 00165 const int* EHSlot = XFI->getEHSpillSlot(); 00166 SpillList.push_back(StackSlotInfo(EHSlot[0], 00167 MFI->getObjectOffset(EHSlot[0]), 00168 TL->getExceptionPointerRegister())); 00169 SpillList.push_back(StackSlotInfo(EHSlot[0], 00170 MFI->getObjectOffset(EHSlot[1]), 00171 TL->getExceptionSelectorRegister())); 00172 std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); 00173 } 00174 00175 00176 static MachineMemOperand * 00177 getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) { 00178 MachineFunction *MF = MBB.getParent(); 00179 const MachineFrameInfo &MFI = *MF->getFrameInfo(); 00180 MachineMemOperand *MMO = 00181 MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), 00182 flags, MFI.getObjectSize(FrameIndex), 00183 MFI.getObjectAlignment(FrameIndex)); 00184 return MMO; 00185 } 00186 00187 00188 /// Restore clobbered registers with their spill slot value. 00189 /// The SP will be adjusted at the same time, thus the SpillList must be ordered 00190 /// with the largest (negative) offsets first. 00191 static void 00192 RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 00193 DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, 00194 SmallVectorImpl<StackSlotInfo> &SpillList) { 00195 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 00196 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); 00197 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); 00198 int OffsetFromTop = - SpillList[i].Offset/4; 00199 IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj); 00200 int Offset = RemainingAdj - OffsetFromTop; 00201 int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 00202 BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg) 00203 .addImm(Offset) 00204 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, 00205 MachineMemOperand::MOLoad)); 00206 } 00207 } 00208 00209 //===----------------------------------------------------------------------===// 00210 // XCoreFrameLowering: 00211 //===----------------------------------------------------------------------===// 00212 00213 XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) 00214 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) { 00215 // Do nothing 00216 } 00217 00218 bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { 00219 return MF.getTarget().Options.DisableFramePointerElim(MF) || 00220 MF.getFrameInfo()->hasVarSizedObjects(); 00221 } 00222 00223 void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { 00224 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00225 MachineBasicBlock::iterator MBBI = MBB.begin(); 00226 MachineFrameInfo *MFI = MF.getFrameInfo(); 00227 MachineModuleInfo *MMI = &MF.getMMI(); 00228 const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); 00229 const XCoreInstrInfo &TII = 00230 *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00231 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00232 // Debug location must be unknown since the first debug location is used 00233 // to determine the end of the prologue. 00234 DebugLoc dl; 00235 00236 if (MFI->getMaxAlignment() > getStackAlignment()) 00237 report_fatal_error("emitPrologue unsupported alignment: " 00238 + Twine(MFI->getMaxAlignment())); 00239 00240 const AttributeSet &PAL = MF.getFunction()->getAttributes(); 00241 if (PAL.hasAttrSomewhere(Attribute::Nest)) 00242 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); 00243 // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack(). 00244 00245 // Work out frame sizes. 00246 // We will adjust the SP in stages towards the final FrameSize. 00247 assert(MFI->getStackSize()%4 == 0 && "Misaligned frame size"); 00248 const int FrameSize = MFI->getStackSize() / 4; 00249 int Adjusted = 0; 00250 00251 bool saveLR = XFI->hasLRSpillSlot(); 00252 bool UseENTSP = saveLR && FrameSize 00253 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 00254 if (UseENTSP) 00255 saveLR = false; 00256 bool FP = hasFP(MF); 00257 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); 00258 00259 if (UseENTSP) { 00260 // Allocate space on the stack at the same time as saving LR. 00261 Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize; 00262 int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 00263 MBB.addLiveIn(XCore::LR); 00264 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)); 00265 MIB.addImm(Adjusted); 00266 MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(), 00267 true); 00268 if (emitFrameMoves) { 00269 EmitDefCfaOffset(MBB, MBBI, dl, TII, MMI, Adjusted*4); 00270 unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true); 00271 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, 0); 00272 } 00273 } 00274 00275 // If necessary, save LR and FP to the stack, as we EXTSP. 00276 SmallVector<StackSlotInfo,2> SpillList; 00277 GetSpillList(SpillList, MFI, XFI, saveLR, FP); 00278 // We want the nearest (negative) offsets first, so reverse list. 00279 std::reverse(SpillList.begin(), SpillList.end()); 00280 for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { 00281 assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); 00282 assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); 00283 int OffsetFromTop = - SpillList[i].Offset/4; 00284 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize, 00285 emitFrameMoves); 00286 int Offset = Adjusted - OffsetFromTop; 00287 int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 00288 MBB.addLiveIn(SpillList[i].Reg); 00289 BuildMI(MBB, MBBI, dl, TII.get(Opcode)) 00290 .addReg(SpillList[i].Reg, RegState::Kill) 00291 .addImm(Offset) 00292 .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, 00293 MachineMemOperand::MOStore)); 00294 if (emitFrameMoves) { 00295 unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true); 00296 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset); 00297 } 00298 } 00299 00300 // Complete any remaining Stack adjustment. 00301 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize, 00302 emitFrameMoves); 00303 assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment"); 00304 00305 if (FP) { 00306 // Set the FP from the SP. 00307 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); 00308 if (emitFrameMoves) 00309 EmitDefCfaRegister(MBB, MBBI, dl, TII, MMI, 00310 MRI->getDwarfRegNum(FramePtr, true)); 00311 } 00312 00313 if (emitFrameMoves) { 00314 // Frame moves for callee saved. 00315 auto SpillLabels = XFI->getSpillLabels(); 00316 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 00317 MachineBasicBlock::iterator Pos = SpillLabels[I].first; 00318 ++Pos; 00319 CalleeSavedInfo &CSI = SpillLabels[I].second; 00320 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 00321 unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true); 00322 EmitCfiOffset(MBB, Pos, dl, TII, MMI, DRegNum, Offset); 00323 } 00324 if (XFI->hasEHSpillSlot()) { 00325 // The unwinder requires stack slot & CFI offsets for the exception info. 00326 // We do not save/spill these registers. 00327 SmallVector<StackSlotInfo,2> SpillList; 00328 GetEHSpillList(SpillList, MFI, XFI, 00329 MF.getSubtarget().getTargetLowering()); 00330 assert(SpillList.size()==2 && "Unexpected SpillList size"); 00331 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, 00332 MRI->getDwarfRegNum(SpillList[0].Reg, true), 00333 SpillList[0].Offset); 00334 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, 00335 MRI->getDwarfRegNum(SpillList[1].Reg, true), 00336 SpillList[1].Offset); 00337 } 00338 } 00339 } 00340 00341 void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, 00342 MachineBasicBlock &MBB) const { 00343 MachineFrameInfo *MFI = MF.getFrameInfo(); 00344 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 00345 const XCoreInstrInfo &TII = 00346 *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00347 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00348 DebugLoc dl = MBBI->getDebugLoc(); 00349 unsigned RetOpcode = MBBI->getOpcode(); 00350 00351 // Work out frame sizes. 00352 // We will adjust the SP in stages towards the final FrameSize. 00353 int RemainingAdj = MFI->getStackSize(); 00354 assert(RemainingAdj%4 == 0 && "Misaligned frame size"); 00355 RemainingAdj /= 4; 00356 00357 if (RetOpcode == XCore::EH_RETURN) { 00358 // 'Restore' the exception info the unwinder has placed into the stack 00359 // slots. 00360 SmallVector<StackSlotInfo,2> SpillList; 00361 GetEHSpillList(SpillList, MFI, XFI, MF.getSubtarget().getTargetLowering()); 00362 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); 00363 00364 // Return to the landing pad. 00365 unsigned EhStackReg = MBBI->getOperand(0).getReg(); 00366 unsigned EhHandlerReg = MBBI->getOperand(1).getReg(); 00367 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg); 00368 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg); 00369 MBB.erase(MBBI); // Erase the previous return instruction. 00370 return; 00371 } 00372 00373 bool restoreLR = XFI->hasLRSpillSlot(); 00374 bool UseRETSP = restoreLR && RemainingAdj 00375 && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); 00376 if (UseRETSP) 00377 restoreLR = false; 00378 bool FP = hasFP(MF); 00379 00380 if (FP) // Restore the stack pointer. 00381 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); 00382 00383 // If necessary, restore LR and FP from the stack, as we EXTSP. 00384 SmallVector<StackSlotInfo,2> SpillList; 00385 GetSpillList(SpillList, MFI, XFI, restoreLR, FP); 00386 RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); 00387 00388 if (RemainingAdj) { 00389 // Complete all but one of the remaining Stack adjustments. 00390 IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj); 00391 if (UseRETSP) { 00392 // Fold prologue into return instruction 00393 assert(RetOpcode == XCore::RETSP_u6 00394 || RetOpcode == XCore::RETSP_lu6); 00395 int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 00396 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)) 00397 .addImm(RemainingAdj); 00398 for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) 00399 MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands 00400 MBB.erase(MBBI); // Erase the previous return instruction. 00401 } else { 00402 int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 : 00403 XCore::LDAWSP_lru6; 00404 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj); 00405 // Don't erase the return instruction. 00406 } 00407 } // else Don't erase the return instruction. 00408 } 00409 00410 bool XCoreFrameLowering:: 00411 spillCalleeSavedRegisters(MachineBasicBlock &MBB, 00412 MachineBasicBlock::iterator MI, 00413 const std::vector<CalleeSavedInfo> &CSI, 00414 const TargetRegisterInfo *TRI) const { 00415 if (CSI.empty()) 00416 return true; 00417 00418 MachineFunction *MF = MBB.getParent(); 00419 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 00420 XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>(); 00421 bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); 00422 00423 DebugLoc DL; 00424 if (MI != MBB.end() && !MI->isDebugValue()) 00425 DL = MI->getDebugLoc(); 00426 00427 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 00428 it != CSI.end(); ++it) { 00429 unsigned Reg = it->getReg(); 00430 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 00431 "LR & FP are always handled in emitPrologue"); 00432 00433 // Add the callee-saved register as live-in. It's killed at the spill. 00434 MBB.addLiveIn(Reg); 00435 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 00436 TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI); 00437 if (emitFrameMoves) { 00438 auto Store = MI; 00439 --Store; 00440 XFI->getSpillLabels().push_back(std::make_pair(Store, *it)); 00441 } 00442 } 00443 return true; 00444 } 00445 00446 bool XCoreFrameLowering:: 00447 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 00448 MachineBasicBlock::iterator MI, 00449 const std::vector<CalleeSavedInfo> &CSI, 00450 const TargetRegisterInfo *TRI) const{ 00451 MachineFunction *MF = MBB.getParent(); 00452 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 00453 bool AtStart = MI == MBB.begin(); 00454 MachineBasicBlock::iterator BeforeI = MI; 00455 if (!AtStart) 00456 --BeforeI; 00457 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin(); 00458 it != CSI.end(); ++it) { 00459 unsigned Reg = it->getReg(); 00460 assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) && 00461 "LR & FP are always handled in emitEpilogue"); 00462 00463 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 00464 TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI); 00465 assert(MI != MBB.begin() && 00466 "loadRegFromStackSlot didn't insert any code!"); 00467 // Insert in reverse order. loadRegFromStackSlot can insert multiple 00468 // instructions. 00469 if (AtStart) 00470 MI = MBB.begin(); 00471 else { 00472 MI = BeforeI; 00473 ++MI; 00474 } 00475 } 00476 return true; 00477 } 00478 00479 // This function eliminates ADJCALLSTACKDOWN, 00480 // ADJCALLSTACKUP pseudo instructions 00481 void XCoreFrameLowering:: 00482 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00483 MachineBasicBlock::iterator I) const { 00484 const XCoreInstrInfo &TII = 00485 *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00486 if (!hasReservedCallFrame(MF)) { 00487 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 00488 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 00489 MachineInstr *Old = I; 00490 uint64_t Amount = Old->getOperand(0).getImm(); 00491 if (Amount != 0) { 00492 // We need to keep the stack aligned properly. To do this, we round the 00493 // amount of space needed for the outgoing arguments up to the next 00494 // alignment boundary. 00495 unsigned Align = getStackAlignment(); 00496 Amount = (Amount+Align-1)/Align*Align; 00497 00498 assert(Amount%4 == 0); 00499 Amount /= 4; 00500 00501 bool isU6 = isImmU6(Amount); 00502 if (!isU6 && !isImmU16(Amount)) { 00503 // FIX could emit multiple instructions in this case. 00504 #ifndef NDEBUG 00505 errs() << "eliminateCallFramePseudoInstr size too big: " 00506 << Amount << "\n"; 00507 #endif 00508 llvm_unreachable(nullptr); 00509 } 00510 00511 MachineInstr *New; 00512 if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 00513 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 00514 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) 00515 .addImm(Amount); 00516 } else { 00517 assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 00518 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 00519 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) 00520 .addImm(Amount); 00521 } 00522 00523 // Replace the pseudo instruction with a new instruction... 00524 MBB.insert(I, New); 00525 } 00526 } 00527 00528 MBB.erase(I); 00529 } 00530 00531 void XCoreFrameLowering:: 00532 processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 00533 RegScavenger *RS) const { 00534 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00535 00536 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 00537 00538 if (!LRUsed && !MF.getFunction()->isVarArg() && 00539 MF.getFrameInfo()->estimateStackSize(MF)) 00540 // If we need to extend the stack it is more efficient to use entsp / retsp. 00541 // We force the LR to be saved so these instructions are used. 00542 LRUsed = true; 00543 00544 if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) { 00545 // The unwinder expects to find spill slots for the exception info regs R0 00546 // & R1. These are used during llvm.eh.return() to 'restore' the exception 00547 // info. N.B. we do not spill or restore R0, R1 during normal operation. 00548 XFI->createEHSpillSlot(MF); 00549 // As we will have a stack, we force the LR to be saved. 00550 LRUsed = true; 00551 } 00552 00553 if (LRUsed) { 00554 // We will handle the LR in the prologue/epilogue 00555 // and allocate space on the stack ourselves. 00556 MF.getRegInfo().setPhysRegUnused(XCore::LR); 00557 XFI->createLRSpillSlot(MF); 00558 } 00559 00560 if (hasFP(MF)) 00561 // A callee save register is used to hold the FP. 00562 // This needs saving / restoring in the epilogue / prologue. 00563 XFI->createFPSpillSlot(MF); 00564 } 00565 00566 void XCoreFrameLowering:: 00567 processFunctionBeforeFrameFinalized(MachineFunction &MF, 00568 RegScavenger *RS) const { 00569 assert(RS && "requiresRegisterScavenging failed"); 00570 MachineFrameInfo *MFI = MF.getFrameInfo(); 00571 const TargetRegisterClass *RC = &XCore::GRRegsRegClass; 00572 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 00573 // Reserve slots close to SP or frame pointer for Scavenging spills. 00574 // When using SP for small frames, we don't need any scratch registers. 00575 // When using SP for large frames, we may need 2 scratch registers. 00576 // When using FP, for large or small frames, we may need 1 scratch register. 00577 if (XFI->isLargeFrame(MF) || hasFP(MF)) 00578 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 00579 RC->getAlignment(), 00580 false)); 00581 if (XFI->isLargeFrame(MF) && !hasFP(MF)) 00582 RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 00583 RC->getAlignment(), 00584 false)); 00585 }