34 uint64_t &Residual)
const {
43 Residual = Total - Initial;
61 uint64_t NumInitialBytes, NumResidualBytes;
89 emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, -NumInitialBytes,
92 if (NeedsFrameMoves && NumInitialBytes) {
108 bool FPNeedsSetting =
hasFP(MF);
109 for (; MBBI != MBB.end(); ++MBBI) {
114 if (FPNeedsSetting && MBBI->getOpcode() == AArch64::LSPair64_STR
115 && MBBI->getOperand(0).getReg() == AArch64::X29) {
116 int64_t X29FrameIdx = MBBI->getOperand(2).getIndex();
120 emitRegUpdate(MBB, MBBI, DL, TII, AArch64::X29, AArch64::XSP,
131 if (NeedsFrameMoves) {
140 FPNeedsSetting =
false;
147 assert(!FPNeedsSetting &&
"Frame pointer couldn't be set");
149 emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, -NumResidualBytes,
155 if (!NeedsFrameMoves)
162 if (!
hasFP(MF) && NumResidualBytes) {
169 unsigned Offset = NumResidualBytes + NumInitialBytes;
183 for (std::vector<CalleeSavedInfo>::const_iterator
I = CSI.begin(),
184 E = CSI.end();
I != E; ++
I) {
202 unsigned RetOpcode = MBBI->getOpcode();
207 uint64_t NumResidualBytes = MFI.
getStackSize() - NumInitialBytes;
208 uint64_t ArgumentPopSize = 0;
209 if (RetOpcode == AArch64::TC_RETURNdi ||
210 RetOpcode == AArch64::TC_RETURNxi) {
215 if (RetOpcode == AArch64::TC_RETURNdi) {
216 MIB =
BuildMI(MBB, MBBI, DL, TII.
get(AArch64::TAIL_Bimm));
221 assert(JumpTarget.
isSymbol() &&
"unexpected tail call destination");
226 assert(RetOpcode == AArch64::TC_RETURNxi && JumpTarget.
isReg()
227 &&
"Unexpected tail call");
229 MIB =
BuildMI(MBB, MBBI, DL, TII.
get(AArch64::TAIL_BRx));
235 for (
unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
247 ArgumentPopSize = StackAdjust.
getImm();
256 assert(NumInitialBytes % 16 == 0 && NumResidualBytes % 16 == 0
257 &&
"refusing to adjust stack by misaligned amt");
266 MinCSFI = CSI[0].getFrameIdx();
267 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
273 if (NumInitialBytes + ArgumentPopSize != 0) {
275 NumInitialBytes + ArgumentPopSize);
286 while (MBBI != MBB.
begin()) {
290 for (FrameOp = 0; FrameOp < MBBI->getNumOperands(); ++FrameOp) {
291 if (MBBI->getOperand(FrameOp).isFI())
297 if (FrameOp == MBBI->getNumOperands())
301 int FrameIdx = MBBI->getOperand(FrameOp).getIndex();
302 if (FrameIdx < MinCSFI || FrameIdx > MaxCSFI)
305 FirstEpilogue = MBBI;
309 int64_t StaticFrameBase;
312 AArch64::XSP, AArch64::X29, AArch64::NoRegister,
315 emitSPUpdate(MBB, FirstEpilogue, DL,TII, AArch64::X16, NumResidualBytes);
324 bool IsCalleeSaveOp)
const {
332 &&
"callee-saved register in unexpected place");
338 if (IsCalleeSaveOp) {
339 FrameReg = AArch64::XSP;
343 FrameReg = AArch64::X29;
346 FrameReg = AArch64::XSP;
347 FrameRegPos = -
static_cast<int64_t
>(MFI->getStackSize()) + SPAdj;
350 return TopOfFrameOffset - FrameRegPos;
382 uint16_t ExtraReg = AArch64::NoRegister;
384 for (
unsigned i = 0; CSRegs[i]; ++i) {
385 if (AArch64::GPR64RegClass.contains(CSRegs[i]) &&
387 ExtraReg = CSRegs[i];
395 assert(RS &&
"Expect register scavenger to be available");
408 unsigned Reg)
const {
411 if (Reg == AArch64::X30) {
426 const std::vector<CalleeSavedInfo> &CSI,
428 const LoadStoreMethod PossClasses[],
429 unsigned NumClasses)
const {
445 for (
unsigned i = 0, e = CSI.size(); i < e; ++i) {
446 unsigned Reg = CSI[i].getReg();
451 for (ClassIdx = 0; ClassIdx < NumClasses; ++ClassIdx) {
452 if (PossClasses[ClassIdx].RegClass->contains(Reg))
455 assert(ClassIdx != NumClasses
456 &&
"Asked to store register in unexpected class");
465 unsigned StLow = 0, StHigh = 0;
476 NewMI =
BuildMI(MBB, MBBI, DL, TII.
get(PossClasses[ClassIdx].PairOpcode))
477 .addReg(CSI[i+1].
getReg(), StLow)
478 .addReg(CSI[i].
getReg(), StHigh);
491 TII.
get(PossClasses[ClassIdx].SingleOpcode))
492 .addReg(CSI[i].
getReg(), State);
498 int FrameIdx = CSI[i].getFrameIdx();
526 const std::vector<CalleeSavedInfo> &CSI,
531 static const LoadStoreMethod PossibleClasses[] = {
532 {&AArch64::GPR64RegClass, AArch64::LSPair64_STR, AArch64::LS64_STR},
533 {&AArch64::FPR64RegClass, AArch64::LSFPPair64_STR, AArch64::LSFP64_STR},
538 PossibleClasses, NumClasses);
546 const std::vector<CalleeSavedInfo> &CSI,
552 static const LoadStoreMethod PossibleClasses[] = {
553 {&AArch64::GPR64RegClass, AArch64::LSPair64_LDR, AArch64::LS64_LDR},
554 {&AArch64::FPR64RegClass, AArch64::LSFPPair64_LDR, AArch64::LSFP64_LDR},
559 PossibleClasses, NumClasses);
605 int Opcode = MI->getOpcode();
606 bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
607 uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0;
612 int64_t Amount = MI->getOperand(0).getImm();
614 if (!IsDestroy) Amount = -Amount;
619 if (CalleePopAmount == 0) {
624 assert(Amount > -0xfff && Amount < 0xfff &&
"call frame too large");
625 emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount);
627 }
else if (CalleePopAmount != 0) {
630 assert(CalleePopAmount < 0xfff &&
"call frame too large");
631 emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount);
unsigned getStackAlignment() const
The memory access reads data.
const MachineFunction * getParent() const
instr_iterator erase(instr_iterator I)
void setPhysRegUsed(unsigned Reg)
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...
The memory access writes data.
const GlobalValue * getGlobal() const
void setInitialStackAdjust(unsigned bytes)
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
On AA.
virtual void emitPrologue(MachineFunction &MF) const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
int getFramePointerOffset() const
bool adjustsStack() const
void addLiveIn(unsigned Reg)
const uint16_t * getCalleeSavedRegs(const MachineFunction *MF=0) const
bool isReturnAddressTaken() const
const char * getSymbolName() const
const Function * getFunction() const
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
void emitFrameMemOps(bool isStore, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI, const LoadStoreMethod PossibleClasses[], unsigned NumClasses) const
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
uint64_t getStackSize() const
MCSymbol * CreateTempSymbol()
const HexagonInstrInfo * TII
void splitSPAdjustments(uint64_t Total, uint64_t &Initial, uint64_t &Residual) const
bool DisableFramePointerElim(const MachineFunction &MF) const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Abstract Stack Frame Information.
bool isFrameAddressTaken() const
bool hasDebugInfo() const
unsigned estimateRSStackLimit(MachineFunction &MF) const
const MachineInstrBuilder & addImm(int64_t Val) const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
const MachineBasicBlock & front() const
size_t array_lengthof(T(&)[N])
Find the length of an array.
bool isLiveIn(unsigned Reg) const
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
iterator getLastNonDebugInstr()
unsigned getKillRegState(bool B)
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
bundle_iterator< MachineInstr, instr_iterator > iterator
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
unsigned getTargetFlags() const
bool determinePrologueDeath(MachineBasicBlock &MBB, unsigned Reg) const
static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register, int Offset)
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it...
virtual bool needsStackRealignment(const MachineFunction &MF) const
unsigned getAlignment() const
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
int64_t resolveFrameIndexReference(MachineFunction &MF, int FrameIndex, unsigned &FrameReg, int SPAdj, bool IsCalleeSaveOp) const
int64_t getOffset() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getInitialStackAdjust() const
const MCInstrDesc & get(unsigned Opcode) const
int64_t getObjectOffset(int ObjectIdx) const
DebugLoc findDebugLoc(instr_iterator MBBI)
virtual bool useFPForAddressing(const MachineFunction &MF) const
bool hasCalls() const
hasCalls - Return true if the current function has any function calls.
virtual const TargetInstrInfo * getInstrInfo() const
void addOperand(MachineFunction &MF, const MachineOperand &Op)
const MCContext & getContext() const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
void setOffsetAdjustment(int Adj)
MachineFrameInfo * getFrameInfo()
const MachineInstrBuilder & addFrameIndex(int Idx) const
MemOperandFlags
Flags values. These may be or'd together.
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))
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
const MCRegisterInfo * getRegisterInfo() const
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP=false, const AllocaInst *Alloca=0)
MachineRegisterInfo & getRegInfo()
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
virtual bool hasFP(const MachineFunction &MF) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
void addFrameInst(const MCCFIInstruction &Inst)
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool hasVarSizedObjects() const
void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned DstReg, unsigned SrcReg, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
unsigned getReg() const
getReg - Returns the register number.
bool isPhysRegUsed(unsigned Reg) const
ItTy prior(ItTy it, Dist n)
unsigned getArgumentStackToRestore() const
MachineModuleInfo & getMMI() const
const MCRegisterInfo & MRI
void setFramePointerOffset(int Idx)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
bool contains(unsigned Reg) const