XCoreFrameLowering.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. //===-- XCoreFrameLowering.cpp - Frame info for XCore Target --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file contains XCore frame information that doesn't fit anywhere else
  11. // cleanly...
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "XCoreFrameLowering.h"
  15. #include "XCore.h"
  16. #include "XCoreInstrInfo.h"
  17. #include "XCoreMachineFunctionInfo.h"
  18. #include "XCoreSubtarget.h"
  19. #include "llvm/CodeGen/MachineFrameInfo.h"
  20. #include "llvm/CodeGen/MachineFunction.h"
  21. #include "llvm/CodeGen/MachineInstrBuilder.h"
  22. #include "llvm/CodeGen/MachineModuleInfo.h"
  23. #include "llvm/CodeGen/MachineRegisterInfo.h"
  24. #include "llvm/CodeGen/RegisterScavenging.h"
  25. #include "llvm/IR/DataLayout.h"
  26. #include "llvm/IR/Function.h"
  27. #include "llvm/Support/ErrorHandling.h"
  28. #include "llvm/Target/TargetLowering.h"
  29. #include "llvm/Target/TargetOptions.h"
  30. #include <algorithm> // std::sort
  31. using namespace llvm;
  32. static const unsigned FramePtr = XCore::R10;
  33. static const int MaxImmU16 = (1<<16) - 1;
  34. // helper functions. FIXME: Eliminate.
  35. static inline bool isImmU6(unsigned val) {
  36. return val < (1 << 6);
  37. }
  38. static inline bool isImmU16(unsigned val) {
  39. return val < (1 << 16);
  40. }
  41. // Helper structure with compare function for handling stack slots.
  42. namespace {
  43. struct StackSlotInfo {
  44. int FI;
  45. int Offset;
  46. unsigned Reg;
  47. StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){};
  48. };
  49. } // end anonymous namespace
  50. static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) {
  51. return a.Offset < b.Offset;
  52. }
  53. static void EmitDefCfaRegister(MachineBasicBlock &MBB,
  54. MachineBasicBlock::iterator MBBI,
  55. const DebugLoc &dl, const TargetInstrInfo &TII,
  56. MachineFunction &MF, unsigned DRegNum) {
  57. unsigned CFIIndex = MF.addFrameInst(
  58. MCCFIInstruction::createDefCfaRegister(nullptr, DRegNum));
  59. BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
  60. .addCFIIndex(CFIIndex);
  61. }
  62. static void EmitDefCfaOffset(MachineBasicBlock &MBB,
  63. MachineBasicBlock::iterator MBBI,
  64. const DebugLoc &dl, const TargetInstrInfo &TII,
  65. int Offset) {
  66. MachineFunction &MF = *MBB.getParent();
  67. unsigned CFIIndex =
  68. MF.addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
  69. BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
  70. .addCFIIndex(CFIIndex);
  71. }
  72. static void EmitCfiOffset(MachineBasicBlock &MBB,
  73. MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
  74. const TargetInstrInfo &TII, unsigned DRegNum,
  75. int Offset) {
  76. MachineFunction &MF = *MBB.getParent();
  77. unsigned CFIIndex = MF.addFrameInst(
  78. MCCFIInstruction::createOffset(nullptr, DRegNum, Offset));
  79. BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
  80. .addCFIIndex(CFIIndex);
  81. }
  82. /// The SP register is moved in steps of 'MaxImmU16' towards the bottom of the
  83. /// frame. During these steps, it may be necessary to spill registers.
  84. /// IfNeededExtSP emits the necessary EXTSP instructions to move the SP only
  85. /// as far as to make 'OffsetFromBottom' reachable using an STWSP_lru6.
  86. /// \param OffsetFromTop the spill offset from the top of the frame.
  87. /// \param [in,out] Adjusted the current SP offset from the top of the frame.
  88. static void IfNeededExtSP(MachineBasicBlock &MBB,
  89. MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
  90. const TargetInstrInfo &TII, int OffsetFromTop,
  91. int &Adjusted, int FrameSize, bool emitFrameMoves) {
  92. while (OffsetFromTop > Adjusted) {
  93. assert(Adjusted < FrameSize && "OffsetFromTop is beyond FrameSize");
  94. int remaining = FrameSize - Adjusted;
  95. int OpImm = (remaining > MaxImmU16) ? MaxImmU16 : remaining;
  96. int Opcode = isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
  97. BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(OpImm);
  98. Adjusted += OpImm;
  99. if (emitFrameMoves)
  100. EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
  101. }
  102. }
  103. /// The SP register is moved in steps of 'MaxImmU16' towards the top of the
  104. /// frame. During these steps, it may be necessary to re-load registers.
  105. /// IfNeededLDAWSP emits the necessary LDAWSP instructions to move the SP only
  106. /// as far as to make 'OffsetFromTop' reachable using an LDAWSP_lru6.
  107. /// \param OffsetFromTop the spill offset from the top of the frame.
  108. /// \param [in,out] RemainingAdj the current SP offset from the top of the
  109. /// frame.
  110. static void IfNeededLDAWSP(MachineBasicBlock &MBB,
  111. MachineBasicBlock::iterator MBBI, const DebugLoc &dl,
  112. const TargetInstrInfo &TII, int OffsetFromTop,
  113. int &RemainingAdj) {
  114. while (OffsetFromTop < RemainingAdj - MaxImmU16) {
  115. assert(RemainingAdj && "OffsetFromTop is beyond FrameSize");
  116. int OpImm = (RemainingAdj > MaxImmU16) ? MaxImmU16 : RemainingAdj;
  117. int Opcode = isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
  118. BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(OpImm);
  119. RemainingAdj -= OpImm;
  120. }
  121. }
  122. /// Creates an ordered list of registers that are spilled
  123. /// during the emitPrologue/emitEpilogue.
  124. /// Registers are ordered according to their frame offset.
  125. /// As offsets are negative, the largest offsets will be first.
  126. static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
  127. MachineFrameInfo &MFI, XCoreFunctionInfo *XFI,
  128. bool fetchLR, bool fetchFP) {
  129. if (fetchLR) {
  130. int Offset = MFI.getObjectOffset(XFI->getLRSpillSlot());
  131. SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(),
  132. Offset,
  133. XCore::LR));
  134. }
  135. if (fetchFP) {
  136. int Offset = MFI.getObjectOffset(XFI->getFPSpillSlot());
  137. SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(),
  138. Offset,
  139. FramePtr));
  140. }
  141. std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
  142. }
  143. /// Creates an ordered list of EH info register 'spills'.
  144. /// These slots are only used by the unwinder and calls to llvm.eh.return().
  145. /// Registers are ordered according to their frame offset.
  146. /// As offsets are negative, the largest offsets will be first.
  147. static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList,
  148. MachineFrameInfo &MFI, XCoreFunctionInfo *XFI,
  149. const Constant *PersonalityFn,
  150. const TargetLowering *TL) {
  151. assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots");
  152. const int *EHSlot = XFI->getEHSpillSlot();
  153. SpillList.push_back(
  154. StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[0]),
  155. TL->getExceptionPointerRegister(PersonalityFn)));
  156. SpillList.push_back(
  157. StackSlotInfo(EHSlot[0], MFI.getObjectOffset(EHSlot[1]),
  158. TL->getExceptionSelectorRegister(PersonalityFn)));
  159. std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset);
  160. }
  161. static MachineMemOperand *getFrameIndexMMO(MachineBasicBlock &MBB,
  162. int FrameIndex,
  163. MachineMemOperand::Flags flags) {
  164. MachineFunction *MF = MBB.getParent();
  165. const MachineFrameInfo &MFI = MF->getFrameInfo();
  166. MachineMemOperand *MMO = MF->getMachineMemOperand(
  167. MachinePointerInfo::getFixedStack(*MF, FrameIndex), flags,
  168. MFI.getObjectSize(FrameIndex), MFI.getObjectAlignment(FrameIndex));
  169. return MMO;
  170. }
  171. /// Restore clobbered registers with their spill slot value.
  172. /// The SP will be adjusted at the same time, thus the SpillList must be ordered
  173. /// with the largest (negative) offsets first.
  174. static void RestoreSpillList(MachineBasicBlock &MBB,
  175. MachineBasicBlock::iterator MBBI,
  176. const DebugLoc &dl, const TargetInstrInfo &TII,
  177. int &RemainingAdj,
  178. SmallVectorImpl<StackSlotInfo> &SpillList) {
  179. for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
  180. assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
  181. assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
  182. int OffsetFromTop = - SpillList[i].Offset/4;
  183. IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj);
  184. int Offset = RemainingAdj - OffsetFromTop;
  185. int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
  186. BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg)
  187. .addImm(Offset)
  188. .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
  189. MachineMemOperand::MOLoad));
  190. }
  191. }
  192. //===----------------------------------------------------------------------===//
  193. // XCoreFrameLowering:
  194. //===----------------------------------------------------------------------===//
  195. XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
  196. : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0) {
  197. // Do nothing
  198. }
  199. bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
  200. return MF.getTarget().Options.DisableFramePointerElim(MF) ||
  201. MF.getFrameInfo().hasVarSizedObjects();
  202. }
  203. void XCoreFrameLowering::emitPrologue(MachineFunction &MF,
  204. MachineBasicBlock &MBB) const {
  205. assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
  206. MachineBasicBlock::iterator MBBI = MBB.begin();
  207. MachineFrameInfo &MFI = MF.getFrameInfo();
  208. MachineModuleInfo *MMI = &MF.getMMI();
  209. const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
  210. const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
  211. XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
  212. // Debug location must be unknown since the first debug location is used
  213. // to determine the end of the prologue.
  214. DebugLoc dl;
  215. if (MFI.getMaxAlignment() > getStackAlignment())
  216. report_fatal_error("emitPrologue unsupported alignment: "
  217. + Twine(MFI.getMaxAlignment()));
  218. const AttributeSet &PAL = MF.getFunction()->getAttributes();
  219. if (PAL.hasAttrSomewhere(Attribute::Nest))
  220. BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
  221. // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack().
  222. // Work out frame sizes.
  223. // We will adjust the SP in stages towards the final FrameSize.
  224. assert(MFI.getStackSize()%4 == 0 && "Misaligned frame size");
  225. const int FrameSize = MFI.getStackSize() / 4;
  226. int Adjusted = 0;
  227. bool saveLR = XFI->hasLRSpillSlot();
  228. bool UseENTSP = saveLR && FrameSize
  229. && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
  230. if (UseENTSP)
  231. saveLR = false;
  232. bool FP = hasFP(MF);
  233. bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF);
  234. if (UseENTSP) {
  235. // Allocate space on the stack at the same time as saving LR.
  236. Adjusted = (FrameSize > MaxImmU16) ? MaxImmU16 : FrameSize;
  237. int Opcode = isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
  238. MBB.addLiveIn(XCore::LR);
  239. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode));
  240. MIB.addImm(Adjusted);
  241. MIB->addRegisterKilled(XCore::LR, MF.getSubtarget().getRegisterInfo(),
  242. true);
  243. if (emitFrameMoves) {
  244. EmitDefCfaOffset(MBB, MBBI, dl, TII, Adjusted*4);
  245. unsigned DRegNum = MRI->getDwarfRegNum(XCore::LR, true);
  246. EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, 0);
  247. }
  248. }
  249. // If necessary, save LR and FP to the stack, as we EXTSP.
  250. SmallVector<StackSlotInfo,2> SpillList;
  251. GetSpillList(SpillList, MFI, XFI, saveLR, FP);
  252. // We want the nearest (negative) offsets first, so reverse list.
  253. std::reverse(SpillList.begin(), SpillList.end());
  254. for (unsigned i = 0, e = SpillList.size(); i != e; ++i) {
  255. assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset");
  256. assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset");
  257. int OffsetFromTop = - SpillList[i].Offset/4;
  258. IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
  259. emitFrameMoves);
  260. int Offset = Adjusted - OffsetFromTop;
  261. int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
  262. MBB.addLiveIn(SpillList[i].Reg);
  263. BuildMI(MBB, MBBI, dl, TII.get(Opcode))
  264. .addReg(SpillList[i].Reg, RegState::Kill)
  265. .addImm(Offset)
  266. .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI,
  267. MachineMemOperand::MOStore));
  268. if (emitFrameMoves) {
  269. unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true);
  270. EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
  271. }
  272. }
  273. // Complete any remaining Stack adjustment.
  274. IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
  275. emitFrameMoves);
  276. assert(Adjusted==FrameSize && "IfNeededExtSP has not completed adjustment");
  277. if (FP) {
  278. // Set the FP from the SP.
  279. BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
  280. if (emitFrameMoves)
  281. EmitDefCfaRegister(MBB, MBBI, dl, TII, MF,
  282. MRI->getDwarfRegNum(FramePtr, true));
  283. }
  284. if (emitFrameMoves) {
  285. // Frame moves for callee saved.
  286. for (const auto &SpillLabel : XFI->getSpillLabels()) {
  287. MachineBasicBlock::iterator Pos = SpillLabel.first;
  288. ++Pos;
  289. const CalleeSavedInfo &CSI = SpillLabel.second;
  290. int Offset = MFI.getObjectOffset(CSI.getFrameIdx());
  291. unsigned DRegNum = MRI->getDwarfRegNum(CSI.getReg(), true);
  292. EmitCfiOffset(MBB, Pos, dl, TII, DRegNum, Offset);
  293. }
  294. if (XFI->hasEHSpillSlot()) {
  295. // The unwinder requires stack slot & CFI offsets for the exception info.
  296. // We do not save/spill these registers.
  297. const Function *Fn = MF.getFunction();
  298. const Constant *PersonalityFn =
  299. Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
  300. SmallVector<StackSlotInfo, 2> SpillList;
  301. GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
  302. MF.getSubtarget().getTargetLowering());
  303. assert(SpillList.size()==2 && "Unexpected SpillList size");
  304. EmitCfiOffset(MBB, MBBI, dl, TII,
  305. MRI->getDwarfRegNum(SpillList[0].Reg, true),
  306. SpillList[0].Offset);
  307. EmitCfiOffset(MBB, MBBI, dl, TII,
  308. MRI->getDwarfRegNum(SpillList[1].Reg, true),
  309. SpillList[1].Offset);
  310. }
  311. }
  312. }
  313. void XCoreFrameLowering::emitEpilogue(MachineFunction &MF,
  314. MachineBasicBlock &MBB) const {
  315. MachineFrameInfo &MFI = MF.getFrameInfo();
  316. MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
  317. const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
  318. XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
  319. DebugLoc dl = MBBI->getDebugLoc();
  320. unsigned RetOpcode = MBBI->getOpcode();
  321. // Work out frame sizes.
  322. // We will adjust the SP in stages towards the final FrameSize.
  323. int RemainingAdj = MFI.getStackSize();
  324. assert(RemainingAdj%4 == 0 && "Misaligned frame size");
  325. RemainingAdj /= 4;
  326. if (RetOpcode == XCore::EH_RETURN) {
  327. // 'Restore' the exception info the unwinder has placed into the stack
  328. // slots.
  329. const Function *Fn = MF.getFunction();
  330. const Constant *PersonalityFn =
  331. Fn->hasPersonalityFn() ? Fn->getPersonalityFn() : nullptr;
  332. SmallVector<StackSlotInfo, 2> SpillList;
  333. GetEHSpillList(SpillList, MFI, XFI, PersonalityFn,
  334. MF.getSubtarget().getTargetLowering());
  335. RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
  336. // Return to the landing pad.
  337. unsigned EhStackReg = MBBI->getOperand(0).getReg();
  338. unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
  339. BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
  340. BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
  341. MBB.erase(MBBI); // Erase the previous return instruction.
  342. return;
  343. }
  344. bool restoreLR = XFI->hasLRSpillSlot();
  345. bool UseRETSP = restoreLR && RemainingAdj
  346. && (MFI.getObjectOffset(XFI->getLRSpillSlot()) == 0);
  347. if (UseRETSP)
  348. restoreLR = false;
  349. bool FP = hasFP(MF);
  350. if (FP) // Restore the stack pointer.
  351. BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
  352. // If necessary, restore LR and FP from the stack, as we EXTSP.
  353. SmallVector<StackSlotInfo,2> SpillList;
  354. GetSpillList(SpillList, MFI, XFI, restoreLR, FP);
  355. RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList);
  356. if (RemainingAdj) {
  357. // Complete all but one of the remaining Stack adjustments.
  358. IfNeededLDAWSP(MBB, MBBI, dl, TII, 0, RemainingAdj);
  359. if (UseRETSP) {
  360. // Fold prologue into return instruction
  361. assert(RetOpcode == XCore::RETSP_u6
  362. || RetOpcode == XCore::RETSP_lu6);
  363. int Opcode = isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
  364. MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode))
  365. .addImm(RemainingAdj);
  366. for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
  367. MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands
  368. MBB.erase(MBBI); // Erase the previous return instruction.
  369. } else {
  370. int Opcode = isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
  371. XCore::LDAWSP_lru6;
  372. BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
  373. // Don't erase the return instruction.
  374. }
  375. } // else Don't erase the return instruction.
  376. }
  377. bool XCoreFrameLowering::
  378. spillCalleeSavedRegisters(MachineBasicBlock &MBB,
  379. MachineBasicBlock::iterator MI,
  380. const std::vector<CalleeSavedInfo> &CSI,
  381. const TargetRegisterInfo *TRI) const {
  382. if (CSI.empty())
  383. return true;
  384. MachineFunction *MF = MBB.getParent();
  385. const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
  386. XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
  387. bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
  388. DebugLoc DL;
  389. if (MI != MBB.end() && !MI->isDebugValue())
  390. DL = MI->getDebugLoc();
  391. for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
  392. it != CSI.end(); ++it) {
  393. unsigned Reg = it->getReg();
  394. assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
  395. "LR & FP are always handled in emitPrologue");
  396. // Add the callee-saved register as live-in. It's killed at the spill.
  397. MBB.addLiveIn(Reg);
  398. const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
  399. TII.storeRegToStackSlot(MBB, MI, Reg, true, it->getFrameIdx(), RC, TRI);
  400. if (emitFrameMoves) {
  401. auto Store = MI;
  402. --Store;
  403. XFI->getSpillLabels().push_back(std::make_pair(Store, *it));
  404. }
  405. }
  406. return true;
  407. }
  408. bool XCoreFrameLowering::
  409. restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
  410. MachineBasicBlock::iterator MI,
  411. const std::vector<CalleeSavedInfo> &CSI,
  412. const TargetRegisterInfo *TRI) const{
  413. MachineFunction *MF = MBB.getParent();
  414. const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
  415. bool AtStart = MI == MBB.begin();
  416. MachineBasicBlock::iterator BeforeI = MI;
  417. if (!AtStart)
  418. --BeforeI;
  419. for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
  420. it != CSI.end(); ++it) {
  421. unsigned Reg = it->getReg();
  422. assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
  423. "LR & FP are always handled in emitEpilogue");
  424. const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
  425. TII.loadRegFromStackSlot(MBB, MI, Reg, it->getFrameIdx(), RC, TRI);
  426. assert(MI != MBB.begin() &&
  427. "loadRegFromStackSlot didn't insert any code!");
  428. // Insert in reverse order. loadRegFromStackSlot can insert multiple
  429. // instructions.
  430. if (AtStart)
  431. MI = MBB.begin();
  432. else {
  433. MI = BeforeI;
  434. ++MI;
  435. }
  436. }
  437. return true;
  438. }
  439. // This function eliminates ADJCALLSTACKDOWN,
  440. // ADJCALLSTACKUP pseudo instructions
  441. MachineBasicBlock::iterator XCoreFrameLowering::eliminateCallFramePseudoInstr(
  442. MachineFunction &MF, MachineBasicBlock &MBB,
  443. MachineBasicBlock::iterator I) const {
  444. const XCoreInstrInfo &TII = *MF.getSubtarget<XCoreSubtarget>().getInstrInfo();
  445. if (!hasReservedCallFrame(MF)) {
  446. // Turn the adjcallstackdown instruction into 'extsp <amt>' and the
  447. // adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
  448. MachineInstr &Old = *I;
  449. uint64_t Amount = Old.getOperand(0).getImm();
  450. if (Amount != 0) {
  451. // We need to keep the stack aligned properly. To do this, we round the
  452. // amount of space needed for the outgoing arguments up to the next
  453. // alignment boundary.
  454. unsigned Align = getStackAlignment();
  455. Amount = (Amount+Align-1)/Align*Align;
  456. assert(Amount%4 == 0);
  457. Amount /= 4;
  458. bool isU6 = isImmU6(Amount);
  459. if (!isU6 && !isImmU16(Amount)) {
  460. // FIX could emit multiple instructions in this case.
  461. #ifndef NDEBUG
  462. errs() << "eliminateCallFramePseudoInstr size too big: "
  463. << Amount << "\n";
  464. #endif
  465. llvm_unreachable(nullptr);
  466. }
  467. MachineInstr *New;
  468. if (Old.getOpcode() == XCore::ADJCALLSTACKDOWN) {
  469. int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
  470. New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode)).addImm(Amount);
  471. } else {
  472. assert(Old.getOpcode() == XCore::ADJCALLSTACKUP);
  473. int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
  474. New = BuildMI(MF, Old.getDebugLoc(), TII.get(Opcode), XCore::SP)
  475. .addImm(Amount);
  476. }
  477. // Replace the pseudo instruction with a new instruction...
  478. MBB.insert(I, New);
  479. }
  480. }
  481. return MBB.erase(I);
  482. }
  483. void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF,
  484. BitVector &SavedRegs,
  485. RegScavenger *RS) const {
  486. TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
  487. XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
  488. const MachineRegisterInfo &MRI = MF.getRegInfo();
  489. bool LRUsed = MRI.isPhysRegModified(XCore::LR);
  490. if (!LRUsed && !MF.getFunction()->isVarArg() &&
  491. MF.getFrameInfo().estimateStackSize(MF))
  492. // If we need to extend the stack it is more efficient to use entsp / retsp.
  493. // We force the LR to be saved so these instructions are used.
  494. LRUsed = true;
  495. if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
  496. // The unwinder expects to find spill slots for the exception info regs R0
  497. // & R1. These are used during llvm.eh.return() to 'restore' the exception
  498. // info. N.B. we do not spill or restore R0, R1 during normal operation.
  499. XFI->createEHSpillSlot(MF);
  500. // As we will have a stack, we force the LR to be saved.
  501. LRUsed = true;
  502. }
  503. if (LRUsed) {
  504. // We will handle the LR in the prologue/epilogue
  505. // and allocate space on the stack ourselves.
  506. SavedRegs.reset(XCore::LR);
  507. XFI->createLRSpillSlot(MF);
  508. }
  509. if (hasFP(MF))
  510. // A callee save register is used to hold the FP.
  511. // This needs saving / restoring in the epilogue / prologue.
  512. XFI->createFPSpillSlot(MF);
  513. }
  514. void XCoreFrameLowering::
  515. processFunctionBeforeFrameFinalized(MachineFunction &MF,
  516. RegScavenger *RS) const {
  517. assert(RS && "requiresRegisterScavenging failed");
  518. MachineFrameInfo &MFI = MF.getFrameInfo();
  519. const TargetRegisterClass *RC = &XCore::GRRegsRegClass;
  520. XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
  521. // Reserve slots close to SP or frame pointer for Scavenging spills.
  522. // When using SP for small frames, we don't need any scratch registers.
  523. // When using SP for large frames, we may need 2 scratch registers.
  524. // When using FP, for large or small frames, we may need 1 scratch register.
  525. if (XFI->isLargeFrame(MF) || hasFP(MF))
  526. RS->addScavengingFrameIndex(MFI.CreateStackObject(RC->getSize(),
  527. RC->getAlignment(),
  528. false));
  529. if (XFI->isLargeFrame(MF) && !hasFP(MF))
  530. RS->addScavengingFrameIndex(MFI.CreateStackObject(RC->getSize(),
  531. RC->getAlignment(),
  532. false));
  533. }