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;
69 .addCFIIndex(CFIIndex);
79 .addCFIIndex(CFIIndex);
85 unsigned DRegNum,
int Offset) {
89 .addCFIIndex(CFIIndex);
101 int OffsetFromTop,
int &Adjusted,
int FrameSize,
102 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) {
164 assert(XFI->
hasEHSpillSlot() &&
"There are no EH register spill slots");
166 SpillList.
push_back(StackSlotInfo(EHSlot[0],
169 SpillList.
push_back(StackSlotInfo(EHSlot[0],
195 for (
unsigned i = 0, e = SpillList.
size(); i != e; ++i) {
196 assert(SpillList[i].Offset % 4 == 0 &&
"Misaligned stack offset");
197 assert(SpillList[i].Offset <= 0 &&
"Unexpected positive stack offset");
198 int OffsetFromTop = - SpillList[i].Offset/4;
200 int Offset = RemainingAdj - OffsetFromTop;
201 int Opcode =
isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
202 BuildMI(MBB, MBBI, dl, TII.
get(Opcode), SpillList[i].Reg)
225 assert(&MF.
front() == &MBB &&
"Shrink-wrapping not yet supported");
242 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0);
247 assert(MFI->
getStackSize()%4 == 0 &&
"Misaligned frame size");
252 bool UseENTSP = saveLR && FrameSize
262 int Opcode =
isImmU6(Adjusted) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
268 if (emitFrameMoves) {
279 std::reverse(SpillList.
begin(), SpillList.
end());
280 for (
unsigned i = 0, e = SpillList.
size(); i != e; ++i) {
281 assert(SpillList[i].Offset % 4 == 0 &&
"Misaligned stack offset");
282 assert(SpillList[i].Offset <= 0 &&
"Unexpected positive stack offset");
283 int OffsetFromTop = - SpillList[i].Offset/4;
284 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize,
286 int Offset = Adjusted - OffsetFromTop;
287 int Opcode =
isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
289 BuildMI(MBB, MBBI, dl, TII.get(Opcode))
294 if (emitFrameMoves) {
296 EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillList[i].Offset);
301 IfNeededExtSP(MBB, MBBI, dl, TII, MMI, FrameSize, Adjusted, FrameSize,
303 assert(Adjusted==FrameSize &&
"IfNeededExtSP has not completed adjustment");
307 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6),
FramePtr).addImm(0);
313 if (emitFrameMoves) {
329 assert(SpillList.
size()==2 &&
"Unexpected SpillList size");
332 SpillList[0].Offset);
335 SpillList[1].Offset);
347 unsigned RetOpcode = MBBI->getOpcode();
352 assert(RemainingAdj%4 == 0 &&
"Misaligned frame size");
363 unsigned EhStackReg = MBBI->getOperand(0).getReg();
364 unsigned EhHandlerReg = MBBI->getOperand(1).getReg();
365 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(EhStackReg);
366 BuildMI(MBB, MBBI, dl, TII.get(XCore::BAU_1r)).addReg(EhHandlerReg);
372 bool UseRETSP = restoreLR && RemainingAdj
391 assert(RetOpcode == XCore::RETSP_u6
392 || RetOpcode == XCore::RETSP_lu6);
393 int Opcode =
isImmU6(RemainingAdj) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
395 .addImm(RemainingAdj);
396 for (
unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
400 int Opcode =
isImmU6(RemainingAdj) ? XCore::LDAWSP_ru6 :
402 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(RemainingAdj);
411 const std::vector<CalleeSavedInfo> &CSI,
422 if (MI != MBB.
end() && !MI->isDebugValue())
423 DL = MI->getDebugLoc();
425 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
426 it != CSI.end(); ++it) {
427 unsigned Reg = it->getReg();
428 assert(Reg != XCore::LR && !(Reg == XCore::R10 &&
hasFP(*MF)) &&
429 "LR & FP are always handled in emitPrologue");
435 if (emitFrameMoves) {
447 const std::vector<CalleeSavedInfo> &CSI,
451 bool AtStart = MI == MBB.
begin();
455 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
456 it != CSI.end(); ++it) {
457 unsigned Reg = it->getReg();
458 assert(Reg != XCore::LR && !(Reg == XCore::R10 &&
hasFP(*MF)) &&
459 "LR & FP are always handled in emitEpilogue");
463 assert(MI != MBB.
begin() &&
464 "loadRegFromStackSlot didn't insert any code!");
493 Amount = (Amount+Align-1)/Align*Align;
495 assert(Amount%4 == 0);
502 errs() <<
"eliminateCallFramePseudoInstr size too big: "
509 if (Old->
getOpcode() == XCore::ADJCALLSTACKDOWN) {
510 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
514 assert(Old->
getOpcode() == XCore::ADJCALLSTACKUP);
515 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
556 SavedRegs.
reset(XCore::LR);
569 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)
The memory access reads data.
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
static const int MaxImmU16
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
The memory access writes data.
static bool isImmU16(unsigned val)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isPhysRegModified(unsigned PhysReg) const
Return true if the specified register is modified in this function.
XCoreFrameLowering(const XCoreSubtarget &STI)
Nested function static chain.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
std::vector< std::pair< MachineBasicBlock::iterator, CalleeSavedInfo > > & getSpillLabels()
static void EmitDefCfaOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, int Offset)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, SmallVectorImpl< StackSlotInfo > &SpillList)
Restore clobbered registers with their spill slot value.
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
static void GetEHSpillList(SmallVectorImpl< StackSlotInfo > &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, const TargetLowering *TL)
Creates an ordered list of EH info register 'spills'.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
static void IfNeededLDAWSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int OffsetFromTop, int &RemainingAdj)
The SP register is moved in steps of 'MaxImmU16' towards the top of the frame.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
getFixedStack - Return a MachinePointerInfo record that refers to the the specified FrameIndex...
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
eliminateCallFramePseudoInstr - This method is called during prolog/epilog code insertion to eliminat...
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
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
MachineMemOperand - 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.
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
bool callsUnwindInit() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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...
Reg
All possible values of the reg field in the ModR/M byte.
static void IfNeededExtSP(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, int OffsetFromTop, int &Adjusted, int FrameSize, bool emitFrameMoves)
The SP register is moved in steps of 'MaxImmU16' towards the bottom of the frame. ...
static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, unsigned DRegNum)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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.
const int * getEHSpillSlot() const
unsigned LLVM_ATTRIBUTE_UNUSED_RESULT addFrameInst(const MCCFIInstruction &Inst)
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()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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.
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getAlignment() const
getAlignment - 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.
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...
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.
static void EmitCfiOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, MachineModuleInfo *MMI, unsigned DRegNum, int Offset)
const int * createEHSpillSlot(MachineFunction &MF)
static MachineMemOperand * getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
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...
unsigned getExceptionPointerRegister() const
If a physical register, this returns the register that receives the exception address on entry to a l...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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.
bool callsEHReturn() const
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
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
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.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
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...
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
getMinimalPhysRegClass - Returns the Register Class of a physical register of the given type...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
const MCRegisterInfo * getRegisterInfo() const
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool hasAttrSomewhere(Attribute::AttrKind Attr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
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.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
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...
virtual const TargetInstrInfo * getInstrInfo() const
static const unsigned FramePtr
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
unsigned getExceptionSelectorRegister() const
If a physical register, this returns the register that receives the exception typeid on entry to a la...
static bool CompareSSIOffset(const StackSlotInfo &a, const StackSlotInfo &b)
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.
MachineModuleInfo - This class contains meta information specific to a module.
This file describes how to lower LLVM code to machine code.