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
111 extern Register::RegisterImpl all_RegisterImpls[Register::number_of_registers + 1] INTERNAL_VISIBILITY;
112
113 inline constexpr const Register::RegisterImpl* Register::RegisterImpl::first() {
114 return all_RegisterImpls + 1;
115 }
116
117 constexpr Register noreg = Register();
118
119 inline constexpr Register as_Register(int encoding) {
120 if (0 <= encoding && encoding < Register::number_of_registers) {
121 return Register(encoding);
122 }
123 return noreg;
124 }
125
126 inline Register Register::RegisterImpl::successor() const {
127 assert(is_valid(), "sanity");
128 return as_Register(encoding() + 1);
129 }
130
131 // The integer registers of RISCV architecture
132 constexpr Register x0 = as_Register( 0);
133 constexpr Register x1 = as_Register( 1);
134 constexpr Register x2 = as_Register( 2);
135 constexpr Register x3 = as_Register( 3);
136 constexpr Register x4 = as_Register( 4);
137 constexpr Register x5 = as_Register( 5);
138 constexpr Register x6 = as_Register( 6);
139 constexpr Register x7 = as_Register( 7);
140 constexpr Register x8 = as_Register( 8);
141 constexpr Register x9 = as_Register( 9);
142 constexpr Register x10 = as_Register(10);
143 constexpr Register x11 = as_Register(11);
144 constexpr Register x12 = as_Register(12);
145 constexpr Register x13 = as_Register(13);
146 constexpr Register x14 = as_Register(14);
147 constexpr Register x15 = as_Register(15);
148 constexpr Register x16 = as_Register(16);
149 constexpr Register x17 = as_Register(17);
150 constexpr Register x18 = as_Register(18);
151 constexpr Register x19 = as_Register(19);
152 constexpr Register x20 = as_Register(20);
153 constexpr Register x21 = as_Register(21);
154 constexpr Register x22 = as_Register(22);
155 constexpr Register x23 = as_Register(23);
156 constexpr Register x24 = as_Register(24);
157 constexpr Register x25 = as_Register(25);
158 constexpr Register x26 = as_Register(26);
159 constexpr Register x27 = as_Register(27);
160 constexpr Register x28 = as_Register(28);
161 constexpr Register x29 = as_Register(29);
162 constexpr Register x30 = as_Register(30);
163 constexpr Register x31 = as_Register(31);
164
165 // The implementation of floating point registers for the architecture
166 class FloatRegister {
167 private:
168 int _encoding;
169
170 constexpr explicit FloatRegister(int encoding) : _encoding(encoding) {}
171
172 public:
173 inline friend constexpr FloatRegister as_FloatRegister(int encoding);
174
175 enum {
176 number_of_registers = 32,
177 max_slots_per_register = 2,
178
179 // float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec.
180 compressed_register_base = 8,
181 compressed_register_top = 15,
182 };
183
184 class FloatRegisterImpl: public AbstractRegisterImpl {
185 friend class FloatRegister;
186
187 static constexpr const FloatRegisterImpl* first();
188
189 public:
190 // accessors
191 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
192 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
193 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
194
195 // for rvc
196 int compressed_raw_encoding() const {
197 return raw_encoding() - compressed_register_base;
198 }
199
200 int compressed_encoding() const {
201 assert(is_compressed_valid(), "invalid compressed register");
202 return encoding() - compressed_register_base;
203 }
204
205 bool is_compressed_valid() const {
206 return raw_encoding() >= compressed_register_base &&
207 raw_encoding() <= compressed_register_top;
208 }
209
210 // derived registers, offsets, and addresses
211 inline FloatRegister successor() const;
212
213 VMReg as_VMReg() const;
214
215 const char* name() const;
216 };
217
218 constexpr FloatRegister() : _encoding(-1) {} // fnoreg
219
220 int operator==(const FloatRegister r) const { return _encoding == r._encoding; }
221 int operator!=(const FloatRegister r) const { return _encoding != r._encoding; }
222
223 constexpr const FloatRegisterImpl* operator->() const { return FloatRegisterImpl::first() + _encoding; }
224 };
225
226 extern FloatRegister::FloatRegisterImpl all_FloatRegisterImpls[FloatRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
227
228 inline constexpr const FloatRegister::FloatRegisterImpl* FloatRegister::FloatRegisterImpl::first() {
229 return all_FloatRegisterImpls + 1;
230 }
231
232 constexpr FloatRegister fnoreg = FloatRegister();
233
234 inline constexpr FloatRegister as_FloatRegister(int encoding) {
235 if (0 <= encoding && encoding < FloatRegister::number_of_registers) {
236 return FloatRegister(encoding);
237 }
238 return fnoreg;
239 }
240
241 inline FloatRegister FloatRegister::FloatRegisterImpl::successor() const {
242 assert(is_valid(), "sanity");
243 return as_FloatRegister(encoding() + 1);
244 }
245
246 // The float registers of the RISCV architecture
247 constexpr FloatRegister f0 = as_FloatRegister( 0);
248 constexpr FloatRegister f1 = as_FloatRegister( 1);
249 constexpr FloatRegister f2 = as_FloatRegister( 2);
250 constexpr FloatRegister f3 = as_FloatRegister( 3);
251 constexpr FloatRegister f4 = as_FloatRegister( 4);
252 constexpr FloatRegister f5 = as_FloatRegister( 5);
253 constexpr FloatRegister f6 = as_FloatRegister( 6);
254 constexpr FloatRegister f7 = as_FloatRegister( 7);
255 constexpr FloatRegister f8 = as_FloatRegister( 8);
256 constexpr FloatRegister f9 = as_FloatRegister( 9);
257 constexpr FloatRegister f10 = as_FloatRegister(10);
258 constexpr FloatRegister f11 = as_FloatRegister(11);
259 constexpr FloatRegister f12 = as_FloatRegister(12);
260 constexpr FloatRegister f13 = as_FloatRegister(13);
261 constexpr FloatRegister f14 = as_FloatRegister(14);
262 constexpr FloatRegister f15 = as_FloatRegister(15);
263 constexpr FloatRegister f16 = as_FloatRegister(16);
264 constexpr FloatRegister f17 = as_FloatRegister(17);
265 constexpr FloatRegister f18 = as_FloatRegister(18);
266 constexpr FloatRegister f19 = as_FloatRegister(19);
267 constexpr FloatRegister f20 = as_FloatRegister(20);
268 constexpr FloatRegister f21 = as_FloatRegister(21);
269 constexpr FloatRegister f22 = as_FloatRegister(22);
270 constexpr FloatRegister f23 = as_FloatRegister(23);
271 constexpr FloatRegister f24 = as_FloatRegister(24);
272 constexpr FloatRegister f25 = as_FloatRegister(25);
273 constexpr FloatRegister f26 = as_FloatRegister(26);
274 constexpr FloatRegister f27 = as_FloatRegister(27);
275 constexpr FloatRegister f28 = as_FloatRegister(28);
276 constexpr FloatRegister f29 = as_FloatRegister(29);
277 constexpr FloatRegister f30 = as_FloatRegister(30);
278 constexpr FloatRegister f31 = as_FloatRegister(31);
279
280 // The implementation of vector registers for RVV
281 class VectorRegister {
282 int _encoding;
283
284 constexpr explicit VectorRegister(int encoding) : _encoding(encoding) {}
285
286 public:
287 inline friend constexpr VectorRegister as_VectorRegister(int encoding);
288
289 enum {
290 number_of_registers = 32,
291 max_slots_per_register = 4
292 };
293
294 class VectorRegisterImpl: public AbstractRegisterImpl {
295 friend class VectorRegister;
296
297 static constexpr const VectorRegisterImpl* first();
298
299 public:
300 // accessors
301 constexpr int raw_encoding() const { return checked_cast<int>(this - first()); }
302 constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); }
303 constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; }
304
305 // derived registers, offsets, and addresses
306 inline VectorRegister successor() const;
307
308 VMReg as_VMReg() const;
309
310 const char* name() const;
311 };
312
313 constexpr VectorRegister() : _encoding(-1) {} // vnoreg
314
315 int operator==(const VectorRegister r) const { return _encoding == r._encoding; }
316 int operator!=(const VectorRegister r) const { return _encoding != r._encoding; }
317
318 constexpr const VectorRegisterImpl* operator->() const { return VectorRegisterImpl::first() + _encoding; }
319 };
320
321 extern VectorRegister::VectorRegisterImpl all_VectorRegisterImpls[VectorRegister::number_of_registers + 1] INTERNAL_VISIBILITY;
322
323 inline constexpr const VectorRegister::VectorRegisterImpl* VectorRegister::VectorRegisterImpl::first() {
324 return all_VectorRegisterImpls + 1;
325 }
326
327 constexpr VectorRegister vnoreg = VectorRegister();
328
329 inline constexpr VectorRegister as_VectorRegister(int encoding) {
330 if (0 <= encoding && encoding < VectorRegister::number_of_registers) {
331 return VectorRegister(encoding);
332 }
333 return vnoreg;
334 }
335
336 inline VectorRegister VectorRegister::VectorRegisterImpl::successor() const {
337 assert(is_valid(), "sanity");
338 return as_VectorRegister(encoding() + 1);
339 }
340
341 // The vector registers of RVV
342 constexpr VectorRegister v0 = as_VectorRegister( 0);
343 constexpr VectorRegister v1 = as_VectorRegister( 1);
344 constexpr VectorRegister v2 = as_VectorRegister( 2);
345 constexpr VectorRegister v3 = as_VectorRegister( 3);
346 constexpr VectorRegister v4 = as_VectorRegister( 4);
347 constexpr VectorRegister v5 = as_VectorRegister( 5);
348 constexpr VectorRegister v6 = as_VectorRegister( 6);
349 constexpr VectorRegister v7 = as_VectorRegister( 7);
350 constexpr VectorRegister v8 = as_VectorRegister( 8);
351 constexpr VectorRegister v9 = as_VectorRegister( 9);
352 constexpr VectorRegister v10 = as_VectorRegister(10);
353 constexpr VectorRegister v11 = as_VectorRegister(11);
354 constexpr VectorRegister v12 = as_VectorRegister(12);
355 constexpr VectorRegister v13 = as_VectorRegister(13);
356 constexpr VectorRegister v14 = as_VectorRegister(14);
357 constexpr VectorRegister v15 = as_VectorRegister(15);
358 constexpr VectorRegister v16 = as_VectorRegister(16);
359 constexpr VectorRegister v17 = as_VectorRegister(17);
360 constexpr VectorRegister v18 = as_VectorRegister(18);
361 constexpr VectorRegister v19 = as_VectorRegister(19);
362 constexpr VectorRegister v20 = as_VectorRegister(20);
363 constexpr VectorRegister v21 = as_VectorRegister(21);
364 constexpr VectorRegister v22 = as_VectorRegister(22);
365 constexpr VectorRegister v23 = as_VectorRegister(23);
366 constexpr VectorRegister v24 = as_VectorRegister(24);
367 constexpr VectorRegister v25 = as_VectorRegister(25);
368 constexpr VectorRegister v26 = as_VectorRegister(26);
369 constexpr VectorRegister v27 = as_VectorRegister(27);
370 constexpr VectorRegister v28 = as_VectorRegister(28);
371 constexpr VectorRegister v29 = as_VectorRegister(29);
372 constexpr VectorRegister v30 = as_VectorRegister(30);
373 constexpr VectorRegister v31 = as_VectorRegister(31);
374
375 // Need to know the total number of registers of all sorts for SharedInfo.
376 // Define a class that exports it.
377 class ConcreteRegisterImpl : public AbstractRegisterImpl {
378 public:
379 enum {
380 max_gpr = Register::number_of_registers * Register::max_slots_per_register,
381 max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register,
382 max_vpr = max_fpr + VectorRegister::number_of_registers * VectorRegister::max_slots_per_register,
383
384 // A big enough number for C2: all the registers plus flags
385 // This number must be large enough to cover REG_COUNT (defined by c2) registers.
386 // There is no requirement that any ordering here matches any ordering c2 gives
387 // it's optoregs.
388 number_of_registers = max_vpr // gpr/fpr/vpr
389 };
390 };
391
392 typedef AbstractRegSet<Register> RegSet;
393 typedef AbstractRegSet<FloatRegister> FloatRegSet;
394 typedef AbstractRegSet<VectorRegister> VectorRegSet;
395
396
397 template <>
398 inline Register AbstractRegSet<Register>::first() {
399 uint32_t first = _bitset & -_bitset;
400 return first ? as_Register(exact_log2(first)) : noreg;
401 }
402
403 template <>
404 inline FloatRegister AbstractRegSet<FloatRegister>::first() {
405 uint32_t first = _bitset & -_bitset;
406 return first ? as_FloatRegister(exact_log2(first)) : fnoreg;
407 }
408
409 template<>
410 inline VectorRegister AbstractRegSet<VectorRegister>::first() {
411 uint32_t first = _bitset & -_bitset;
412 return first ? as_VectorRegister(exact_log2(first)) : vnoreg;
413 }
414
415 #endif // CPU_RISCV_REGISTER_RISCV_HPP