26 { SystemZ::R2D, 0x10 },
27 { SystemZ::R3D, 0x18 },
28 { SystemZ::R4D, 0x20 },
29 { SystemZ::R5D, 0x28 },
30 { SystemZ::R6D, 0x30 },
31 { SystemZ::R7D, 0x38 },
32 { SystemZ::R8D, 0x40 },
33 { SystemZ::R9D, 0x48 },
34 { SystemZ::R10D, 0x50 },
35 { SystemZ::R11D, 0x58 },
36 { SystemZ::R12D, 0x60 },
37 { SystemZ::R13D, 0x68 },
38 { SystemZ::R14D, 0x70 },
39 { SystemZ::R15D, 0x78 },
40 { SystemZ::F0D, 0x80 },
41 { SystemZ::F2D, 0x88 },
42 { SystemZ::F4D, 0x90 },
43 { SystemZ::F6D, 0x98 }
53 RegSpillOffsets.
grow(SystemZ::NUM_TARGET_REGS);
55 RegSpillOffsets[SpillOffsetTable[
I].
Reg] = SpillOffsetTable[
I].Offset;
61 return SpillOffsetTable;
70 bool HasFP =
hasFP(MF);
97 for (
unsigned I = 0; CSRegs[
I]; ++
I) {
98 unsigned Reg = CSRegs[
I];
99 if (SystemZ::GR64BitRegClass.contains(Reg) && MRI.
isPhysRegUsed(Reg)) {
112 unsigned GPR64,
bool IsImplicit) {
114 unsigned GPR32 = RI->getSubReg(GPR64, SystemZ::subreg_l32);
116 if (!IsLive || !IsImplicit) {
126 const std::vector<CalleeSavedInfo> &CSI,
139 unsigned HighGPR = SystemZ::R15D;
140 unsigned StartOffset = -1U;
141 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
142 unsigned Reg = CSI[
I].getReg();
143 if (SystemZ::GR64BitRegClass.contains(Reg)) {
144 unsigned Offset = RegSpillOffsets[
Reg];
145 assert(Offset &&
"Unexpected GPR save");
146 if (StartOffset > Offset) {
148 StartOffset = Offset;
164 unsigned Offset = RegSpillOffsets[
Reg];
165 if (StartOffset > Offset) {
166 LowGPR =
Reg; StartOffset = Offset;
173 assert(LowGPR != HighGPR &&
"Should be saving %r15 and something else");
187 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
188 unsigned Reg = CSI[
I].getReg();
189 if (SystemZ::GR64BitRegClass.contains(Reg))
200 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
201 unsigned Reg = CSI[
I].getReg();
202 if (SystemZ::FP64BitRegClass.contains(Reg)) {
205 &SystemZ::FP64BitRegClass, TRI);
215 const std::vector<CalleeSavedInfo> &CSI,
223 bool HasFP =
hasFP(MF);
227 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
228 unsigned Reg = CSI[
I].getReg();
229 if (SystemZ::FP64BitRegClass.contains(Reg))
231 &SystemZ::FP64BitRegClass, TRI);
238 unsigned StartOffset = RegSpillOffsets[LowGPR];
243 assert(LowGPR != HighGPR &&
"Should be loading %r15 and something else");
253 MIB.
addReg(HasFP ? SystemZ::R11D : SystemZ::R15D);
257 for (
unsigned I = 0, E = CSI.size();
I != E; ++
I) {
258 unsigned Reg = CSI[
I].getReg();
259 if (Reg != LowGPR && Reg != HighGPR)
273 if (!isUInt<12>(MaxReach)) {
287 unsigned Reg, int64_t NumBytes,
291 int64_t ThisVal = NumBytes;
293 Opcode = SystemZ::AGHI;
295 Opcode = SystemZ::AGFI;
297 int64_t MinVal = -int64_t(1) << 31;
298 int64_t MaxVal = (int64_t(1) << 31) - 8;
299 if (ThisVal < MinVal)
301 else if (ThisVal > MaxVal)
305 .addReg(Reg).
addImm(ThisVal);
322 bool HasFP =
hasFP(MF);
330 if (MBBI != MBB.
end() && MBBI->getOpcode() == SystemZ::STMG)
339 for (std::vector<CalleeSavedInfo>::const_iterator
340 I = CSI.begin(), E = CSI.end();
I != E; ++
I) {
341 unsigned Reg =
I->getReg();
342 if (SystemZ::GR64BitRegClass.contains(Reg)) {
343 int64_t Offset = SPOffsetFromCFA + RegSpillOffsets[
Reg];
353 int64_t Delta = -int64_t(StackSize);
359 .addSym(AdjustSPLabel);
361 AdjustSPLabel, SPOffsetFromCFA + Delta));
362 SPOffsetFromCFA += Delta;
367 BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR), SystemZ::R11D)
368 .addReg(SystemZ::R15D);
383 I->addLiveIn(SystemZ::R11D);
388 for (std::vector<CalleeSavedInfo>::const_iterator
389 I = CSI.begin(), E = CSI.end();
I != E; ++
I) {
390 unsigned Reg =
I->getReg();
391 if (SystemZ::FP64BitRegClass.contains(Reg)) {
392 if (MBBI != MBB.
end() &&
393 (MBBI->getOpcode() == SystemZ::STD ||
394 MBBI->getOpcode() == SystemZ::STDY))
405 FPRSaveLabel, Reg, SPOffsetFromCFA + Offset));
412 .addSym(FPRSaveLabel);
423 assert(MBBI->isReturn() &&
"Can only insert epilogue into returning blocks");
428 unsigned Opcode = MBBI->getOpcode();
429 if (Opcode != SystemZ::LMG)
432 unsigned AddrOpNo = 2;
434 uint64_t Offset = StackSize + MBBI->getOperand(AddrOpNo + 1).getImm();
440 uint64_t NumBytes = Offset - 0x7fff8;
441 emitIncrement(MBB, MBBI, DL, MBBI->getOperand(AddrOpNo).getReg(),
445 assert(NewOpcode &&
"No restore instruction available");
448 MBBI->setDesc(ZII->get(NewOpcode));
449 MBBI->getOperand(AddrOpNo + 1).ChangeToImmediate(Offset);
450 }
else if (StackSize) {
510 switch (MI->getOpcode()) {
511 case SystemZ::ADJCALLSTACKDOWN:
512 case SystemZ::ADJCALLSTACKUP:
514 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
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...
virtual bool hasReservedCallFrame(const MachineFunction &MF) const LLVM_OVERRIDE
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)
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)
void setIsDead(bool Val=true)
const Function * getFunction() const
const unsigned NumArgGPRs
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...
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF=0) const =0
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const LLVM_OVERRIDE
uint64_t getStackSize() const
MCSymbol * CreateTempSymbol()
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
bool DisableFramePointerElim(const MachineFunction &MF) const
Abstract Stack Frame Information.
SystemZFrameLowering(const SystemZTargetMachine &tm, const SystemZSubtarget &sti)
const MachineInstrBuilder & addImm(int64_t Val) const
const MachineBasicBlock & front() const
size_t array_lengthof(T(&)[N])
Find the length of an array.
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const LLVM_OVERRIDE
int getOffsetAdjustment() const
iterator getLastNonDebugInstr()
unsigned getHighSavedGPR() const
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
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const
const SystemZTargetMachine & TM
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...
static void addSavedGPR(MachineBasicBlock &MBB, MachineInstrBuilder &MIB, const SystemZTargetMachine &TM, unsigned GPR64, bool IsImplicit)
const MachineOperand & getOperand(unsigned i) const
const int64_t CFAOffsetFromInitialSP
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
ItTy next(ItTy it, Dist n)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const LLVM_OVERRIDE
virtual void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
unsigned getLowSavedGPR() const
const MCInstrDesc & get(unsigned Opcode) const
int64_t getObjectOffset(int ObjectIdx) const
virtual const SystemZRegisterInfo * getRegisterInfo() const LLVM_OVERRIDE
bool hasCalls() const
hasCalls - Return true if the current function has any function calls.
virtual const TargetInstrInfo * getInstrInfo() const
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const LLVM_OVERRIDE
const MCContext & getContext() const
void setHighSavedGPR(unsigned Reg)
uint64_t getAllocatedStackSize(const MachineFunction &MF) const
void addScavengingFrameIndex(int FI)
Add a scavenging frame index.
int getOffsetOfLocalArea() const
virtual bool hasFP(const MachineFunction &MF) const LLVM_OVERRIDE
MachineFrameInfo * getFrameInfo()
void setLowSavedGPR(unsigned Reg)
const MCRegisterInfo * getRegisterInfo() const
int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, bool MayNeedSP=false, const AllocaInst *Alloca=0)
bool isLiveIn(unsigned Reg) const
MachineRegisterInfo & getRegInfo()
virtual void emitPrologue(MachineFunction &MF) const LLVM_OVERRIDE
unsigned getImplRegState(bool B)
void addFrameInst(const MCCFIInstruction &Inst)
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool isInt< 16 >(int64_t x)
bool hasVarSizedObjects() const
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBII, const std::vector< CalleeSavedInfo > &CSI, const TargetRegisterInfo *TRI) const LLVM_OVERRIDE
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const
virtual const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const LLVM_OVERRIDE
virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const LLVM_OVERRIDE
unsigned getVarArgsFirstGPR() const
bool isPhysRegUsed(unsigned Reg) const
BasicBlockListType::iterator iterator
MachineModuleInfo & getMMI() const
const MCRegisterInfo & MRI
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const