xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZFrameLowering.h (revision 0eae32dcef82f6f06de6419a0d623d7def0cc8f6)
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"
13349cc55cSDimitry Andric #include "SystemZInstrBuilder.h"
14349cc55cSDimitry 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 {
24349cc55cSDimitry Andric public:
25349cc55cSDimitry Andric   SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl,
26349cc55cSDimitry Andric                        bool StackReal);
27349cc55cSDimitry Andric 
28349cc55cSDimitry Andric   static std::unique_ptr<SystemZFrameLowering>
29349cc55cSDimitry Andric   create(const SystemZSubtarget &STI);
30349cc55cSDimitry Andric 
31349cc55cSDimitry Andric   // Override TargetFrameLowering.
324824e7fdSDimitry Andric   bool allocateScavengingFrameIndexesNearIncomingSP(
334824e7fdSDimitry Andric     const MachineFunction &MF) const override {
344824e7fdSDimitry Andric     // SystemZ wants normal register scavenging slots, as close to the stack or
354824e7fdSDimitry Andric     // frame pointer as possible.
364824e7fdSDimitry Andric     // The default implementation assumes an x86-like layout, where the frame
374824e7fdSDimitry Andric     // pointer is at the opposite end of the frame from the stack pointer.
384824e7fdSDimitry Andric     // This meant that when frame pointer elimination was disabled,
394824e7fdSDimitry Andric     // the slots ended up being as close as possible to the incoming
404824e7fdSDimitry Andric     // stack pointer, which is the opposite of what we want on SystemZ.
414824e7fdSDimitry Andric     return false;
424824e7fdSDimitry Andric   }
434824e7fdSDimitry Andric 
44349cc55cSDimitry Andric   bool hasReservedCallFrame(const MachineFunction &MF) const override;
45349cc55cSDimitry Andric   MachineBasicBlock::iterator
46349cc55cSDimitry Andric   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
47349cc55cSDimitry Andric                                 MachineBasicBlock::iterator MI) const override;
48349cc55cSDimitry Andric };
49349cc55cSDimitry Andric 
50349cc55cSDimitry Andric class SystemZELFFrameLowering : public SystemZFrameLowering {
510b57cec5SDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric public:
54349cc55cSDimitry Andric   SystemZELFFrameLowering();
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   // Override TargetFrameLowering.
57480093f4SDimitry Andric   bool
58480093f4SDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
59480093f4SDimitry Andric                               const TargetRegisterInfo *TRI,
60480093f4SDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
610b57cec5SDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
620b57cec5SDimitry Andric                             RegScavenger *RS) const override;
630b57cec5SDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
640b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MBBI,
655ffd83dbSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
660b57cec5SDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
675ffd83dbSDimitry Andric   bool
685ffd83dbSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
690b57cec5SDimitry Andric                               MachineBasicBlock::iterator MBBII,
705ffd83dbSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
715ffd83dbSDimitry Andric                               const TargetRegisterInfo *TRI) const override;
720b57cec5SDimitry Andric   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
730b57cec5SDimitry Andric                                            RegScavenger *RS) const override;
740b57cec5SDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
750b57cec5SDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
765ffd83dbSDimitry Andric   void inlineStackProbe(MachineFunction &MF,
775ffd83dbSDimitry Andric                         MachineBasicBlock &PrologMBB) const override;
780b57cec5SDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
79e8d8bef9SDimitry Andric   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
805ffd83dbSDimitry Andric                                      Register &FrameReg) const override;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   // Return the byte offset from the incoming stack pointer of Reg's
835ffd83dbSDimitry Andric   // ABI-defined save slot.  Return 0 if no slot is defined for Reg.  Adjust
845ffd83dbSDimitry Andric   // the offset in case MF has packed-stack.
855ffd83dbSDimitry Andric   unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
86480093f4SDimitry Andric 
875ffd83dbSDimitry Andric   bool usePackedStack(MachineFunction &MF) const;
88e8d8bef9SDimitry Andric 
89e8d8bef9SDimitry Andric   // Return the offset of the backchain.
90e8d8bef9SDimitry Andric   unsigned getBackchainOffset(MachineFunction &MF) const {
91e8d8bef9SDimitry Andric     // The back chain is stored topmost with packed-stack.
92fe6060f1SDimitry Andric     return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
93e8d8bef9SDimitry Andric   }
94349cc55cSDimitry Andric 
95349cc55cSDimitry Andric   // Get or create the frame index of where the old frame pointer is stored.
96349cc55cSDimitry Andric   int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
97349cc55cSDimitry Andric };
98349cc55cSDimitry Andric 
99349cc55cSDimitry Andric class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
100349cc55cSDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
101349cc55cSDimitry Andric 
102349cc55cSDimitry Andric public:
103349cc55cSDimitry Andric   SystemZXPLINKFrameLowering();
104349cc55cSDimitry Andric 
105349cc55cSDimitry Andric   bool
106349cc55cSDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
107349cc55cSDimitry Andric                               const TargetRegisterInfo *TRI,
108349cc55cSDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
109349cc55cSDimitry Andric 
110349cc55cSDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
111349cc55cSDimitry Andric                             RegScavenger *RS) const override;
112349cc55cSDimitry Andric 
113349cc55cSDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
114349cc55cSDimitry Andric                                  MachineBasicBlock::iterator MBBI,
115349cc55cSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
116349cc55cSDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
117349cc55cSDimitry Andric 
118*0eae32dcSDimitry Andric   bool
119*0eae32dcSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
120*0eae32dcSDimitry Andric                               MachineBasicBlock::iterator MBBII,
121*0eae32dcSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
122*0eae32dcSDimitry Andric                               const TargetRegisterInfo *TRI) const override;
123*0eae32dcSDimitry Andric 
124349cc55cSDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
125349cc55cSDimitry Andric 
126349cc55cSDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
127349cc55cSDimitry Andric 
128349cc55cSDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
129*0eae32dcSDimitry Andric 
130*0eae32dcSDimitry Andric   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
131*0eae32dcSDimitry Andric                                            RegScavenger *RS) const override;
1320b57cec5SDimitry Andric };
1330b57cec5SDimitry Andric } // end namespace llvm
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric #endif
136