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 }
54 RegSpillOffsets.
grow(SystemZ::NUM_TARGET_REGS);
56 RegSpillOffsets[SpillOffsetTable[
I].
Reg] = SpillOffsetTable[
I].
Offset;
62 return SpillOffsetTable;
72 bool HasFP =
hasFP(MF);
86 SavedRegs.
set(SystemZ::R6D);
87 SavedRegs.
set(SystemZ::R7D);
93 SavedRegs.
set(SystemZ::R11D);
98 SavedRegs.
set(SystemZ::R14D);
105 for (
unsigned I = 0; CSRegs[
I]; ++
I) {
106 unsigned Reg = CSRegs[
I];
107 if (SystemZ::GR64BitRegClass.
contains(Reg) && SavedRegs.
test(Reg)) {
108 SavedRegs.
set(SystemZ::R15D);
119 unsigned GPR64,
bool IsImplicit) {
122 unsigned GPR32 = RI->
getSubReg(GPR64, SystemZ::subreg_l32);
124 if (!IsLive || !IsImplicit) {
134 const std::vector<CalleeSavedInfo> &CSI,
147 unsigned HighGPR = SystemZ::R15D;
148 unsigned StartOffset = -1U;
149 for (
unsigned I = 0,
E = CSI.size();
I !=
E; ++
I) {
150 unsigned Reg = CSI[
I].getReg();
151 if (SystemZ::GR64BitRegClass.
contains(Reg)) {
153 assert(Offset &&
"Unexpected GPR save");
154 if (StartOffset > Offset) {
173 if (StartOffset > Offset) {
181 assert(LowGPR != HighGPR &&
"Should be saving %r15 and something else");
195 for (
unsigned I = 0,
E = CSI.size();
I !=
E; ++
I) {
196 unsigned Reg = CSI[
I].getReg();
197 if (SystemZ::GR64BitRegClass.
contains(Reg))
208 for (
unsigned I = 0,
E = CSI.size();
I !=
E; ++
I) {
209 unsigned Reg = CSI[
I].getReg();
210 if (SystemZ::FP64BitRegClass.
contains(Reg)) {
213 &SystemZ::FP64BitRegClass, TRI);
215 if (SystemZ::VR128BitRegClass.
contains(Reg)) {
218 &SystemZ::VR128BitRegClass, TRI);
228 std::vector<CalleeSavedInfo> &CSI,
236 bool HasFP =
hasFP(MF);
240 for (
unsigned I = 0,
E = CSI.size();
I !=
E; ++
I) {
241 unsigned Reg = CSI[
I].getReg();
242 if (SystemZ::FP64BitRegClass.
contains(Reg))
244 &SystemZ::FP64BitRegClass, TRI);
245 if (SystemZ::VR128BitRegClass.
contains(Reg))
247 &SystemZ::VR128BitRegClass, TRI);
254 unsigned StartOffset = RegSpillOffsets[LowGPR];
259 assert(LowGPR != HighGPR &&
"Should be loading %r15 and something else");
269 MIB.
addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
273 for (
unsigned I = 0,
E = CSI.size();
I !=
E; ++
I) {
274 unsigned Reg = CSI[
I].getReg();
275 if (Reg != LowGPR && Reg != HighGPR &&
276 SystemZ::GR64BitRegClass.
contains(Reg))
299 MaxArgOffset =
std::max(MaxArgOffset, ArgOffset);
302 uint64_t MaxReach = StackSize + MaxArgOffset;
303 if (!isUInt<12>(MaxReach)) {
317 unsigned Reg, int64_t NumBytes,
321 int64_t ThisVal = NumBytes;
323 Opcode = SystemZ::AGHI;
325 Opcode = SystemZ::AGFI;
327 int64_t MinVal = -uint64_t(1) << 31;
328 int64_t MaxVal = (int64_t(1) << 31) - 8;
329 if (ThisVal < MinVal)
331 else if (ThisVal > MaxVal)
335 .addReg(Reg).
addImm(ThisVal);
344 assert(&MF.
front() == &MBB &&
"Shrink-wrapping not yet supported");
352 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
353 bool HasFP =
hasFP(MF);
364 if (MBBI != MBB.
end() && MBBI->getOpcode() == SystemZ::STMG)
370 for (
auto &Save : CSI) {
371 unsigned Reg = Save.getReg();
372 if (SystemZ::GR64BitRegClass.
contains(Reg)) {
373 int64_t
Offset = SPOffsetFromCFA + RegSpillOffsets[
Reg];
376 BuildMI(MBB, MBBI, DL, ZII->
get(TargetOpcode::CFI_INSTRUCTION))
377 .addCFIIndex(CFIIndex);
382 uint64_t StackSize = MFFrame.getStackSize();
386 if (StackSize || MFFrame.hasVarSizedObjects() || MFFrame.hasCalls()) {
388 MFFrame.setStackSize(StackSize);
398 BuildMI(MBB, MBBI, DL, ZII->
get(SystemZ::LGR))
402 int64_t Delta = -int64_t(StackSize);
408 BuildMI(MBB, MBBI, DL, ZII->
get(TargetOpcode::CFI_INSTRUCTION))
409 .addCFIIndex(CFIIndex);
410 SPOffsetFromCFA += Delta;
413 BuildMI(MBB, MBBI, DL, ZII->
get(SystemZ::STG))
419 BuildMI(MBB, MBBI, DL, ZII->
get(SystemZ::LGR), SystemZ::R11D)
420 .addReg(SystemZ::R15D);
426 BuildMI(MBB, MBBI, DL, ZII->
get(TargetOpcode::CFI_INSTRUCTION))
427 .addCFIIndex(CFIIndex);
432 for (
auto I = std::next(MF.
begin()),
E = MF.
end();
I !=
E; ++
I)
433 I->addLiveIn(SystemZ::R11D);
438 for (
auto &Save : CSI) {
439 unsigned Reg = Save.getReg();
440 if (SystemZ::FP64BitRegClass.
contains(Reg)) {
441 if (MBBI != MBB.
end() &&
442 (MBBI->getOpcode() == SystemZ::STD ||
443 MBBI->getOpcode() == SystemZ::STDY))
447 }
else if (SystemZ::VR128BitRegClass.
contains(Reg)) {
448 if (MBBI != MBB.
end() &&
449 MBBI->getOpcode() == SystemZ::VST)
458 unsigned IgnoredFrameReg;
463 nullptr, DwarfReg, SPOffsetFromCFA + Offset));
468 for (
auto CFIIndex : CFIIndexes) {
469 BuildMI(MBB, MBBI, DL, ZII->
get(TargetOpcode::CFI_INSTRUCTION))
470 .addCFIIndex(CFIIndex);
483 assert(MBBI->isReturn() &&
"Can only insert epilogue into returning blocks");
485 uint64_t StackSize = MFFrame.getStackSize();
488 unsigned Opcode = MBBI->getOpcode();
489 if (Opcode != SystemZ::LMG)
492 unsigned AddrOpNo = 2;
494 uint64_t
Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
495 unsigned NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
500 uint64_t NumBytes = Offset - 0x7fff8;
501 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
504 NewOpcode = ZII->getOpcodeForOffset(Opcode, Offset);
505 assert(NewOpcode &&
"No restore instruction available");
508 MBBI->setDesc(ZII->get(NewOpcode));
509 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
510 }
else if (StackSize) {
535 switch (MI->getOpcode()) {
536 case SystemZ::ADJCALLSTACKDOWN:
537 case SystemZ::ADJCALLSTACKUP:
539 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
540 return MBB.
erase(MI);
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const int64_t CallFrameSize
This class represents lattice values for constants.
unsigned getHighSavedGPR() const
virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static void emitIncrement(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &DL, unsigned Reg, int64_t NumBytes, const TargetInstrInfo *TII)
void push_back(const T &Elt)
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.
bool test(unsigned Idx) const
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.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
constexpr bool isInt< 16 >(int64_t x)
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
const unsigned NumArgGPRs
MachineModuleInfo & getMMI() const
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset)
.cfi_def_cfa_offset modifies a rule for computing CFA.
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it...
return AArch64::GPR64RegClass contains(Reg)
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) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const HexagonInstrInfo * TII
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
const MCContext & getContext() const
int getObjectIndexBegin() const
Return the minimum frame object index.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
virtual const TargetInstrInfo * getInstrInfo() const
unsigned getLowSavedGPR() const
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
Return a null-terminated list of all of the callee-saved registers on this target.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
This file declares the machine register scavenger class.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const int64_t CFAOffsetFromInitialSP
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, unsigned GPR64, bool IsImplicit)
unsigned getVarArgsFirstGPR() const
void setHighSavedGPR(unsigned Reg)
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
unsigned estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Information about stack frame layout on the target.
void setLowSavedGPR(unsigned Reg)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
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...
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
unsigned getImplRegState(bool B)
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
const MCPhysReg ArgGPRs[NumArgGPRs]
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 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...
This class contains meta information specific to a module.
bool hasCalls() const
Return true if the current function has any function calls.