34 if (CFSize >= ((1 << 8) - 1) * 4 / 2)
70 Amount = (Amount+Align-1)/Align*Align;
74 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
77 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
87 assert(&MBB == &MF.
front() &&
"Shrink-wrapping not yet implemented");
100 assert(NumBytes >= ArgRegsSaveSize &&
101 "ArgRegsSaveSize is included in NumBytes");
109 NumBytes = (NumBytes + 3) & ~3;
114 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
115 int FramePtrSpillFI = 0;
117 if (ArgRegsSaveSize) {
118 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize,
120 CFAOffset -= ArgRegsSaveSize;
121 unsigned CFIIndex = MMI.addFrameInst(
124 .addCFIIndex(CFIIndex)
129 if (NumBytes - ArgRegsSaveSize != 0) {
130 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -(NumBytes - ArgRegsSaveSize),
132 CFAOffset -= NumBytes - ArgRegsSaveSize;
133 unsigned CFIIndex = MMI.addFrameInst(
136 .addCFIIndex(CFIIndex)
142 for (
unsigned i = 0, e = CSI.size(); i != e; ++i) {
143 unsigned Reg = CSI[i].getReg();
144 int FI = CSI[i].getFrameIdx();
161 FramePtrSpillFI = FI;
169 if (MBBI != MBB.
end() && MBBI->getOpcode() == ARM::tPUSH) {
171 if (MBBI != MBB.
end())
172 dl = MBBI->getDebugLoc();
176 unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize - (GPRCS1Size + GPRCS2Size + DPRCSSize);
177 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
178 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
179 bool HasFP =
hasFP(MF);
186 NumBytes = DPRCSOffset;
188 int FramePtrOffsetInBlock = 0;
189 unsigned adjustedGPRCS1Size = GPRCS1Size;
191 FramePtrOffsetInBlock = NumBytes;
192 adjustedGPRCS1Size += NumBytes;
196 if (adjustedGPRCS1Size) {
197 CFAOffset -= adjustedGPRCS1Size;
198 unsigned CFIIndex = MMI.addFrameInst(
201 .addCFIIndex(CFIIndex)
204 for (std::vector<CalleeSavedInfo>::const_iterator
I = CSI.begin(),
205 E = CSI.end();
I != E; ++
I) {
206 unsigned Reg =
I->getReg();
207 int FI =
I->getFrameIdx();
229 .addCFIIndex(CFIIndex)
239 + GPRCS1Size + ArgRegsSaveSize;
241 .addReg(ARM::SP).
addImm(FramePtrOffsetInBlock / 4)
243 if(FramePtrOffsetInBlock) {
244 CFAOffset += FramePtrOffsetInBlock;
248 .addCFIIndex(CFIIndex)
255 .addCFIIndex(CFIIndex)
269 CFAOffset -= NumBytes;
270 unsigned CFIIndex = MMI.addFrameInst(
273 .addCFIIndex(CFIIndex)
325 assert((MBBI->getOpcode() == ARM::tBX_RET ||
326 MBBI->getOpcode() == ARM::tPOP_RET) &&
327 "Can only insert epilog into returning blocks");
338 assert((
unsigned)NumBytes >= ArgRegsSaveSize &&
339 "ArgRegsSaveSize is included in NumBytes");
340 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
341 unsigned FramePtr = RegInfo->getFrameRegister(MF);
344 if (NumBytes - ArgRegsSaveSize != 0)
345 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes - ArgRegsSaveSize);
348 if (MBBI != MBB.
begin()) {
369 "No scratch register to restore SP from FP!");
380 if (MBBI->getOpcode() == ARM::tBX_RET &&
381 &MBB.
front() != MBBI &&
382 std::prev(MBBI)->
getOpcode() == ARM::tPOP) {
391 bool IsV4PopReturn =
false;
393 if (CSI.getReg() == ARM::LR)
394 IsV4PopReturn =
true;
411 if (ArgRegsSaveSize || IsV4PopReturn) {
414 assert (MBBI->getOpcode() == ARM::tBX_RET);
422 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
425 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX))
439 emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize);
456 const std::vector<CalleeSavedInfo> &CSI,
464 if (MI != MBB.
end()) DL = MI->getDebugLoc();
468 for (
unsigned i = CSI.size(); i != 0; --i) {
469 unsigned Reg = CSI[i-1].getReg();
475 if (Reg == ARM::LR) {
494 const std::vector<CalleeSavedInfo> &CSI,
508 bool NumRegs =
false;
509 for (
unsigned i = CSI.size(); i != 0; --i) {
510 unsigned Reg = CSI[i-1].getReg();
511 if (Reg == ARM::LR) {
519 (*MIB).setDesc(TII.get(ARM::tPOP_RET));
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
unsigned getBaseRegister() const
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.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
void setGPRCalleeSavedArea2Offset(unsigned o)
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
unsigned getDPRCalleeSavedAreaSize() const
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
const ARMBaseInstrInfo * getInstrInfo() const override
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
DILocation * get() const
Get the underlying DILocation.
const HexagonInstrInfo * TII
Thumb1FrameLowering(const ARMSubtarget &sti)
unsigned getFrameRegister(const MachineFunction &MF) const override
unsigned getArgRegsSaveSize() const
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...
void setDPRCalleeSavedAreaOffset(unsigned o)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void setFramePtrSpillOffset(unsigned o)
const MachineBasicBlock & front() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool isLiveIn(unsigned Reg) const
int getOffsetAdjustment() const
Return the correction for frame offsets.
void setShouldRestoreSPFromFP(bool s)
unsigned getReturnRegsCount() const
bool isTargetMachO() const
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 getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDefRegState(bool B)
bundle_iterator< MachineInstr, instr_iterator > iterator
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
bool hasStackFrame() 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...
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
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...
void setStackSize(uint64_t Size)
Set the size of the stack.
const MachineOperand & getOperand(unsigned i) const
unsigned getFramePtrSpillOffset() const
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setGPRCalleeSavedArea2Size(unsigned s)
bool hasReservedCallFrame(const MachineFunction &MF) const override
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.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
void DeleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
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...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
static bool isCSRestore(MachineInstr *MI, const MCPhysReg *CSRegs)
void setGPRCalleeSavedArea1Size(unsigned s)
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
bool test(unsigned Idx) const
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
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))
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool hasBasePointer(const MachineFunction &MF) const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Representation of each machine instruction.
static void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, DebugLoc dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags)
void setGPRCalleeSavedArea1Offset(unsigned o)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const ARMBaseRegisterInfo * getRegisterInfo() const override
void setDPRCalleeSavedAreaSize(unsigned s)
const MachineInstrBuilder & copyImplicitOps(const MachineInstr *OtherMI)
Copy all the implicit operands from OtherMI onto this one.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
unsigned getReg() const
getReg - Returns the register number.
unsigned getGPRCalleeSavedArea1Size() const
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
eliminateCallFramePseudoInstr - This method is called during prolog/epilog code insertion to eliminat...
static const unsigned FramePtr
MachineModuleInfo & getMMI() const
unsigned getGPRCalleeSavedArea2Size() const
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 MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
bool needsStackRealignment(const MachineFunction &MF) const override
MachineModuleInfo - This class contains meta information specific to a module.
bool shouldRestoreSPFromFP() const