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