33 static inline bool isImmU6(
unsigned val) {
34 return val < (1 << 6);
38 return val < (1 << 16);
43 unsigned DstReg,
int Offset,
DebugLoc dl,
45 assert(Offset%4 == 0 &&
"Misaligned stack offset");
50 int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;
58 unsigned SrcReg,
int Offset,
DebugLoc dl,
60 assert(Offset%4 == 0 &&
"Misaligned stack offset");
65 int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6;
109 assert(FrameSize%4 == 0 &&
"Misaligned frame size");
112 bool isU6 =
isImmU6(FrameSize);
114 if (!isU6 && !
isImmU16(FrameSize)) {
123 bool LRSavedOnEntry =
false;
126 Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6;
129 LRSavedOnEntry =
true;
131 Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
133 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize);
135 if (emitFrameMoves) {
141 if (LRSavedOnEntry) {
149 storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII);
152 if (emitFrameMoves) {
164 storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl, TII);
167 if (emitFrameMoves) {
175 unsigned FramePtr = XCore::R10;
176 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0);
177 if (emitFrameMoves) {
187 if (emitFrameMoves) {
189 std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels =
191 for (
unsigned I = 0, E = SpillLabels.size();
I != E; ++
I) {
192 MCSymbol *SpillLabel = SpillLabels[
I].first;
214 unsigned FramePtr = XCore::R10;
215 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r))
222 assert(FrameSize%4 == 0 &&
"Misaligned frame size");
226 bool isU6 =
isImmU6(FrameSize);
228 if (!isU6 && !
isImmU16(FrameSize)) {
236 FPSpillOffset += FrameSize*4;
237 loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII);
244 LRSpillOffset += FrameSize*4;
253 assert(MBBI->getOpcode() == XCore::RETSP_u6
254 || MBBI->getOpcode() == XCore::RETSP_lu6);
255 int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6;
257 for (
unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i)
261 int Opcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
262 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize);
269 const std::vector<CalleeSavedInfo> &CSI,
281 if (MI != MBB.
end()) DL = MI->getDebugLoc();
283 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
284 it != CSI.end(); ++it) {
288 unsigned Reg = it->getReg();
291 it->getFrameIdx(), RC, TRI);
292 if (emitFrameMoves) {
303 const std::vector<CalleeSavedInfo> &CSI,
308 bool AtStart = MI == MBB.
begin();
312 for (std::vector<CalleeSavedInfo>::const_iterator it = CSI.begin();
313 it != CSI.end(); ++it) {
314 unsigned Reg = it->getReg();
318 assert(MI != MBB.
begin() &&
319 "loadRegFromStackSlot didn't insert any code!");
349 Amount = (Amount+Align-1)/Align*Align;
351 assert(Amount%4 == 0);
358 errs() <<
"eliminateCallFramePseudoInstr size too big: "
365 if (Old->
getOpcode() == XCore::ADJCALLSTACKDOWN) {
366 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
370 assert(Old->
getOpcode() == XCore::ADJCALLSTACKUP);
371 int Opcode = isU6 ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;
unsigned getStackAlignment() const
const MachineFunction * getParent() const
instr_iterator erase(instr_iterator I)
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number. Returns -1 if there is no equivalent va...
static bool isImmU16(unsigned val)
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, EVT VT=MVT::Other) const
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)
bool hasFP(const MachineFunction &MF) const
static void storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, int Offset, DebugLoc dl, const TargetInstrInfo &TII)
void setLRSpillSlot(int off)
const Function * getFunction() const
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA. Register remains the same, but offset is new...
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
unsigned getMaxAlignment() const
uint64_t getStackSize() const
MCSymbol * CreateTempSymbol()
const HexagonInstrInfo * TII
static void loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DstReg, int Offset, DebugLoc dl, const TargetInstrInfo &TII)
#define llvm_unreachable(msg)
bool DisableFramePointerElim(const MachineFunction &MF) const
Abstract Stack Frame Information.
const MachineInstrBuilder & addImm(int64_t Val) const
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
const MachineBasicBlock & front() const
static bool needsFrameMoves(const MachineFunction &MF)
Return whether to emit frame moves.
iterator getLastNonDebugInstr()
MCContext & getContext() const
void emitPrologue(MachineFunction &MF) const
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const
bundle_iterator< MachineInstr, instr_iterator > iterator
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
unsigned getAlignment() const
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA. From now on Register will be used instead of...
void setFPSpillSlot(int off)
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
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
const MCInstrDesc & get(unsigned Opcode) const
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
int64_t getObjectOffset(int ObjectIdx) const
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
virtual const TargetInstrInfo * getInstrInfo() const
int getFPSpillSlot() const
void addOperand(MachineFunction &MF, const MachineOperand &Op)
std::vector< std::pair< MCSymbol *, CalleeSavedInfo > > & getSpillLabels()
const MCContext & getContext() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS=NULL) const
void setPhysRegUnused(unsigned Reg)
MachineFrameInfo * getFrameInfo()
int getLRSpillSlot() const
static bool isImmU6(unsigned val)
AttributeSet getAttributes() const
Return the attribute list for this Function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
const MCRegisterInfo * getRegisterInfo() const
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP=false, const AllocaInst *Alloca=0)
MachineRegisterInfo & getRegInfo()
bool hasAttrSomewhere(Attribute::AttrKind Attr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
void addFrameInst(const MCCFIInstruction &Inst)
const TargetMachine & getTarget() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
virtual const TargetRegisterInfo * getRegisterInfo() const
bool hasVarSizedObjects() const
bool isPhysRegUsed(unsigned Reg) const
MachineModuleInfo & getMMI() const
const MCRegisterInfo & MRI
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable)
DebugLoc getDebugLoc() const