xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h (revision fcaf7f8644a9988098ac6be2165bce3ea4786e91)
1 //===-- SystemZRegisterInfo.h - SystemZ register information ----*- 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_SYSTEMZREGISTERINFO_H
10 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZREGISTERINFO_H
11 
12 #include "SystemZ.h"
13 #include "llvm/CodeGen/TargetFrameLowering.h"
14 #include "llvm/CodeGen/TargetRegisterInfo.h"
15 
16 #define GET_REGINFO_HEADER
17 #include "SystemZGenRegisterInfo.inc"
18 
19 namespace llvm {
20 
21 class LiveIntervals;
22 
23 namespace SystemZ {
24 // Return the subreg to use for referring to the even and odd registers
25 // in a GR128 pair.  Is32Bit says whether we want a GR32 or GR64.
26 inline unsigned even128(bool Is32bit) {
27   return Is32bit ? subreg_hl32 : subreg_h64;
28 }
29 inline unsigned odd128(bool Is32bit) {
30   return Is32bit ? subreg_l32 : subreg_l64;
31 }
32 
33 // Reg should be a 32-bit GPR.  Return true if it is a high register rather
34 // than a low register.
35 inline bool isHighReg(unsigned int Reg) {
36   if (SystemZ::GRH32BitRegClass.contains(Reg))
37     return true;
38   assert(SystemZ::GR32BitRegClass.contains(Reg) && "Invalid GRX32");
39   return false;
40 }
41 } // end namespace SystemZ
42 
43 /// A SystemZ-specific class detailing special use registers
44 /// particular for calling conventions.
45 /// It is abstract, all calling conventions must override and
46 /// define the pure virtual member function defined in this class.
47 class SystemZCallingConventionRegisters {
48 
49 public:
50   /// \returns the register that keeps the return function address.
51   virtual int getReturnFunctionAddressRegister() = 0;
52 
53   /// \returns the register that keeps the
54   /// stack pointer address.
55   virtual int getStackPointerRegister() = 0;
56 
57   /// \returns the register that keeps the
58   /// frame pointer address.
59   virtual int getFramePointerRegister() = 0;
60 
61   /// \returns an array of all the callee saved registers.
62   virtual const MCPhysReg *
63   getCalleeSavedRegs(const MachineFunction *MF) const = 0;
64 
65   /// \returns the mask of all the call preserved registers.
66   virtual const uint32_t *getCallPreservedMask(const MachineFunction &MF,
67                                                CallingConv::ID CC) const = 0;
68 
69   /// \returns the offset to the locals area.
70   virtual int getCallFrameSize() = 0;
71 
72   /// \returns the stack pointer bias.
73   virtual int getStackPointerBias() = 0;
74 
75   /// Destroys the object. Bogus destructor allowing derived classes
76   /// to override it.
77   virtual ~SystemZCallingConventionRegisters() = default;
78 };
79 
80 /// XPLINK64 calling convention specific use registers
81 /// Particular to z/OS when in 64 bit mode
82 class SystemZXPLINK64Registers : public SystemZCallingConventionRegisters {
83 public:
84   int getReturnFunctionAddressRegister() override final {
85     return SystemZ::R7D;
86   };
87 
88   int getStackPointerRegister() override final { return SystemZ::R4D; };
89 
90   int getFramePointerRegister() override final { return SystemZ::R8D; };
91 
92   int getAddressOfCalleeRegister() { return SystemZ::R6D; };
93 
94   const MCPhysReg *
95   getCalleeSavedRegs(const MachineFunction *MF) const override final;
96 
97   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
98                                        CallingConv::ID CC) const override final;
99 
100   int getCallFrameSize() override final { return 128; }
101 
102   int getStackPointerBias() override final { return 2048; }
103 
104   /// Destroys the object. Bogus destructor overriding base class destructor
105   ~SystemZXPLINK64Registers() = default;
106 };
107 
108 /// ELF calling convention specific use registers
109 /// Particular when on zLinux in 64 bit mode
110 class SystemZELFRegisters : public SystemZCallingConventionRegisters {
111 public:
112   int getReturnFunctionAddressRegister() override final {
113     return SystemZ::R14D;
114   };
115 
116   int getStackPointerRegister() override final { return SystemZ::R15D; };
117 
118   int getFramePointerRegister() override final { return SystemZ::R11D; };
119 
120   const MCPhysReg *
121   getCalleeSavedRegs(const MachineFunction *MF) const override final;
122 
123   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
124                                        CallingConv::ID CC) const override final;
125 
126   int getCallFrameSize() override final { return SystemZMC::ELFCallFrameSize; }
127 
128   int getStackPointerBias() override final { return 0; }
129 
130   /// Destroys the object. Bogus destructor overriding base class destructor
131   ~SystemZELFRegisters() = default;
132 };
133 
134 struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
135 public:
136   SystemZRegisterInfo(unsigned int RA);
137 
138   /// getPointerRegClass - Return the register class to use to hold pointers.
139   /// This is currently only used by LOAD_STACK_GUARD, which requires a non-%r0
140   /// register, hence ADDR64.
141   const TargetRegisterClass *
142   getPointerRegClass(const MachineFunction &MF,
143                      unsigned Kind=0) const override {
144     return &SystemZ::ADDR64BitRegClass;
145   }
146 
147   /// getCrossCopyRegClass - Returns a legal register class to copy a register
148   /// in the specified class to or from. Returns NULL if it is possible to copy
149   /// between a two registers of the specified class.
150   const TargetRegisterClass *
151   getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
152 
153   bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
154                              SmallVectorImpl<MCPhysReg> &Hints,
155                              const MachineFunction &MF, const VirtRegMap *VRM,
156                              const LiveRegMatrix *Matrix) const override;
157 
158   // Override TargetRegisterInfo.h.
159   bool requiresRegisterScavenging(const MachineFunction &MF) const override {
160     return true;
161   }
162   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override {
163     return true;
164   }
165   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
166   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
167                                        CallingConv::ID CC) const override;
168   BitVector getReservedRegs(const MachineFunction &MF) const override;
169   void eliminateFrameIndex(MachineBasicBlock::iterator MI,
170                            int SPAdj, unsigned FIOperandNum,
171                            RegScavenger *RS) const override;
172 
173   /// SrcRC and DstRC will be morphed into NewRC if this returns true.
174  bool shouldCoalesce(MachineInstr *MI,
175                       const TargetRegisterClass *SrcRC,
176                       unsigned SubReg,
177                       const TargetRegisterClass *DstRC,
178                       unsigned DstSubReg,
179                       const TargetRegisterClass *NewRC,
180                       LiveIntervals &LIS) const override;
181 
182   Register getFrameRegister(const MachineFunction &MF) const override;
183 };
184 
185 } // end namespace llvm
186 
187 #endif
188