xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZFrameLowering.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric //===-- SystemZFrameLowering.h - Frame lowering for SystemZ -----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
110b57cec5SDimitry Andric 
12e8d8bef9SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h"
13*349cc55cSDimitry Andric #include "SystemZInstrBuilder.h"
14*349cc55cSDimitry Andric #include "SystemZMachineFunctionInfo.h"
150b57cec5SDimitry Andric #include "llvm/ADT/IndexedMap.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
17e8d8bef9SDimitry Andric #include "llvm/Support/TypeSize.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace llvm {
200b57cec5SDimitry Andric class SystemZTargetMachine;
210b57cec5SDimitry Andric class SystemZSubtarget;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric class SystemZFrameLowering : public TargetFrameLowering {
24*349cc55cSDimitry Andric public:
25*349cc55cSDimitry Andric   SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl,
26*349cc55cSDimitry Andric                        bool StackReal);
27*349cc55cSDimitry Andric 
28*349cc55cSDimitry Andric   static std::unique_ptr<SystemZFrameLowering>
29*349cc55cSDimitry Andric   create(const SystemZSubtarget &STI);
30*349cc55cSDimitry Andric 
31*349cc55cSDimitry Andric   // Override TargetFrameLowering.
32*349cc55cSDimitry Andric   bool isFPCloseToIncomingSP() const override { return false; }
33*349cc55cSDimitry Andric   bool hasReservedCallFrame(const MachineFunction &MF) const override;
34*349cc55cSDimitry Andric   MachineBasicBlock::iterator
35*349cc55cSDimitry Andric   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
36*349cc55cSDimitry Andric                                 MachineBasicBlock::iterator MI) const override;
37*349cc55cSDimitry Andric };
38*349cc55cSDimitry Andric 
39*349cc55cSDimitry Andric class SystemZELFFrameLowering : public SystemZFrameLowering {
400b57cec5SDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric public:
43*349cc55cSDimitry Andric   SystemZELFFrameLowering();
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   // Override TargetFrameLowering.
460b57cec5SDimitry Andric   bool isFPCloseToIncomingSP() const override { return false; }
47480093f4SDimitry Andric   bool
48480093f4SDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
49480093f4SDimitry Andric                               const TargetRegisterInfo *TRI,
50480093f4SDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
510b57cec5SDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
520b57cec5SDimitry Andric                             RegScavenger *RS) const override;
530b57cec5SDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
540b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MBBI,
555ffd83dbSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
560b57cec5SDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
575ffd83dbSDimitry Andric   bool
585ffd83dbSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
590b57cec5SDimitry Andric                               MachineBasicBlock::iterator MBBII,
605ffd83dbSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
615ffd83dbSDimitry Andric                               const TargetRegisterInfo *TRI) const override;
620b57cec5SDimitry Andric   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
630b57cec5SDimitry Andric                                            RegScavenger *RS) const override;
640b57cec5SDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
650b57cec5SDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
665ffd83dbSDimitry Andric   void inlineStackProbe(MachineFunction &MF,
675ffd83dbSDimitry Andric                         MachineBasicBlock &PrologMBB) const override;
680b57cec5SDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
69e8d8bef9SDimitry Andric   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
705ffd83dbSDimitry Andric                                      Register &FrameReg) const override;
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   // Return the byte offset from the incoming stack pointer of Reg's
735ffd83dbSDimitry Andric   // ABI-defined save slot.  Return 0 if no slot is defined for Reg.  Adjust
745ffd83dbSDimitry Andric   // the offset in case MF has packed-stack.
755ffd83dbSDimitry Andric   unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
76480093f4SDimitry Andric 
775ffd83dbSDimitry Andric   bool usePackedStack(MachineFunction &MF) const;
78e8d8bef9SDimitry Andric 
79e8d8bef9SDimitry Andric   // Return the offset of the backchain.
80e8d8bef9SDimitry Andric   unsigned getBackchainOffset(MachineFunction &MF) const {
81e8d8bef9SDimitry Andric     // The back chain is stored topmost with packed-stack.
82fe6060f1SDimitry Andric     return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
83e8d8bef9SDimitry Andric   }
84*349cc55cSDimitry Andric 
85*349cc55cSDimitry Andric   // Get or create the frame index of where the old frame pointer is stored.
86*349cc55cSDimitry Andric   int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
87*349cc55cSDimitry Andric };
88*349cc55cSDimitry Andric 
89*349cc55cSDimitry Andric class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
90*349cc55cSDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
91*349cc55cSDimitry Andric 
92*349cc55cSDimitry Andric public:
93*349cc55cSDimitry Andric   SystemZXPLINKFrameLowering();
94*349cc55cSDimitry Andric 
95*349cc55cSDimitry Andric   bool
96*349cc55cSDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
97*349cc55cSDimitry Andric                               const TargetRegisterInfo *TRI,
98*349cc55cSDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
99*349cc55cSDimitry Andric 
100*349cc55cSDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
101*349cc55cSDimitry Andric                             RegScavenger *RS) const override;
102*349cc55cSDimitry Andric 
103*349cc55cSDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
104*349cc55cSDimitry Andric                                  MachineBasicBlock::iterator MBBI,
105*349cc55cSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
106*349cc55cSDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
107*349cc55cSDimitry Andric 
108*349cc55cSDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
109*349cc55cSDimitry Andric 
110*349cc55cSDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
111*349cc55cSDimitry Andric 
112*349cc55cSDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
1130b57cec5SDimitry Andric };
1140b57cec5SDimitry Andric } // end namespace llvm
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric #endif
117