1 /*
  2  * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2020, 2022, 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 
 31 #define CSR_FFLAGS   0x001        // Floating-Point Accrued Exceptions.
 32 #define CSR_FRM      0x002        // Floating-Point Dynamic Rounding Mode.
 33 #define CSR_FCSR     0x003        // Floating-Point Control and Status Register (frm + fflags).
 34 #define CSR_VSTART   0x008        // Vector start position
 35 #define CSR_VXSAT    0x009        // Fixed-Point Saturate Flag
 36 #define CSR_VXRM     0x00A        // Fixed-Point Rounding Mode
 37 #define CSR_VCSR     0x00F        // Vector control and status register
 38 #define CSR_VL       0xC20        // Vector length
 39 #define CSR_VTYPE    0xC21        // Vector data type register
 40 #define CSR_VLENB    0xC22        // VLEN/8 (vector register length in bytes)
 41 #define CSR_CYCLE    0xc00        // Cycle counter for RDCYCLE instruction.
 42 #define CSR_TIME     0xc01        // Timer for RDTIME instruction.
 43 #define CSR_INSTERT  0xc02        // Instructions-retired counter for RDINSTRET instruction.
 44 
 45 class VMRegImpl;
 46 typedef VMRegImpl* VMReg;
 47 
 48 // Use Register as shortcut
 49 class RegisterImpl;
 50 typedef const RegisterImpl* Register;
 51 
 52 inline constexpr Register as_Register(int encoding);
 53 
 54 class RegisterImpl: public AbstractRegisterImpl {
 55   static constexpr Register first();
 56 
 57  public:
 58   enum {
 59     number_of_registers      = 32,
 60     max_slots_per_register   = 2,
 61 
 62     // integer registers x8 - x15 and floating-point registers f8 - f15 are allocatable
 63     // for compressed instructions. See Table 17.2 in spec.
 64     compressed_register_base = 8,
 65     compressed_register_top  = 15,
 66   };
 67 
 68   // derived registers, offsets, and addresses
 69   const Register successor() const { return this + 1; }
 70 
 71   // construction
 72   inline friend constexpr Register as_Register(int encoding);
 73 
 74   VMReg as_VMReg() const;
 75 
 76   // accessors
 77   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
 78   int encoding_nocheck() const    { return this - first(); }
 79   bool is_valid() const           { return (unsigned)encoding_nocheck() < number_of_registers; }
 80   const char* name() const;
 81 
 82   // for rvc
 83   int compressed_encoding() const {
 84     assert(is_compressed_valid(), "invalid compressed register");
 85     return encoding() - compressed_register_base;
 86   }
 87 
 88   int compressed_encoding_nocheck() const {
 89     return encoding_nocheck() - compressed_register_base;
 90   }
 91 
 92   bool is_compressed_valid() const {
 93     return encoding_nocheck() >= compressed_register_base &&
 94            encoding_nocheck() <= compressed_register_top;
 95   }
 96 };
 97 
 98 REGISTER_IMPL_DECLARATION(Register, RegisterImpl, RegisterImpl::number_of_registers);
 99 
100 // The integer registers of the RISCV architecture
101 
102 CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
103 
104 CONSTANT_REGISTER_DECLARATION(Register, x0,    (0));
105 CONSTANT_REGISTER_DECLARATION(Register, x1,    (1));
106 CONSTANT_REGISTER_DECLARATION(Register, x2,    (2));
107 CONSTANT_REGISTER_DECLARATION(Register, x3,    (3));
108 CONSTANT_REGISTER_DECLARATION(Register, x4,    (4));
109 CONSTANT_REGISTER_DECLARATION(Register, x5,    (5));
110 CONSTANT_REGISTER_DECLARATION(Register, x6,    (6));
111 CONSTANT_REGISTER_DECLARATION(Register, x7,    (7));
112 CONSTANT_REGISTER_DECLARATION(Register, x8,    (8));
113 CONSTANT_REGISTER_DECLARATION(Register, x9,    (9));
114 CONSTANT_REGISTER_DECLARATION(Register, x10,  (10));
115 CONSTANT_REGISTER_DECLARATION(Register, x11,  (11));
116 CONSTANT_REGISTER_DECLARATION(Register, x12,  (12));
117 CONSTANT_REGISTER_DECLARATION(Register, x13,  (13));
118 CONSTANT_REGISTER_DECLARATION(Register, x14,  (14));
119 CONSTANT_REGISTER_DECLARATION(Register, x15,  (15));
120 CONSTANT_REGISTER_DECLARATION(Register, x16,  (16));
121 CONSTANT_REGISTER_DECLARATION(Register, x17,  (17));
122 CONSTANT_REGISTER_DECLARATION(Register, x18,  (18));
123 CONSTANT_REGISTER_DECLARATION(Register, x19,  (19));
124 CONSTANT_REGISTER_DECLARATION(Register, x20,  (20));
125 CONSTANT_REGISTER_DECLARATION(Register, x21,  (21));
126 CONSTANT_REGISTER_DECLARATION(Register, x22,  (22));
127 CONSTANT_REGISTER_DECLARATION(Register, x23,  (23));
128 CONSTANT_REGISTER_DECLARATION(Register, x24,  (24));
129 CONSTANT_REGISTER_DECLARATION(Register, x25,  (25));
130 CONSTANT_REGISTER_DECLARATION(Register, x26,  (26));
131 CONSTANT_REGISTER_DECLARATION(Register, x27,  (27));
132 CONSTANT_REGISTER_DECLARATION(Register, x28,  (28));
133 CONSTANT_REGISTER_DECLARATION(Register, x29,  (29));
134 CONSTANT_REGISTER_DECLARATION(Register, x30,  (30));
135 CONSTANT_REGISTER_DECLARATION(Register, x31,  (31));
136 
137 // Use FloatRegister as shortcut
138 class FloatRegisterImpl;
139 typedef const FloatRegisterImpl* FloatRegister;
140 
141 inline constexpr FloatRegister as_FloatRegister(int encoding);
142 
143 // The implementation of floating point registers for the architecture
144 class FloatRegisterImpl: public AbstractRegisterImpl {
145   static constexpr FloatRegister first();
146 
147  public:
148   enum {
149     number_of_registers     = 32,
150     max_slots_per_register  = 2,
151 
152     // float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec.
153     compressed_register_base = 8,
154     compressed_register_top  = 15,
155   };
156 
157   // construction
158   inline friend constexpr FloatRegister as_FloatRegister(int encoding);
159 
160   VMReg as_VMReg() const;
161 
162   // derived registers, offsets, and addresses
163   FloatRegister successor() const {
164     return as_FloatRegister((encoding() + 1) % (unsigned)number_of_registers);
165   }
166 
167   // accessors
168   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
169   int encoding_nocheck() const    { return this - first(); }
170   int is_valid() const            { return (unsigned)encoding_nocheck() < number_of_registers; }
171   const char* name() const;
172 
173   // for rvc
174   int compressed_encoding() const {
175     assert(is_compressed_valid(), "invalid compressed register");
176     return encoding() - compressed_register_base;
177   }
178 
179   int compressed_encoding_nocheck() const {
180     return encoding_nocheck() - compressed_register_base;
181   }
182 
183   bool is_compressed_valid() const {
184     return encoding_nocheck() >= compressed_register_base &&
185            encoding_nocheck() <= compressed_register_top;
186   }
187 };
188 
189 REGISTER_IMPL_DECLARATION(FloatRegister, FloatRegisterImpl, FloatRegisterImpl::number_of_registers);
190 
191 // The float registers of the RISCV architecture
192 
193 CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
194 
195 CONSTANT_REGISTER_DECLARATION(FloatRegister, f0     , ( 0));
196 CONSTANT_REGISTER_DECLARATION(FloatRegister, f1     , ( 1));
197 CONSTANT_REGISTER_DECLARATION(FloatRegister, f2     , ( 2));
198 CONSTANT_REGISTER_DECLARATION(FloatRegister, f3     , ( 3));
199 CONSTANT_REGISTER_DECLARATION(FloatRegister, f4     , ( 4));
200 CONSTANT_REGISTER_DECLARATION(FloatRegister, f5     , ( 5));
201 CONSTANT_REGISTER_DECLARATION(FloatRegister, f6     , ( 6));
202 CONSTANT_REGISTER_DECLARATION(FloatRegister, f7     , ( 7));
203 CONSTANT_REGISTER_DECLARATION(FloatRegister, f8     , ( 8));
204 CONSTANT_REGISTER_DECLARATION(FloatRegister, f9     , ( 9));
205 CONSTANT_REGISTER_DECLARATION(FloatRegister, f10    , (10));
206 CONSTANT_REGISTER_DECLARATION(FloatRegister, f11    , (11));
207 CONSTANT_REGISTER_DECLARATION(FloatRegister, f12    , (12));
208 CONSTANT_REGISTER_DECLARATION(FloatRegister, f13    , (13));
209 CONSTANT_REGISTER_DECLARATION(FloatRegister, f14    , (14));
210 CONSTANT_REGISTER_DECLARATION(FloatRegister, f15    , (15));
211 CONSTANT_REGISTER_DECLARATION(FloatRegister, f16    , (16));
212 CONSTANT_REGISTER_DECLARATION(FloatRegister, f17    , (17));
213 CONSTANT_REGISTER_DECLARATION(FloatRegister, f18    , (18));
214 CONSTANT_REGISTER_DECLARATION(FloatRegister, f19    , (19));
215 CONSTANT_REGISTER_DECLARATION(FloatRegister, f20    , (20));
216 CONSTANT_REGISTER_DECLARATION(FloatRegister, f21    , (21));
217 CONSTANT_REGISTER_DECLARATION(FloatRegister, f22    , (22));
218 CONSTANT_REGISTER_DECLARATION(FloatRegister, f23    , (23));
219 CONSTANT_REGISTER_DECLARATION(FloatRegister, f24    , (24));
220 CONSTANT_REGISTER_DECLARATION(FloatRegister, f25    , (25));
221 CONSTANT_REGISTER_DECLARATION(FloatRegister, f26    , (26));
222 CONSTANT_REGISTER_DECLARATION(FloatRegister, f27    , (27));
223 CONSTANT_REGISTER_DECLARATION(FloatRegister, f28    , (28));
224 CONSTANT_REGISTER_DECLARATION(FloatRegister, f29    , (29));
225 CONSTANT_REGISTER_DECLARATION(FloatRegister, f30    , (30));
226 CONSTANT_REGISTER_DECLARATION(FloatRegister, f31    , (31));
227 
228 // Use VectorRegister as shortcut
229 class VectorRegisterImpl;
230 typedef const VectorRegisterImpl* VectorRegister;
231 
232 inline constexpr VectorRegister as_VectorRegister(int encoding);
233 
234 // The implementation of vector registers for RVV
235 class VectorRegisterImpl: public AbstractRegisterImpl {
236   static constexpr VectorRegister first();
237 
238  public:
239   enum {
240     number_of_registers    = 32,
241     max_slots_per_register = 4
242   };
243 
244   // construction
245   inline friend constexpr VectorRegister as_VectorRegister(int encoding);
246 
247   VMReg as_VMReg() const;
248 
249   // derived registers, offsets, and addresses
250   VectorRegister successor() const { return this + 1; }
251 
252   // accessors
253   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
254   int encoding_nocheck() const    { return this - first(); }
255   bool is_valid() const           { return (unsigned)encoding_nocheck() < number_of_registers; }
256   const char* name() const;
257 
258 };
259 
260 REGISTER_IMPL_DECLARATION(VectorRegister, VectorRegisterImpl, VectorRegisterImpl::number_of_registers);
261 
262 // The vector registers of RVV
263 CONSTANT_REGISTER_DECLARATION(VectorRegister, vnoreg , (-1));
264 
265 CONSTANT_REGISTER_DECLARATION(VectorRegister, v0     , ( 0));
266 CONSTANT_REGISTER_DECLARATION(VectorRegister, v1     , ( 1));
267 CONSTANT_REGISTER_DECLARATION(VectorRegister, v2     , ( 2));
268 CONSTANT_REGISTER_DECLARATION(VectorRegister, v3     , ( 3));
269 CONSTANT_REGISTER_DECLARATION(VectorRegister, v4     , ( 4));
270 CONSTANT_REGISTER_DECLARATION(VectorRegister, v5     , ( 5));
271 CONSTANT_REGISTER_DECLARATION(VectorRegister, v6     , ( 6));
272 CONSTANT_REGISTER_DECLARATION(VectorRegister, v7     , ( 7));
273 CONSTANT_REGISTER_DECLARATION(VectorRegister, v8     , ( 8));
274 CONSTANT_REGISTER_DECLARATION(VectorRegister, v9     , ( 9));
275 CONSTANT_REGISTER_DECLARATION(VectorRegister, v10    , (10));
276 CONSTANT_REGISTER_DECLARATION(VectorRegister, v11    , (11));
277 CONSTANT_REGISTER_DECLARATION(VectorRegister, v12    , (12));
278 CONSTANT_REGISTER_DECLARATION(VectorRegister, v13    , (13));
279 CONSTANT_REGISTER_DECLARATION(VectorRegister, v14    , (14));
280 CONSTANT_REGISTER_DECLARATION(VectorRegister, v15    , (15));
281 CONSTANT_REGISTER_DECLARATION(VectorRegister, v16    , (16));
282 CONSTANT_REGISTER_DECLARATION(VectorRegister, v17    , (17));
283 CONSTANT_REGISTER_DECLARATION(VectorRegister, v18    , (18));
284 CONSTANT_REGISTER_DECLARATION(VectorRegister, v19    , (19));
285 CONSTANT_REGISTER_DECLARATION(VectorRegister, v20    , (20));
286 CONSTANT_REGISTER_DECLARATION(VectorRegister, v21    , (21));
287 CONSTANT_REGISTER_DECLARATION(VectorRegister, v22    , (22));
288 CONSTANT_REGISTER_DECLARATION(VectorRegister, v23    , (23));
289 CONSTANT_REGISTER_DECLARATION(VectorRegister, v24    , (24));
290 CONSTANT_REGISTER_DECLARATION(VectorRegister, v25    , (25));
291 CONSTANT_REGISTER_DECLARATION(VectorRegister, v26    , (26));
292 CONSTANT_REGISTER_DECLARATION(VectorRegister, v27    , (27));
293 CONSTANT_REGISTER_DECLARATION(VectorRegister, v28    , (28));
294 CONSTANT_REGISTER_DECLARATION(VectorRegister, v29    , (29));
295 CONSTANT_REGISTER_DECLARATION(VectorRegister, v30    , (30));
296 CONSTANT_REGISTER_DECLARATION(VectorRegister, v31    , (31));
297 
298 
299 // Need to know the total number of registers of all sorts for SharedInfo.
300 // Define a class that exports it.
301 class ConcreteRegisterImpl : public AbstractRegisterImpl {
302  public:
303   enum {
304   // A big enough number for C2: all the registers plus flags
305   // This number must be large enough to cover REG_COUNT (defined by c2) registers.
306   // There is no requirement that any ordering here matches any ordering c2 gives
307   // it's optoregs.
308 
309     number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
310                            FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
311                            VectorRegisterImpl::max_slots_per_register * VectorRegisterImpl::number_of_registers)
312   };
313 
314   // added to make it compile
315   static const int max_gpr;
316   static const int max_fpr;
317   static const int max_vpr;
318 };
319 
320 typedef AbstractRegSet<Register> RegSet;
321 typedef AbstractRegSet<FloatRegister> FloatRegSet;
322 typedef AbstractRegSet<VectorRegister> VectorRegSet;
323 
324 #endif // CPU_RISCV_REGISTER_RISCV_HPP