28 { SystemZ::R2D, 0x10 },
29 { SystemZ::R3D, 0x18 },
30 { SystemZ::R4D, 0x20 },
31 { SystemZ::R5D, 0x28 },
32 { SystemZ::R6D, 0x30 },
33 { SystemZ::R7D, 0x38 },
34 { SystemZ::R8D, 0x40 },
35 { SystemZ::R9D, 0x48 },
36 { SystemZ::R10D, 0x50 },
37 { SystemZ::R11D, 0x58 },
38 { SystemZ::R12D, 0x60 },
39 { SystemZ::R13D, 0x68 },
40 { SystemZ::R14D, 0x70 },
41 { SystemZ::R15D, 0x78 },
42 { SystemZ::F0D, 0x80 },
43 { SystemZ::F2D, 0x88 },
44 { SystemZ::F4D, 0x90 },
45 { SystemZ::F6D, 0x98 }
53 RegSpillOffsets.
grow(SystemZ::NUM_TARGET_REGS);
55 RegSpillOffsets[SpillOffsetTable[
I].
Reg] = SpillOffsetTable[
I].Offset;
61 return SpillOffsetTable;
71 bool HasFP =
hasFP(MF);
86 SavedRegs.
set(SystemZ::R11D);
91 SavedRegs.
set(SystemZ::R14D);
98 for (
unsigned I = 0; CSRegs[
I]; ++
I) {
99 unsigned Reg = CSRegs[
I];
100 if (SystemZ::GR64BitRegClass.
contains(Reg) && SavedRegs.
test(Reg)) {
101 SavedRegs.
set(SystemZ::R15D);
112 unsigned GPR64,
bool IsImplicit) {
115 unsigned GPR32 = RI->
getSubReg(GPR64, SystemZ::subreg_l32);
117 if (!IsLive || !IsImplicit) {
127 const std::vector<CalleeSavedInfo> &CSI,
140 unsigned HighGPR = SystemZ::R15D;
141 unsigned StartOffset = -1U;
142 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
143 unsigned Reg = CSI[
I].getReg();
144 if (SystemZ::GR64BitRegClass.
contains(Reg)) {
145 unsigned Offset = RegSpillOffsets[
Reg];
146 assert(Offset &&
"Unexpected GPR save");
147 if (StartOffset > Offset) {
149 StartOffset = Offset;
165 unsigned Offset = RegSpillOffsets[
Reg];
166 if (StartOffset > Offset) {
167 LowGPR =
Reg; StartOffset = Offset;
174 assert(LowGPR != HighGPR &&
"Should be saving %r15 and something else");
188 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
189 unsigned Reg = CSI[
I].getReg();
190 if (SystemZ::GR64BitRegClass.
contains(Reg))
201 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
202 unsigned Reg = CSI[
I].getReg();
203 if (SystemZ::FP64BitRegClass.
contains(Reg)) {
206 &SystemZ::FP64BitRegClass, TRI);
216 const std::vector<CalleeSavedInfo> &CSI,
224 bool HasFP =
hasFP(MF);
228 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
229 unsigned Reg = CSI[
I].getReg();
230 if (SystemZ::FP64BitRegClass.
contains(Reg))
232 &SystemZ::FP64BitRegClass, TRI);
239 unsigned StartOffset = RegSpillOffsets[LowGPR];
244 assert(LowGPR != HighGPR &&
"Should be loading %r15 and something else");
254 MIB.
addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
258 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
259 unsigned Reg = CSI[
I].getReg();
260 if (Reg != LowGPR && Reg != HighGPR)
274 if (!isUInt<12>(MaxReach)) {
288 unsigned Reg, int64_t NumBytes,
292 int64_t ThisVal = NumBytes;
294 Opcode = SystemZ::AGHI;
296 Opcode = SystemZ::AGFI;
298 int64_t MinVal = -uint64_t(1) << 31;
299 int64_t MaxVal = (int64_t(1) << 31) - 8;
300 if (ThisVal < MinVal)
302 else if (ThisVal > MaxVal)
306 .addReg(Reg).
addImm(ThisVal);
315 assert(&MF.
front() == &MBB &&
"Shrink-wrapping not yet supported");
323 const std::vector<CalleeSavedInfo> &CSI = MFFrame->getCalleeSavedInfo();
324 bool HasFP =
hasFP(MF);
332 if (MBBI != MBB.
end() && MBBI->getOpcode() == SystemZ::STMG)
338 for (
auto &Save : CSI) {
339 unsigned Reg = Save.getReg();
340 if (SystemZ::GR64BitRegClass.
contains(Reg)) {
341 int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[
Reg];
345 .addCFIIndex(CFIIndex);
353 int64_t Delta = -int64_t(StackSize);
360 .addCFIIndex(CFIIndex);
361 SPOffsetFromCFA += Delta;
366 BuildMI(MBB, MBBI, DL, ZII->
get(SystemZ::LGR), SystemZ::R11D)
367 .addReg(SystemZ::R15D);
374 .addCFIIndex(CFIIndex);
379 for (
auto I = std::next(MF.
begin()), E = MF.
end();
I != E; ++
I)
380 I->addLiveIn(SystemZ::R11D);
385 for (
auto &Save : CSI) {
386 unsigned Reg = Save.getReg();
387 if (SystemZ::FP64BitRegClass.
contains(Reg)) {
388 if (MBBI != MBB.
end() &&
389 (MBBI->getOpcode() == SystemZ::STD ||
390 MBBI->getOpcode() == SystemZ::STDY))
399 nullptr, DwarfReg, SPOffsetFromCFA + Offset));
405 for (
auto CFIIndex : CFIIndexes) {
407 .addCFIIndex(CFIIndex);
419 assert(MBBI->isReturn() &&
"Can only insert epilogue into returning blocks");
424 unsigned Opcode = MBBI->getOpcode();
425 if (Opcode != SystemZ::LMG)
428 unsigned AddrOpNo = 2;
430 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
431 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
436 uint64_t NumBytes = Offset - 0x7fff8;
440 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
441 assert(NewOpcode &&
"No restore instruction available");
444 MBBI->setDesc(ZII->get(NewOpcode));
445 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
446 }
else if (StackSize) {
506 switch (MI->getOpcode()) {
507 case SystemZ::ADJCALLSTACKDOWN:
508 case SystemZ::ADJCALLSTACKUP:
510 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
void push_back(const T &Elt)
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.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
const int64_t CallFrameSize
const unsigned ArgGPRs[NumArgGPRs]
static void emitIncrement(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL, unsigned Reg, int64_t NumBytes, const TargetInstrInfo *TII)
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset)
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override
getFrameIndexOffset - Returns the displacement from the frame register to the stack frame of the spec...
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 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.
void setIsDead(bool Val=true)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
const unsigned NumArgGPRs
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
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.
const HexagonInstrInfo * TII
#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...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
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...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
const MachineBasicBlock & front() const
int getOffsetAdjustment() const
Return the correction for frame offsets.
unsigned LLVM_ATTRIBUTE_UNUSED_RESULT addFrameInst(const MCCFIInstruction &Inst)
iterator getLastNonDebugInstr()
getLastNonDebugInstr - returns an iterator to the last non-debug instruction in the basic block...
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
getCalleeSavedRegs - Return a null-terminated list of all of the callee saved registers on this targe...
unsigned getHighSavedGPR() const
unsigned getKillRegState(bool B)
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
bundle_iterator< MachineInstr, instr_iterator > iterator
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
const MachineOperand & getOperand(unsigned i) const
const int64_t CFAOffsetFromInitialSP
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
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...
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
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...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getLowSavedGPR() const
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.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool hasCalls() const
Return true if the current function has any function calls.
const MDOperand & getOperand(unsigned I) const
static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, unsigned GPR64, bool IsImplicit)
const MCContext & getContext() const
void setHighSavedGPR(unsigned Reg)
uint64_t getAllocatedStackSize(const MachineFunction &MF) const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
bool test(unsigned Idx) const
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Information about stack frame layout on the target.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void setLowSavedGPR(unsigned Reg)
const MCRegisterInfo * getRegisterInfo() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool isLiveIn(unsigned Reg) const
isLiveIn - Return true if the specified register is in the live in set.
unsigned getImplRegState(bool B)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool isInt< 16 >(int64_t x)
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...
virtual const TargetInstrInfo * getInstrInfo() const
unsigned getVarArgsFirstGPR() const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MachineModuleInfo & getMMI() const
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 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 isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
MachineModuleInfo - This class contains meta information specific to a module.
void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
eliminateCallFramePseudoInstr - This method is called during prolog/epilog code insertion to eliminat...