OLD | NEW |
1 //===- subzero/src/IceRegistersARM32.h - Register information ---*- C++ -*-===// | 1 //===- subzero/src/IceRegistersARM32.h - Register information ---*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
11 /// \brief Declares the registers and their encodings for ARM32. | 11 /// \brief Declares the registers and their encodings for ARM32. |
12 /// | 12 /// |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #ifndef SUBZERO_SRC_ICEREGISTERSARM32_H | 15 #ifndef SUBZERO_SRC_ICEREGISTERSARM32_H |
16 #define SUBZERO_SRC_ICEREGISTERSARM32_H | 16 #define SUBZERO_SRC_ICEREGISTERSARM32_H |
17 | 17 |
18 #include "IceDefs.h" | 18 #include "IceDefs.h" |
19 #include "IceInstARM32.def" | 19 #include "IceInstARM32.def" |
20 #include "IceOperand.h" // RC_Target | 20 #include "IceOperand.h" // RC_Target |
21 #include "IceTypes.h" | 21 #include "IceTypes.h" |
22 | 22 |
23 namespace Ice { | 23 namespace Ice { |
24 namespace ARM32 { | 24 namespace ARM32 { |
25 | 25 namespace RegARM32 { |
26 /// SizeOf is used to obtain the size of an initializer list as a constexpr | 26 |
27 /// expression. This is only needed until our C++ library is updated to | 27 /// An enum of every register. The enum value may not match the encoding used |
28 /// C++ 14 -- which defines constexpr members to std::initializer_list. | 28 /// to binary encode register operands in instructions. |
29 class SizeOf { | 29 enum AllRegisters { |
30 SizeOf(const SizeOf &) = delete; | |
31 SizeOf &operator=(const SizeOf &) = delete; | |
32 | |
33 public: | |
34 constexpr SizeOf() : Size(0) {} | |
35 template <typename... T> | |
36 explicit constexpr SizeOf(T...) | |
37 : Size(__length<T...>::value) {} | |
38 constexpr SizeT size() const { return Size; } | |
39 | |
40 private: | |
41 template <typename T, typename... U> struct __length { | |
42 static constexpr std::size_t value = 1 + __length<U...>::value; | |
43 }; | |
44 | |
45 template <typename T> struct __length<T> { | |
46 static constexpr std::size_t value = 1; | |
47 }; | |
48 | |
49 const std::size_t Size; | |
50 }; | |
51 | |
52 class RegARM32 { | |
53 private: | |
54 RegARM32() = delete; | |
55 RegARM32(const RegARM32 &) = delete; | |
56 RegARM32 &operator=(const RegARM32 &) = delete; | |
57 ~RegARM32() = delete; | |
58 | |
59 public: | |
60 /// An enum of every register. The enum value may not match the encoding used | |
61 /// to binary encode register operands in instructions. | |
62 enum AllRegisters { | |
63 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 30 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
64 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 31 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
65 val, | 32 val, |
66 REGARM32_TABLE | 33 REGARM32_TABLE |
67 #undef X | 34 #undef X |
68 Reg_NUM, | 35 Reg_NUM, |
69 #define X(val, init) val init, | 36 #define X(val, init) val init, |
70 REGARM32_TABLE_BOUNDS | 37 REGARM32_TABLE_BOUNDS |
71 #undef X | 38 #undef X |
72 }; | 39 }; |
73 | 40 |
74 /// An enum of GPR Registers. The enum value does match the encoding used to | 41 /// An enum of GPR Registers. The enum value does match the encoding used to |
75 /// binary encode register operands in instructions. | 42 /// binary encode register operands in instructions. |
76 enum GPRRegister { | 43 enum GPRRegister { |
77 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 44 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
78 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 45 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
79 Encoded_##val = encode, | 46 Encoded_##val = encode, |
80 REGARM32_GPR_TABLE | 47 REGARM32_GPR_TABLE |
81 #undef X | 48 #undef X |
82 Encoded_Not_GPR = -1 | 49 Encoded_Not_GPR = -1 |
83 }; | 50 }; |
84 | 51 |
85 /// An enum of FP32 S-Registers. The enum value does match the encoding used | 52 /// An enum of FP32 S-Registers. The enum value does match the encoding used |
86 /// to binary encode register operands in instructions. | 53 /// to binary encode register operands in instructions. |
87 enum SRegister { | 54 enum SRegister { |
88 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 55 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
89 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 56 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
90 Encoded_##val = encode, | 57 Encoded_##val = encode, |
91 REGARM32_FP32_TABLE | 58 REGARM32_FP32_TABLE |
92 #undef X | 59 #undef X |
93 Encoded_Not_SReg = -1 | 60 Encoded_Not_SReg = -1 |
94 }; | 61 }; |
95 | 62 |
96 /// An enum of FP64 D-Registers. The enum value does match the encoding used | 63 /// An enum of FP64 D-Registers. The enum value does match the encoding used |
97 /// to binary encode register operands in instructions. | 64 /// to binary encode register operands in instructions. |
98 enum DRegister { | 65 enum DRegister { |
99 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 66 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
100 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 67 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
101 Encoded_##val = encode, | 68 Encoded_##val = encode, |
102 REGARM32_FP64_TABLE | 69 REGARM32_FP64_TABLE |
103 #undef X | 70 #undef X |
104 Encoded_Not_DReg = -1 | 71 Encoded_Not_DReg = -1 |
105 }; | 72 }; |
106 | 73 |
107 /// An enum of 128-bit Q-Registers. The enum value does match the encoding | 74 /// An enum of 128-bit Q-Registers. The enum value does match the encoding |
108 /// used to binary encode register operands in instructions. | 75 /// used to binary encode register operands in instructions. |
109 enum QRegister { | 76 enum QRegister { |
110 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 77 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
111 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 78 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
112 Encoded_##val = encode, | 79 Encoded_##val = encode, |
113 REGARM32_VEC128_TABLE | 80 REGARM32_VEC128_TABLE |
114 #undef X | 81 #undef X |
115 Encoded_Not_QReg = -1 | 82 Encoded_Not_QReg = -1 |
116 }; | 83 }; |
117 | 84 |
118 static constexpr struct TableType { | 85 extern struct RegTableType { |
119 const char *Name; | 86 const char *Name; |
120 unsigned Encoding : 10; | 87 unsigned Encoding : 10; |
121 unsigned CCArg : 6; | 88 unsigned CCArg : 6; |
122 unsigned Scratch : 1; | 89 unsigned Scratch : 1; |
123 unsigned Preserved : 1; | 90 unsigned Preserved : 1; |
124 unsigned StackPtr : 1; | 91 unsigned StackPtr : 1; |
125 unsigned FramePtr : 1; | 92 unsigned FramePtr : 1; |
126 unsigned IsGPR : 1; | 93 unsigned IsGPR : 1; |
127 unsigned IsInt : 1; | 94 unsigned IsInt : 1; |
128 unsigned IsI64Pair : 1; | 95 unsigned IsI64Pair : 1; |
129 unsigned IsFP32 : 1; | 96 unsigned IsFP32 : 1; |
130 unsigned IsFP64 : 1; | 97 unsigned IsFP64 : 1; |
131 unsigned IsVec128 : 1; | 98 unsigned IsVec128 : 1; |
132 #define NUM_ALIASES_BITS 3 | 99 #define NUM_ALIASES_BITS 3 |
133 SizeT NumAliases : (NUM_ALIASES_BITS + 1); | 100 SizeT NumAliases : (NUM_ALIASES_BITS + 1); |
134 uint16_t Aliases[1 << NUM_ALIASES_BITS]; | 101 uint16_t Aliases[1 << NUM_ALIASES_BITS]; |
135 #undef NUM_ALIASES_BITS | 102 #undef NUM_ALIASES_BITS |
136 } Table[Reg_NUM] = { | 103 } RegTable[Reg_NUM]; |
137 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 104 |
138 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 105 static inline bool isGPRegister(int32_t RegNum) { |
139 { \ | 106 assert(RegNum >= 0); |
140 name, encode, cc_arg, scratch, preserved, stackptr, frameptr, isGPR, \ | 107 assert(RegNum < Reg_NUM); |
141 isInt, isI64Pair, isFP32, isFP64, isVec128, \ | 108 return RegTable[RegNum].IsGPR; |
142 (SizeOf alias_init).size(), alias_init \ | 109 } |
143 } \ | 110 |
144 , | 111 static constexpr inline SizeT getNumGPRegs() { |
145 REGARM32_TABLE | 112 return 0 |
146 #undef X | |
147 }; | |
148 | |
149 static inline void assertRegisterDefined(int32_t RegNum) { | |
150 (void)RegNum; | |
151 assert(RegNum >= 0); | |
152 assert(RegNum < Reg_NUM); | |
153 } | |
154 | |
155 static inline bool isGPRegister(int32_t RegNum) { | |
156 assertRegisterDefined(RegNum); | |
157 return Table[RegNum].IsGPR; | |
158 } | |
159 | |
160 static constexpr SizeT getNumGPRegs() { | |
161 return 0 | |
162 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 113 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
163 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 114 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
164 +(isGPR) | 115 +(isGPR) |
165 REGARM32_TABLE | 116 REGARM32_TABLE |
166 #undef X | 117 #undef X |
167 ; | 118 ; |
168 } | 119 } |
169 | 120 |
170 static inline GPRRegister getEncodedGPR(int32_t RegNum) { | 121 static inline GPRRegister getEncodedGPR(int32_t RegNum) { |
171 assert(isGPRegister(RegNum)); | 122 assert(RegNum >= 0); |
172 return GPRRegister(Table[RegNum].Encoding); | 123 assert(RegNum < Reg_NUM); |
173 } | 124 return GPRRegister(RegTable[RegNum].Encoding); |
174 | 125 } |
175 static constexpr SizeT getNumGPRs() { | 126 |
176 return 0 | 127 static constexpr inline SizeT getNumGPRs() { |
| 128 return 0 |
177 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 129 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
178 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 130 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
179 +(isGPR) | 131 +(isGPR) |
180 REGARM32_TABLE | 132 REGARM32_TABLE |
181 #undef X | 133 #undef X |
182 ; | 134 ; |
183 } | 135 } |
184 | 136 |
185 static inline bool isGPR(SizeT RegNum) { | 137 static inline bool isGPR(int32_t RegNum) { |
186 assertRegisterDefined(RegNum); | 138 assert(RegNum >= 0); |
187 return Table[RegNum].IsGPR; | 139 assert(RegNum < Reg_NUM); |
188 } | 140 return RegTable[RegNum].IsGPR; |
189 | 141 } |
190 static inline IceString getGPRName(SizeT RegNum) { | 142 |
191 assert(isGPR(RegNum)); | 143 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { |
192 return Table[RegNum].Name; | 144 assert(RegNum >= 0); |
193 } | 145 assert(RegNum < Reg_NUM); |
194 | 146 return GPRRegister(RegTable[RegNum].Encoding); |
195 static inline GPRRegister getI64PairFirstGPRNum(int32_t RegNum) { | 147 } |
196 assert(isI64RegisterPair(RegNum)); | 148 |
197 return GPRRegister(Table[RegNum].Encoding); | 149 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { |
198 } | 150 assert(RegNum >= 0); |
199 | 151 assert(RegNum < Reg_NUM); |
200 static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) { | 152 return GPRRegister(RegTable[RegNum].Encoding + 1); |
201 assert(isI64RegisterPair(RegNum)); | 153 } |
202 return GPRRegister(Table[RegNum].Encoding + 1); | 154 |
203 } | 155 static inline bool isI64RegisterPair(int32_t RegNum) { |
204 | 156 assert(RegNum >= 0); |
205 static inline bool isI64RegisterPair(int32_t RegNum) { | 157 assert(RegNum < Reg_NUM); |
206 assertRegisterDefined(RegNum); | 158 return RegTable[RegNum].IsI64Pair; |
207 return Table[RegNum].IsI64Pair; | 159 } |
208 } | 160 |
209 | 161 static inline bool isEncodedSReg(int32_t RegNum) { |
210 static inline bool isEncodedSReg(int32_t RegNum) { | 162 assert(RegNum >= 0); |
211 assertRegisterDefined(RegNum); | 163 assert(RegNum < Reg_NUM); |
212 return Table[RegNum].IsFP32; | 164 return RegTable[RegNum].IsFP32; |
213 } | 165 } |
214 | 166 |
215 static constexpr SizeT getNumSRegs() { | 167 static constexpr inline SizeT getNumSRegs() { |
216 return 0 | 168 return 0 |
217 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 169 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
218 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 170 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
219 +(isFP32) | 171 +(isFP32) |
220 REGARM32_TABLE | 172 REGARM32_TABLE |
221 #undef X | 173 #undef X |
222 ; | 174 ; |
223 } | 175 } |
224 | 176 |
225 static inline IceString getSRegName(SizeT RegNum) { | 177 static inline SRegister getEncodedSReg(int32_t RegNum) { |
226 assert(isEncodedSReg(RegNum)); | 178 assert(RegNum >= 0); |
227 return Table[RegNum].Name; | 179 assert(RegNum < Reg_NUM); |
228 } | 180 return SRegister(RegTable[RegNum].Encoding); |
229 | 181 } |
230 static inline SRegister getEncodedSReg(int32_t RegNum) { | 182 |
231 assert(isEncodedSReg(RegNum)); | 183 static inline bool isEncodedDReg(int32_t RegNum) { |
232 return SRegister(Table[RegNum].Encoding); | 184 assert(RegNum >= 0); |
233 } | 185 assert(RegNum < Reg_NUM); |
234 | 186 return RegTable[RegNum].IsFP64; |
235 static inline bool isEncodedDReg(int32_t RegNum) { | 187 } |
236 assertRegisterDefined(RegNum); | 188 |
237 return Table[RegNum].IsFP64; | 189 static constexpr inline SizeT getNumDRegs() { |
238 } | 190 return 0 |
239 | |
240 static constexpr inline SizeT getNumDRegs() { | |
241 return 0 | |
242 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 191 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
243 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 192 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
244 +(isFP64) | 193 +(isFP64) |
245 REGARM32_TABLE | 194 REGARM32_TABLE |
246 #undef X | 195 #undef X |
247 ; | 196 ; |
248 } | 197 } |
249 | 198 |
250 static inline DRegister getEncodedDReg(int32_t RegNum) { | 199 static inline DRegister getEncodedDReg(int32_t RegNum) { |
251 assert(isEncodedDReg(RegNum)); | 200 assert(RegNum >= 0); |
252 return DRegister(Table[RegNum].Encoding); | 201 assert(RegNum < Reg_NUM); |
253 } | 202 return DRegister(RegTable[RegNum].Encoding); |
254 | 203 } |
255 static inline bool isEncodedQReg(int32_t RegNum) { | 204 |
256 assertRegisterDefined(RegNum); | 205 static inline bool isEncodedQReg(int32_t RegNum) { |
257 return Table[RegNum].IsVec128; | 206 assert(RegNum >= 0); |
258 } | 207 assert(RegNum < Reg_NUM); |
259 | 208 return RegTable[RegNum].IsVec128; |
260 static inline QRegister getEncodedQReg(int32_t RegNum) { | 209 } |
261 assert(isEncodedQReg(RegNum)); | 210 |
262 return QRegister(Table[RegNum].Encoding); | 211 static inline QRegister getEncodedQReg(int32_t RegNum) { |
263 } | 212 assert(isEncodedQReg(RegNum)); |
264 | 213 return QRegister(RegTable[RegNum].Encoding); |
265 static inline IceString getRegName(int32_t RegNum) { | 214 } |
266 assertRegisterDefined(RegNum); | 215 |
267 return Table[RegNum].Name; | 216 static inline IceString getRegName(int32_t RegNum) { |
268 } | 217 assert(RegNum >= 0); |
269 }; | 218 assert(RegNum < Reg_NUM); |
| 219 return RegTable[RegNum].Name; |
| 220 } |
270 | 221 |
271 // Extend enum RegClass with ARM32-specific register classes (if any). | 222 // Extend enum RegClass with ARM32-specific register classes (if any). |
272 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; | 223 enum RegClassARM32 : uint8_t { RCARM32_NUM = RC_Target }; |
273 | 224 |
| 225 } // end of namespace RegARM32 |
274 } // end of namespace ARM32 | 226 } // end of namespace ARM32 |
275 } // end of namespace Ice | 227 } // end of namespace Ice |
276 | 228 |
277 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H | 229 #endif // SUBZERO_SRC_ICEREGISTERSARM32_H |
OLD | NEW |