39 static inline bool isImmU6(
unsigned val) {
40 return val < (1 << 6);
44 return val < (1 << 16);
49 struct StackSlotInfo {
53 StackSlotInfo(
int f,
int o,
int r) : FI(f),
Offset(o),
Reg(r){};
58 return a.Offset < b.Offset;
67 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
68 .addCFIIndex(CFIIndex);
78 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
79 .addCFIIndex(CFIIndex);
89 BuildMI(MBB, MBBI, dl, TII.
get(TargetOpcode::CFI_INSTRUCTION))
90 .addCFIIndex(CFIIndex);
102 int &Adjusted,
int FrameSize,
bool emitFrameMoves) {
103 while (OffsetFromTop > Adjusted) {
104 assert(Adjusted < FrameSize &&
"OffsetFromTop is beyond FrameSize");
105 int remaining = FrameSize - Adjusted;
107 int Opcode =
isImmU6(OpImm) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
108 BuildMI(MBB, MBBI, dl, TII.
get(Opcode)).addImm(OpImm);
126 while (OffsetFromTop < RemainingAdj -
MaxImmU16) {
127 assert(RemainingAdj &&
"OffsetFromTop is beyond FrameSize");
129 int Opcode =
isImmU6(OpImm) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
130 BuildMI(MBB, MBBI, dl, TII.
get(Opcode), XCore::SP).addImm(OpImm);
131 RemainingAdj -= OpImm;
141 bool fetchLR,
bool fetchFP) {
196 for (
unsigned i = 0, e = SpillList.
size();
i != e; ++
i) {
197 assert(SpillList[
i].
Offset % 4 == 0 &&
"Misaligned stack offset");
198 assert(SpillList[
i].
Offset <= 0 &&
"Unexpected positive stack offset");
199 int OffsetFromTop = - SpillList[
i].Offset/4;
201 int Offset = RemainingAdj - OffsetFromTop;
202 int Opcode =
isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
203 BuildMI(MBB, MBBI, dl, TII.
get(Opcode), SpillList[
i].Reg)
226 assert(&MF.
front() == &MBB &&
"Shrink-wrapping not yet supported");
243 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
253 bool UseENTSP = saveLR && FrameSize
263 int Opcode =
isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
269 if (emitFrameMoves) {
281 for (
unsigned i = 0, e = SpillList.
size();
i != e; ++
i) {
282 assert(SpillList[
i].
Offset % 4 == 0 &&
"Misaligned stack offset");
283 assert(SpillList[
i].
Offset <= 0 &&
"Unexpected positive stack offset");
284 int OffsetFromTop = - SpillList[
i].Offset/4;
285 IfNeededExtSP(MBB, MBBI, dl, TII, OffsetFromTop, Adjusted, FrameSize,
287 int Offset = Adjusted - OffsetFromTop;
288 int Opcode =
isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
290 BuildMI(MBB, MBBI, dl, TII.get(Opcode))
295 if (emitFrameMoves) {
302 IfNeededExtSP(MBB, MBBI, dl, TII, FrameSize, Adjusted, FrameSize,
304 assert(Adjusted==FrameSize &&
"IfNeededExtSP has not completed adjustment");
308 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6),
FramePtr).addImm(0);
314 if (emitFrameMoves) {
333 assert(SpillList.
size()==2 &&
"Unexpected SpillList size");
336 SpillList[0].Offset);
339 SpillList[1].Offset);
351 unsigned RetOpcode = MBBI->getOpcode();
356 assert(RemainingAdj%4 == 0 &&
"Misaligned frame size");
371 unsigned EhStackReg = MBBI->getOperand(0).getReg();
372 unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
373 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
374 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
380 bool UseRETSP = restoreLR && RemainingAdj
399 assert(RetOpcode == XCore::RETSP_u6
400 || RetOpcode == XCore::RETSP_lu6);
401 int Opcode =
isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
403 .addImm(RemainingAdj);
404 for (
unsigned i = 3, e = MBBI->getNumOperands();
i < e; ++
i)
408 int Opcode =
isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
410 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
419 const std::vector<CalleeSavedInfo> &CSI,
430 if (MI != MBB.
end() && !MI->isDebugValue())
431 DL = MI->getDebugLoc();
433 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
434 it != CSI.end(); ++it) {
435 unsigned Reg = it->getReg();
436 assert(Reg != XCore::LR && !(Reg == XCore::R10 &&
hasFP(*MF)) &&
437 "LR & FP are always handled in emitPrologue");
443 if (emitFrameMoves) {
455 const std::vector<CalleeSavedInfo> &CSI,
459 bool AtStart = MI == MBB.
begin();
463 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
464 it != CSI.end(); ++it) {
465 unsigned Reg = it->getReg();
466 assert(Reg != XCore::LR && !(Reg == XCore::R10 &&
hasFP(*MF)) &&
467 "LR & FP are always handled in emitEpilogue");
472 "loadRegFromStackSlot didn't insert any code!");
501 Amount = (Amount+Align-1)/Align*Align;
510 errs() <<
"eliminateCallFramePseudoInstr size too big: "
517 if (Old.
getOpcode() == XCore::ADJCALLSTACKDOWN) {
518 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
522 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
563 SavedRegs.
reset(XCore::LR);
576 assert(RS &&
"requiresRegisterScavenging failed");
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int createLRSpillSlot(MachineFunction &MF)
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static const int MaxImmU16
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
static bool isImmU16(unsigned val)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
XCoreFrameLowering(const XCoreSubtarget &STI)
bool callsEHReturn() const
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
virtual unsigned getExceptionPointerRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, MachineMemOperand::Flags flags)
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned getSize() const
Return the size of the register in bytes, which is also the size of a stack slot allocated to hold a ...
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const HexagonInstrInfo * TII
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
const MachineBasicBlock & front() const
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, const Constant *PersonalityFn, const TargetLowering *TL)
Creates an ordered list of EH info register 'spills'.
const int * getEHSpillSlot() const
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
int createFPSpillSlot(MachineFunction &MF)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
static void GetSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo &MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP)
Creates an ordered list of registers that are spilled during the emitPrologue/emitEpilogue.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
unsigned getAlignment() const
Return the minimum required alignment for a register of this class.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, unsigned DRegNum, int Offset)
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const MachineOperand & getOperand(unsigned i) const
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
Load the specified register of the given register class from the specified stack frame index...
bool hasPersonalityFn() const
Check whether this function has a personality function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
const int * createEHSpillSlot(MachineFunction &MF)
XCoreFunctionInfo - This class is derived from MachineFunction private XCore target-specific informat...
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
Store the specified register of the given register class to the specified stack frame index...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
The memory access writes data.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool isLargeFrame(const MachineFunction &MF) const
int getFPSpillSlot() const
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
const MCContext & getContext() const
static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int Offset)
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
virtual const TargetLowering * getTargetLowering() const
Information about stack frame layout on the target.
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
int getLRSpillSlot() const
static bool isImmU6(unsigned val)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
AttributeSet getAttributes() const
Return the attribute list for this Function.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Flags
Flags values. These may be or'd together.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MCRegisterInfo * getRegisterInfo() const
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int &RemainingAdj, SmallVectorImpl< StackSlotInfo > &SpillList)
Restore clobbered registers with their spill slot value.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
bool callsUnwindInit() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, const AllocaInst *Alloca=nullptr)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
static void IfNeededExtSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &Adjusted, int FrameSize, bool emitFrameMoves)
The SP register is moved in steps of 'MaxImmU16' towards the bottom of the frame. ...
static const unsigned FramePtr
static void IfNeededLDAWSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, int OffsetFromTop, int &RemainingAdj)
The SP register is moved in steps of 'MaxImmU16' towards the top of the frame.
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MachineModuleInfo & getMMI() const
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
virtual unsigned getExceptionSelectorRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.