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() final { return SystemZ::R7D; };
85 
86   int getStackPointerRegister() final { return SystemZ::R4D; };
87 
88   int getFramePointerRegister() final { return SystemZ::R8D; };
89 
90   int getAddressOfCalleeRegister() { return SystemZ::R6D; };
91 
92   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const final;
93 
94   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
95                                        CallingConv::ID CC) const final;
96 
97   int getCallFrameSize() final { return 128; }
98 
99   int getStackPointerBias() final { return 2048; }
100 
101   /// Destroys the object. Bogus destructor overriding base class destructor
102   ~SystemZXPLINK64Registers() = default;
103 };
104 
105 /// ELF calling convention specific use registers
106 /// Particular when on zLinux in 64 bit mode
107 class SystemZELFRegisters : public SystemZCallingConventionRegisters {
108 public:
109   int getReturnFunctionAddressRegister() final { return SystemZ::R14D; };
110 
111   int getStackPointerRegister() final { return SystemZ::R15D; };
112 
113   int getFramePointerRegister() final { return SystemZ::R11D; };
114 
115   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const final;
116 
117   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
118                                        CallingConv::ID CC) const final;
119 
120   int getCallFrameSize() final { return SystemZMC::ELFCallFrameSize; }
121 
122   int getStackPointerBias() final { return 0; }
123 
124   /// Destroys the object. Bogus destructor overriding base class destructor
125   ~SystemZELFRegisters() = default;
126 };
127 
128 struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
129 public:
130   SystemZRegisterInfo(unsigned int RA);
131 
132   /// getPointerRegClass - Return the register class to use to hold pointers.
133   /// This is currently only used by LOAD_STACK_GUARD, which requires a non-%r0
134   /// register, hence ADDR64.
135   const TargetRegisterClass *
136   getPointerRegClass(const MachineFunction &MF,
137                      unsigned Kind=0) const override {
138     return &SystemZ::ADDR64BitRegClass;
139   }
140 
141   /// getCrossCopyRegClass - Returns a legal register class to copy a register
142   /// in the specified class to or from. Returns NULL if it is possible to copy
143   /// between a two registers of the specified class.
144   const TargetRegisterClass *
145   getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
146 
147   bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
148                              SmallVectorImpl<MCPhysReg> &Hints,
149                              const MachineFunction &MF, const VirtRegMap *VRM,
150                              const LiveRegMatrix *Matrix) const override;
151 
152   // Override TargetRegisterInfo.h.
153   bool requiresRegisterScavenging(const MachineFunction &MF) const override {
154     return true;
155   }
156   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override {
157     return true;
158   }
159   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
160   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
161                                        CallingConv::ID CC) const override;
162   BitVector getReservedRegs(const MachineFunction &MF) const override;
163   bool eliminateFrameIndex(MachineBasicBlock::iterator MI,
164                            int SPAdj, unsigned FIOperandNum,
165                            RegScavenger *RS) const override;
166 
167   /// SrcRC and DstRC will be morphed into NewRC if this returns true.
168  bool shouldCoalesce(MachineInstr *MI,
169                       const TargetRegisterClass *SrcRC,
170                       unsigned SubReg,
171                       const TargetRegisterClass *DstRC,
172                       unsigned DstSubReg,
173                       const TargetRegisterClass *NewRC,
174                       LiveIntervals &LIS) const override;
175 
176   Register getFrameRegister(const MachineFunction &MF) const override;
177 };
178 
179 } // end namespace llvm
180 
181 #endif
182