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) {
297 EmitCfiOffset(MBB, MBBI, dl, TII, DRegNum, SpillList[i].Offset);
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
387 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr);
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->isDebugInstr())
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 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");
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
int createLRSpillSlot(MachineFunction &MF)
static const int MaxImmU16
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
This class represents lattice values for constants.
XCoreFrameLowering(const XCoreSubtarget &STI)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
virtual const TargetLowering * getTargetLowering() const
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
unsigned const TargetRegisterInfo * TRI
MachineModuleInfo & getMMI() const
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, MachineMemOperand::Flags flags)
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
unsigned getSpillAlignment(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class...
A description of a memory reference used in the backend.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const HexagonInstrInfo * TII
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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...
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'.
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
const MCContext & getContext() const
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
AttributeList getAttributes() const
Return the attribute list for this Function.
bool hasPersonalityFn() const
Check whether this function has a personality function.
virtual const TargetInstrInfo * getInstrInfo() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
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.
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...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
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
virtual unsigned getExceptionPointerRegister(const Constant *PersonalityFn) const
If a physical register, this returns the register that receives the exception address on entry to an ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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()
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...
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
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...
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...
const MachineBasicBlock & front() const
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &dl, const TargetInstrInfo &TII, MachineFunction &MF, unsigned DRegNum)
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int getLRSpillSlot() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
void sort(IteratorTy Start, IteratorTy End)
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 restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
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 estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Information about stack frame layout on the target.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
bool callsUnwindInit() const
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...
static bool isImmU6(unsigned val)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool callsEHReturn() const
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
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...
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.
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.
const int * getEHSpillSlot() const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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 MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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...
OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin...
bool isLargeFrame(const MachineFunction &MF) const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Constant * getPersonalityFn() const
Get the personality function associated with this function.
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.
int getFPSpillSlot() const
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const MachineOperand & getOperand(unsigned i) const
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
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...
This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.