1 /*
2 * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef CPU_RISCV_REGISTER_RISCV_HPP
27 #define CPU_RISCV_REGISTER_RISCV_HPP
28
29 #include "asm/register.hpp"
30 #include "utilities/checkedCast.hpp"
31 #include "utilities/powerOfTwo.hpp"
32
33 #define CSR_FFLAGS 0x001 // Floating-Point Accrued Exceptions.
34 #define CSR_FRM 0x002 // Floating-Point Dynamic Rounding Mode.
35 #define CSR_FCSR 0x003 // Floating-Point Control and Status Register (frm + fflags).
36 #define CSR_VSTART 0x008 // Vector start position
37 #define CSR_VXSAT 0x009 // Fixed-Point Saturate Flag
38 #define CSR_VXRM 0x00A // Fixed-Point Rounding Mode
39 #define CSR_VCSR 0x00F // Vector control and status register
40 #define CSR_VL 0xC20 // Vector length
41 #define CSR_VTYPE 0xC21 // Vector data type register
42 #define CSR_VLENB 0xC22 // VLEN/8 (vector register length in bytes)
43 #define CSR_CYCLE 0xc00 // Cycle counter for RDCYCLE instruction.
44 #define CSR_TIME 0xc01 // Timer for RDTIME instruction.
45 #define CSR_INSTRET 0xc02 // Instructions-retired counter for RDINSTRET instruction.
46
47 class VMRegImpl;
48 typedef VMRegImpl* VMReg;
49
50 class Register {
51 private:
52 int _encoding;
53
54 constexpr explicit Register(int encoding) : _encoding(encoding) {}
55
56 public:
57 enum {
58 number_of_registers = 32,
59 max_slots_per_register = 2,
60
61 // integer registers x8 - x15 and floating-point registers f8 - f15 are allocatable
62 // for compressed instructions. See Table 17.2 in spec.
63 compressed_register_base = 8,
64 compressed_register_top = 15,
65 };
66
67 class RegisterImpl: public AbstractRegisterImpl {
68 friend class Register;
69
70 static constexpr const RegisterImpl* first();
71
72 public:
73 // accessors
74 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
75 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
76 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
77
78 // for rvc
79 int compressed_raw_encoding() const {
80 return raw_encoding() - compressed_register_base;
81 }
82
83 int compressed_encoding() const {
84 assert(is_compressed_valid(), "invalid compressed register");
85 return encoding() - compressed_register_base;
86 }
87
88 bool is_compressed_valid() const {
89 return raw_encoding() >= compressed_register_base &&
90 raw_encoding() <= compressed_register_top;
91 }
92
93 // derived registers, offsets, and addresses
94 inline Register successor() const;
95
96 VMReg as_VMReg() const;
97
98 const char* name() const;
99 };
100
101 inline friend constexpr Register as_Register(int encoding);
102
103 constexpr Register() : _encoding(-1) {} // noreg
104
105 int operator==(const Register r) const { return _encoding == r._encoding; }
106 int operator!=(const Register r) const { return _encoding != r._encoding; }
107
108 constexpr const RegisterImpl* operator->() const { return RegisterImpl::first() + _encoding; }
109
110 // Actually available GP registers for use, depending on actual CPU capabilities and flags.
111 static int available_gp_registers() {
112 return number_of_registers;
113 }
114 };
115
116 extern Register::RegisterImpl all_RegisterImpls[Register::number_of_registers + 1] INTERNAL_VISIBILITY;
117
118 inline constexpr const Register::RegisterImpl* Register::RegisterImpl::first() {
119 return all_RegisterImpls + 1;
120 }
121
122 constexpr Register noreg = Register();
123
124 inline constexpr Register as_Register(int encoding) {
125 if (0 <= encoding && encoding < Register::number_of_registers) {
126 return Register(encoding);
127 }
128 return noreg;
129 }
130
131 inline Register Register::RegisterImpl::successor() const {
132 assert(is_valid(), "sanity");
133 return as_Register(encoding() + 1);
134 }
135
136 // The integer registers of RISCV architecture
137 constexpr Register x0 = as_Register( 0);
138 constexpr Register x1 = as_Register( 1);
139 constexpr Register x2 = as_Register( 2);
140 constexpr Register x3 = as_Register( 3);
141 constexpr Register x4 = as_Register( 4);
142 constexpr Register x5 = as_Register( 5);
143 constexpr Register x6 = as_Register( 6);
144 constexpr Register x7 = as_Register( 7);
145 constexpr Register x8 = as_Register( 8);
146 constexpr Register x9 = as_Register( 9);
147 constexpr Register x10 = as_Register(10);
148 constexpr Register x11 = as_Register(11);
149 constexpr Register x12 = as_Register(12);
150 constexpr Register x13 = as_Register(13);
151 constexpr Register x14 = as_Register(14);
152 constexpr Register x15 = as_Register(15);
153 constexpr Register x16 = as_Register(16);
154 constexpr Register x17 = as_Register(17);
155 constexpr Register x18 = as_Register(18);
156 constexpr Register x19 = as_Register(19);
157 constexpr Register x20 = as_Register(20);
158 constexpr Register x21 = as_Register(21);
159 constexpr Register x22 = as_Register(22);
160 constexpr Register x23 = as_Register(23);
161 constexpr Register x24 = as_Register(24);
162 constexpr Register x25 = as_Register(25);
163 constexpr Register x26 = as_Register(26);
164 constexpr Register x27 = as_Register(27);
165 constexpr Register x28 = as_Register(28);
166 constexpr Register x29 = as_Register(29);
167 constexpr Register x30 = as_Register(30);
168 constexpr Register x31 = as_Register(31);
169
170 // The implementation of floating point registers for the architecture
171 class FloatRegister {
172 private:
173 int _encoding;
174
175 constexpr explicit FloatRegister(int encoding) : _encoding(encoding) {}
176
177 public:
178 inline friend constexpr FloatRegister as_FloatRegister(int encoding);
179
180 enum {
181 number_of_registers = 32,
182 max_slots_per_register = 2,
183
184 // float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec.
185 compressed_register_base = 8,
186 compressed_register_top = 15,
187 };
188
189 class FloatRegisterImpl: public AbstractRegisterImpl {
190 friend class FloatRegister;
191
192 static constexpr const FloatRegisterImpl* first();
193
194 public:
195 // accessors
196 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
197 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
198 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
199
200 // for rvc
201 int compressed_raw_encoding() const {
202 return raw_encoding() - compressed_register_base;
203 }
204
205 int compressed_encoding() const {
206 assert(is_compressed_valid(), "invalid compressed register");
207 return encoding() - compressed_register_base;
208 }
209
210 bool is_compressed_valid() const {
211 return raw_encoding() >= compressed_register_base &&
212 raw_encoding() <= compressed_register_top;
213 }
214
215 // derived registers, offsets, and addresses
216 inline FloatRegister successor() const;
217
218 VMReg as_VMReg() const;
219
220 const char* name() const;
221 };
222
223 constexpr FloatRegister() : _encoding(-1) {} // fnoreg
224
225 int operator==(const FloatRegister r) const { return _encoding == r._encoding; }
226 int operator!=(const FloatRegister r) const { return _encoding != r._encoding; }
227
228 constexpr const FloatRegisterImpl* operator->() const { return FloatRegisterImpl::first() + _encoding; }
229 };
230
231 extern FloatRegister::FloatRegisterImpl all_FloatRegisterImpls[FloatRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
232
233 inline constexpr const FloatRegister::FloatRegisterImpl* FloatRegister::FloatRegisterImpl::first() {
234 return all_FloatRegisterImpls + 1;
235 }
236
237 constexpr FloatRegister fnoreg = FloatRegister();
238
239 inline constexpr FloatRegister as_FloatRegister(int encoding) {
240 if (0 <= encoding && encoding < FloatRegister::number_of_registers) {
241 return FloatRegister(encoding);
242 }
243 return fnoreg;
244 }
245
246 inline FloatRegister FloatRegister::FloatRegisterImpl::successor() const {
247 assert(is_valid(), "sanity");
248 return as_FloatRegister(encoding() + 1);
249 }
250
251 // The float registers of the RISCV architecture
252 constexpr FloatRegister f0 = as_FloatRegister( 0);
253 constexpr FloatRegister f1 = as_FloatRegister( 1);
254 constexpr FloatRegister f2 = as_FloatRegister( 2);
255 constexpr FloatRegister f3 = as_FloatRegister( 3);
256 constexpr FloatRegister f4 = as_FloatRegister( 4);
257 constexpr FloatRegister f5 = as_FloatRegister( 5);
258 constexpr FloatRegister f6 = as_FloatRegister( 6);
259 constexpr FloatRegister f7 = as_FloatRegister( 7);
260 constexpr FloatRegister f8 = as_FloatRegister( 8);
261 constexpr FloatRegister f9 = as_FloatRegister( 9);
262 constexpr FloatRegister f10 = as_FloatRegister(10);
263 constexpr FloatRegister f11 = as_FloatRegister(11);
264 constexpr FloatRegister f12 = as_FloatRegister(12);
265 constexpr FloatRegister f13 = as_FloatRegister(13);
266 constexpr FloatRegister f14 = as_FloatRegister(14);
267 constexpr FloatRegister f15 = as_FloatRegister(15);
268 constexpr FloatRegister f16 = as_FloatRegister(16);
269 constexpr FloatRegister f17 = as_FloatRegister(17);
270 constexpr FloatRegister f18 = as_FloatRegister(18);
271 constexpr FloatRegister f19 = as_FloatRegister(19);
272 constexpr FloatRegister f20 = as_FloatRegister(20);
273 constexpr FloatRegister f21 = as_FloatRegister(21);
274 constexpr FloatRegister f22 = as_FloatRegister(22);
275 constexpr FloatRegister f23 = as_FloatRegister(23);
276 constexpr FloatRegister f24 = as_FloatRegister(24);
277 constexpr FloatRegister f25 = as_FloatRegister(25);
278 constexpr FloatRegister f26 = as_FloatRegister(26);
279 constexpr FloatRegister f27 = as_FloatRegister(27);
280 constexpr FloatRegister f28 = as_FloatRegister(28);
281 constexpr FloatRegister f29 = as_FloatRegister(29);
282 constexpr FloatRegister f30 = as_FloatRegister(30);
283 constexpr FloatRegister f31 = as_FloatRegister(31);
284
285 // The implementation of vector registers for RVV
286 class VectorRegister {
287 int _encoding;
288
289 constexpr explicit VectorRegister(int encoding) : _encoding(encoding) {}
290
291 public:
292 inline friend constexpr VectorRegister as_VectorRegister(int encoding);
293
294 enum {
295 number_of_registers = 32,
296 max_slots_per_register = 4
297 };
298
299 class VectorRegisterImpl: public AbstractRegisterImpl {
300 friend class VectorRegister;
301
302 static constexpr const VectorRegisterImpl* first();
303
304 public:
305 // accessors
306 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
307 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
308 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
309
310 // derived registers, offsets, and addresses
311 inline VectorRegister successor() const;
312
313 VMReg as_VMReg() const;
314
315 const char* name() const;
316 };
317
318 constexpr VectorRegister() : _encoding(-1) {} // vnoreg
319
320 int operator==(const VectorRegister r) const { return _encoding == r._encoding; }
321 int operator!=(const VectorRegister r) const { return _encoding != r._encoding; }
322
323 constexpr const VectorRegisterImpl* operator->() const { return VectorRegisterImpl::first() + _encoding; }
324 };
325
326 extern VectorRegister::VectorRegisterImpl all_VectorRegisterImpls[VectorRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
327
328 inline constexpr const VectorRegister::VectorRegisterImpl* VectorRegister::VectorRegisterImpl::first() {
329 return all_VectorRegisterImpls + 1;
330 }
331
332 constexpr VectorRegister vnoreg = VectorRegister();
333
334 inline constexpr VectorRegister as_VectorRegister(int encoding) {
335 if (0 <= encoding && encoding < VectorRegister::number_of_registers) {
336 return VectorRegister(encoding);
337 }
338 return vnoreg;
339 }
340
341 inline VectorRegister VectorRegister::VectorRegisterImpl::successor() const {
342 assert(is_valid(), "sanity");
343 return as_VectorRegister(encoding() + 1);
344 }
345
346 // The vector registers of RVV
347 constexpr VectorRegister v0 = as_VectorRegister( 0);
348 constexpr VectorRegister v1 = as_VectorRegister( 1);
349 constexpr VectorRegister v2 = as_VectorRegister( 2);
350 constexpr VectorRegister v3 = as_VectorRegister( 3);
351 constexpr VectorRegister v4 = as_VectorRegister( 4);
352 constexpr VectorRegister v5 = as_VectorRegister( 5);
353 constexpr VectorRegister v6 = as_VectorRegister( 6);
354 constexpr VectorRegister v7 = as_VectorRegister( 7);
355 constexpr VectorRegister v8 = as_VectorRegister( 8);
356 constexpr VectorRegister v9 = as_VectorRegister( 9);
357 constexpr VectorRegister v10 = as_VectorRegister(10);
358 constexpr VectorRegister v11 = as_VectorRegister(11);
359 constexpr VectorRegister v12 = as_VectorRegister(12);
360 constexpr VectorRegister v13 = as_VectorRegister(13);
361 constexpr VectorRegister v14 = as_VectorRegister(14);
362 constexpr VectorRegister v15 = as_VectorRegister(15);
363 constexpr VectorRegister v16 = as_VectorRegister(16);
364 constexpr VectorRegister v17 = as_VectorRegister(17);
365 constexpr VectorRegister v18 = as_VectorRegister(18);
366 constexpr VectorRegister v19 = as_VectorRegister(19);
367 constexpr VectorRegister v20 = as_VectorRegister(20);
368 constexpr VectorRegister v21 = as_VectorRegister(21);
369 constexpr VectorRegister v22 = as_VectorRegister(22);
370 constexpr VectorRegister v23 = as_VectorRegister(23);
371 constexpr VectorRegister v24 = as_VectorRegister(24);
372 constexpr VectorRegister v25 = as_VectorRegister(25);
373 constexpr VectorRegister v26 = as_VectorRegister(26);
374 constexpr VectorRegister v27 = as_VectorRegister(27);
375 constexpr VectorRegister v28 = as_VectorRegister(28);
376 constexpr VectorRegister v29 = as_VectorRegister(29);
377 constexpr VectorRegister v30 = as_VectorRegister(30);
378 constexpr VectorRegister v31 = as_VectorRegister(31);
379
380 // Need to know the total number of registers of all sorts for SharedInfo.
381 // Define a class that exports it.
382 class ConcreteRegisterImpl : public AbstractRegisterImpl {
383 public:
384 enum {
385 max_gpr = Register::number_of_registers * Register::max_slots_per_register,
386 max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register,
387 max_vpr = max_fpr + VectorRegister::number_of_registers * VectorRegister::max_slots_per_register,
388
389 // A big enough number for C2: all the registers plus flags
390 // This number must be large enough to cover REG_COUNT (defined by c2) registers.
391 // There is no requirement that any ordering here matches any ordering c2 gives
392 // it's optoregs.
393 number_of_registers = max_vpr // gpr/fpr/vpr
394 };
395 };
396
397 typedef AbstractRegSet<Register> RegSet;
398 typedef AbstractRegSet<FloatRegister> FloatRegSet;
399 typedef AbstractRegSet<VectorRegister> VectorRegSet;
400
401
402 template <>
403 inline Register AbstractRegSet<Register>::first() {
404 uint32_t first = _bitset & -_bitset;
405 return first ? as_Register(exact_log2(first)) : noreg;
406 }
407
408 template <>
409 inline FloatRegister AbstractRegSet<FloatRegister>::first() {
410 uint32_t first = _bitset & -_bitset;
411 return first ? as_FloatRegister(exact_log2(first)) : fnoreg;
412 }
413
414 template<>
415 inline VectorRegister AbstractRegSet<VectorRegister>::first() {
416 uint32_t first = _bitset & -_bitset;
417 return first ? as_VectorRegister(exact_log2(first)) : vnoreg;
418 }
419
420 #endif // CPU_RISCV_REGISTER_RISCV_HPP