xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZFrameLowering.h (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 SystemZSubtarget;
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric class SystemZFrameLowering : public TargetFrameLowering {
23349cc55cSDimitry Andric public:
24349cc55cSDimitry Andric   SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl,
25349cc55cSDimitry Andric                        bool StackReal);
26349cc55cSDimitry Andric 
27349cc55cSDimitry Andric   static std::unique_ptr<SystemZFrameLowering>
28349cc55cSDimitry Andric   create(const SystemZSubtarget &STI);
29349cc55cSDimitry Andric 
30349cc55cSDimitry Andric   // Override TargetFrameLowering.
314824e7fdSDimitry Andric   bool allocateScavengingFrameIndexesNearIncomingSP(
324824e7fdSDimitry Andric     const MachineFunction &MF) const override {
334824e7fdSDimitry Andric     // SystemZ wants normal register scavenging slots, as close to the stack or
344824e7fdSDimitry Andric     // frame pointer as possible.
354824e7fdSDimitry Andric     // The default implementation assumes an x86-like layout, where the frame
364824e7fdSDimitry Andric     // pointer is at the opposite end of the frame from the stack pointer.
374824e7fdSDimitry Andric     // This meant that when frame pointer elimination was disabled,
384824e7fdSDimitry Andric     // the slots ended up being as close as possible to the incoming
394824e7fdSDimitry Andric     // stack pointer, which is the opposite of what we want on SystemZ.
404824e7fdSDimitry Andric     return false;
414824e7fdSDimitry Andric   }
424824e7fdSDimitry Andric 
43349cc55cSDimitry Andric   bool hasReservedCallFrame(const MachineFunction &MF) const override;
44349cc55cSDimitry Andric   MachineBasicBlock::iterator
45349cc55cSDimitry Andric   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
46349cc55cSDimitry Andric                                 MachineBasicBlock::iterator MI) const override;
47349cc55cSDimitry Andric };
48349cc55cSDimitry Andric 
49349cc55cSDimitry Andric class SystemZELFFrameLowering : public SystemZFrameLowering {
500b57cec5SDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric public:
53349cc55cSDimitry Andric   SystemZELFFrameLowering();
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   // Override TargetFrameLowering.
56480093f4SDimitry Andric   bool
57480093f4SDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
58480093f4SDimitry Andric                               const TargetRegisterInfo *TRI,
59480093f4SDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
600b57cec5SDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
610b57cec5SDimitry Andric                             RegScavenger *RS) const override;
620b57cec5SDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
630b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MBBI,
645ffd83dbSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
650b57cec5SDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
665ffd83dbSDimitry Andric   bool
675ffd83dbSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
680b57cec5SDimitry Andric                               MachineBasicBlock::iterator MBBII,
695ffd83dbSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
705ffd83dbSDimitry Andric                               const TargetRegisterInfo *TRI) const override;
710b57cec5SDimitry Andric   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
720b57cec5SDimitry Andric                                            RegScavenger *RS) const override;
730b57cec5SDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
740b57cec5SDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
755ffd83dbSDimitry Andric   void inlineStackProbe(MachineFunction &MF,
765ffd83dbSDimitry Andric                         MachineBasicBlock &PrologMBB) const override;
770b57cec5SDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
78e8d8bef9SDimitry Andric   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
795ffd83dbSDimitry Andric                                      Register &FrameReg) const override;
801fd87a68SDimitry Andric   void
811fd87a68SDimitry Andric   orderFrameObjects(const MachineFunction &MF,
821fd87a68SDimitry Andric                     SmallVectorImpl<int> &ObjectsToAllocate) const override;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   // Return the byte offset from the incoming stack pointer of Reg's
855ffd83dbSDimitry Andric   // ABI-defined save slot.  Return 0 if no slot is defined for Reg.  Adjust
865ffd83dbSDimitry Andric   // the offset in case MF has packed-stack.
875ffd83dbSDimitry Andric   unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
88480093f4SDimitry Andric 
895ffd83dbSDimitry Andric   bool usePackedStack(MachineFunction &MF) const;
90e8d8bef9SDimitry Andric 
91e8d8bef9SDimitry Andric   // Return the offset of the backchain.
92e8d8bef9SDimitry Andric   unsigned getBackchainOffset(MachineFunction &MF) const {
93e8d8bef9SDimitry Andric     // The back chain is stored topmost with packed-stack.
94fe6060f1SDimitry Andric     return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
95e8d8bef9SDimitry Andric   }
96349cc55cSDimitry Andric 
97349cc55cSDimitry Andric   // Get or create the frame index of where the old frame pointer is stored.
98349cc55cSDimitry Andric   int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
99349cc55cSDimitry Andric };
100349cc55cSDimitry Andric 
101349cc55cSDimitry Andric class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
102349cc55cSDimitry Andric   IndexedMap<unsigned> RegSpillOffsets;
103349cc55cSDimitry Andric 
104349cc55cSDimitry Andric public:
105349cc55cSDimitry Andric   SystemZXPLINKFrameLowering();
106349cc55cSDimitry Andric 
107349cc55cSDimitry Andric   bool
108349cc55cSDimitry Andric   assignCalleeSavedSpillSlots(MachineFunction &MF,
109349cc55cSDimitry Andric                               const TargetRegisterInfo *TRI,
110349cc55cSDimitry Andric                               std::vector<CalleeSavedInfo> &CSI) const override;
111349cc55cSDimitry Andric 
112349cc55cSDimitry Andric   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
113349cc55cSDimitry Andric                             RegScavenger *RS) const override;
114349cc55cSDimitry Andric 
115349cc55cSDimitry Andric   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
116349cc55cSDimitry Andric                                  MachineBasicBlock::iterator MBBI,
117349cc55cSDimitry Andric                                  ArrayRef<CalleeSavedInfo> CSI,
118349cc55cSDimitry Andric                                  const TargetRegisterInfo *TRI) const override;
119349cc55cSDimitry Andric 
1200eae32dcSDimitry Andric   bool
1210eae32dcSDimitry Andric   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
1220eae32dcSDimitry Andric                               MachineBasicBlock::iterator MBBII,
1230eae32dcSDimitry Andric                               MutableArrayRef<CalleeSavedInfo> CSI,
1240eae32dcSDimitry Andric                               const TargetRegisterInfo *TRI) const override;
1250eae32dcSDimitry Andric 
126349cc55cSDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
127349cc55cSDimitry Andric 
128349cc55cSDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
129349cc55cSDimitry Andric 
130*81ad6265SDimitry Andric   void inlineStackProbe(MachineFunction &MF,
131*81ad6265SDimitry Andric                         MachineBasicBlock &PrologMBB) const override;
132*81ad6265SDimitry Andric 
133349cc55cSDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
1340eae32dcSDimitry Andric 
1350eae32dcSDimitry Andric   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
1360eae32dcSDimitry Andric                                            RegScavenger *RS) const override;
1370b57cec5SDimitry Andric };
1380b57cec5SDimitry Andric } // end namespace llvm
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric #endif
141