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