1 //===-- SystemZFrameLowering.h - Frame lowering for SystemZ -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
10 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
11 
12 #include "MCTargetDesc/SystemZMCTargetDesc.h"
13 #include "SystemZInstrBuilder.h"
14 #include "SystemZMachineFunctionInfo.h"
15 #include "llvm/ADT/IndexedMap.h"
16 #include "llvm/CodeGen/TargetFrameLowering.h"
17 #include "llvm/Support/TypeSize.h"
18 
19 namespace llvm {
20 class SystemZSubtarget;
21 
22 class SystemZFrameLowering : public TargetFrameLowering {
23 public:
24   SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl,
25                        bool StackReal);
26 
27   static std::unique_ptr<SystemZFrameLowering>
28   create(const SystemZSubtarget &STI);
29 
30   // Override TargetFrameLowering.
31   bool allocateScavengingFrameIndexesNearIncomingSP(
32     const MachineFunction &MF) const override {
33     // SystemZ wants normal register scavenging slots, as close to the stack or
34     // frame pointer as possible.
35     // The default implementation assumes an x86-like layout, where the frame
36     // pointer is at the opposite end of the frame from the stack pointer.
37     // This meant that when frame pointer elimination was disabled,
38     // the slots ended up being as close as possible to the incoming
39     // stack pointer, which is the opposite of what we want on SystemZ.
40     return false;
41   }
42 
43   bool hasReservedCallFrame(const MachineFunction &MF) const override;
44   MachineBasicBlock::iterator
45   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
46                                 MachineBasicBlock::iterator MI) const override;
47 };
48 
49 class SystemZELFFrameLowering : public SystemZFrameLowering {
50   IndexedMap<unsigned> RegSpillOffsets;
51 
52 public:
53   SystemZELFFrameLowering();
54 
55   // Override TargetFrameLowering.
56   bool
57   assignCalleeSavedSpillSlots(MachineFunction &MF,
58                               const TargetRegisterInfo *TRI,
59                               std::vector<CalleeSavedInfo> &CSI) const override;
60   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
61                             RegScavenger *RS) const override;
62   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
63                                  MachineBasicBlock::iterator MBBI,
64                                  ArrayRef<CalleeSavedInfo> CSI,
65                                  const TargetRegisterInfo *TRI) const override;
66   bool
67   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
68                               MachineBasicBlock::iterator MBBII,
69                               MutableArrayRef<CalleeSavedInfo> CSI,
70                               const TargetRegisterInfo *TRI) const override;
71   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
72                                            RegScavenger *RS) const override;
73   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
74   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
75   void inlineStackProbe(MachineFunction &MF,
76                         MachineBasicBlock &PrologMBB) const override;
77   bool hasFP(const MachineFunction &MF) const override;
78   StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
79                                      Register &FrameReg) const override;
80   void
81   orderFrameObjects(const MachineFunction &MF,
82                     SmallVectorImpl<int> &ObjectsToAllocate) const override;
83 
84   // Return the byte offset from the incoming stack pointer of Reg's
85   // ABI-defined save slot.  Return 0 if no slot is defined for Reg.  Adjust
86   // the offset in case MF has packed-stack.
87   unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
88 
89   bool usePackedStack(MachineFunction &MF) const;
90 
91   // Return the offset of the backchain.
92   unsigned getBackchainOffset(MachineFunction &MF) const {
93     // The back chain is stored topmost with packed-stack.
94     return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
95   }
96 
97   // Get or create the frame index of where the old frame pointer is stored.
98   int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
99 };
100 
101 class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
102   IndexedMap<unsigned> RegSpillOffsets;
103 
104 public:
105   SystemZXPLINKFrameLowering();
106 
107   bool
108   assignCalleeSavedSpillSlots(MachineFunction &MF,
109                               const TargetRegisterInfo *TRI,
110                               std::vector<CalleeSavedInfo> &CSI) const override;
111 
112   void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
113                             RegScavenger *RS) const override;
114 
115   bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
116                                  MachineBasicBlock::iterator MBBI,
117                                  ArrayRef<CalleeSavedInfo> CSI,
118                                  const TargetRegisterInfo *TRI) const override;
119 
120   bool
121   restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
122                               MachineBasicBlock::iterator MBBII,
123                               MutableArrayRef<CalleeSavedInfo> CSI,
124                               const TargetRegisterInfo *TRI) const override;
125 
126   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
127 
128   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
129 
130   bool hasFP(const MachineFunction &MF) const override;
131 
132   void processFunctionBeforeFrameFinalized(MachineFunction &MF,
133                                            RegScavenger *RS) const override;
134 };
135 } // end namespace llvm
136 
137 #endif
138