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 RegisterImpl* Register;
 51 
 52 inline Register as_Register(int encoding) {
 53   return (Register)(intptr_t) encoding;
 54 }
 55 
 56 class RegisterImpl: public AbstractRegisterImpl {
 57 
 58  public:
 59   enum {
 60     number_of_registers      = 32,
 61     max_slots_per_register   = 2,
 62 
 63     // integer registers x8 - x15 and floating-point registers f8 - f15 are allocatable
 64     // for compressed instructions. See Table 17.2 in spec.
 65     compressed_register_base = 8,
 66     compressed_register_top  = 15,
 67   };
 68 
 69   // derived registers, offsets, and addresses
 70   Register successor() const { return as_Register(encoding() + 1); }
 71 
 72   // construction
 73   inline friend Register as_Register(int encoding);
 74 
 75   VMReg as_VMReg();
 76 
 77   // accessors
 78   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
 79   bool is_valid() const           { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; }
 80   const char* name() const;
 81   int encoding_nocheck() const { return (intptr_t)this; }
 82 
 83   // Return the bit which represents this register. This is intended
 84   // to be ORed into a bitmask: for usage see class AbstractRegSet below.
 85   unsigned long bit(bool should_set = true) const { return should_set ? 1 << encoding() : 0; }
 86 
 87   // for rvc
 88   int compressed_encoding() const {
 89     assert(is_compressed_valid(), "invalid compressed register");
 90     return encoding() - compressed_register_base;
 91   }
 92 
 93   int compressed_encoding_nocheck() const {
 94     return encoding_nocheck() - compressed_register_base;
 95   }
 96 
 97   bool is_compressed_valid() const {
 98     return encoding_nocheck() >= compressed_register_base &&
 99            encoding_nocheck() <= compressed_register_top;
100   }
101 };
102 
103 // The integer registers of the RISCV architecture
104 
105 CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
106 
107 CONSTANT_REGISTER_DECLARATION(Register, x0,    (0));
108 CONSTANT_REGISTER_DECLARATION(Register, x1,    (1));
109 CONSTANT_REGISTER_DECLARATION(Register, x2,    (2));
110 CONSTANT_REGISTER_DECLARATION(Register, x3,    (3));
111 CONSTANT_REGISTER_DECLARATION(Register, x4,    (4));
112 CONSTANT_REGISTER_DECLARATION(Register, x5,    (5));
113 CONSTANT_REGISTER_DECLARATION(Register, x6,    (6));
114 CONSTANT_REGISTER_DECLARATION(Register, x7,    (7));
115 CONSTANT_REGISTER_DECLARATION(Register, x8,    (8));
116 CONSTANT_REGISTER_DECLARATION(Register, x9,    (9));
117 CONSTANT_REGISTER_DECLARATION(Register, x10,  (10));
118 CONSTANT_REGISTER_DECLARATION(Register, x11,  (11));
119 CONSTANT_REGISTER_DECLARATION(Register, x12,  (12));
120 CONSTANT_REGISTER_DECLARATION(Register, x13,  (13));
121 CONSTANT_REGISTER_DECLARATION(Register, x14,  (14));
122 CONSTANT_REGISTER_DECLARATION(Register, x15,  (15));
123 CONSTANT_REGISTER_DECLARATION(Register, x16,  (16));
124 CONSTANT_REGISTER_DECLARATION(Register, x17,  (17));
125 CONSTANT_REGISTER_DECLARATION(Register, x18,  (18));
126 CONSTANT_REGISTER_DECLARATION(Register, x19,  (19));
127 CONSTANT_REGISTER_DECLARATION(Register, x20,  (20));
128 CONSTANT_REGISTER_DECLARATION(Register, x21,  (21));
129 CONSTANT_REGISTER_DECLARATION(Register, x22,  (22));
130 CONSTANT_REGISTER_DECLARATION(Register, x23,  (23));
131 CONSTANT_REGISTER_DECLARATION(Register, x24,  (24));
132 CONSTANT_REGISTER_DECLARATION(Register, x25,  (25));
133 CONSTANT_REGISTER_DECLARATION(Register, x26,  (26));
134 CONSTANT_REGISTER_DECLARATION(Register, x27,  (27));
135 CONSTANT_REGISTER_DECLARATION(Register, x28,  (28));
136 CONSTANT_REGISTER_DECLARATION(Register, x29,  (29));
137 CONSTANT_REGISTER_DECLARATION(Register, x30,  (30));
138 CONSTANT_REGISTER_DECLARATION(Register, x31,  (31));
139 
140 // Use FloatRegister as shortcut
141 class FloatRegisterImpl;
142 typedef FloatRegisterImpl* FloatRegister;
143 
144 inline FloatRegister as_FloatRegister(int encoding) {
145   return (FloatRegister)(intptr_t) encoding;
146 }
147 
148 // The implementation of floating point registers for the architecture
149 class FloatRegisterImpl: public AbstractRegisterImpl {
150 
151  public:
152   enum {
153     number_of_registers     = 32,
154     max_slots_per_register  = 2,
155 
156     // float registers in the range of [f8~f15] correspond to RVC. Please see Table 16.2 in spec.
157     compressed_register_base = 8,
158     compressed_register_top  = 15,
159   };
160 
161   // construction
162   inline friend FloatRegister as_FloatRegister(int encoding);
163 
164   VMReg as_VMReg();
165 
166   // derived registers, offsets, and addresses
167   FloatRegister successor() const {
168     return as_FloatRegister((encoding() + 1));
169   }
170 
171   // accessors
172   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
173   int encoding_nocheck() const    { return (intptr_t)this; }
174   int is_valid() const            { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; }
175   const char* name() const;
176 
177   // for rvc
178   int compressed_encoding() const {
179     assert(is_compressed_valid(), "invalid compressed register");
180     return encoding() - compressed_register_base;
181   }
182 
183   int compressed_encoding_nocheck() const {
184     return encoding_nocheck() - compressed_register_base;
185   }
186 
187   bool is_compressed_valid() const {
188     return encoding_nocheck() >= compressed_register_base &&
189            encoding_nocheck() <= compressed_register_top;
190   }
191 };
192 
193 // The float registers of the RISCV architecture
194 
195 CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
196 
197 CONSTANT_REGISTER_DECLARATION(FloatRegister, f0     , ( 0));
198 CONSTANT_REGISTER_DECLARATION(FloatRegister, f1     , ( 1));
199 CONSTANT_REGISTER_DECLARATION(FloatRegister, f2     , ( 2));
200 CONSTANT_REGISTER_DECLARATION(FloatRegister, f3     , ( 3));
201 CONSTANT_REGISTER_DECLARATION(FloatRegister, f4     , ( 4));
202 CONSTANT_REGISTER_DECLARATION(FloatRegister, f5     , ( 5));
203 CONSTANT_REGISTER_DECLARATION(FloatRegister, f6     , ( 6));
204 CONSTANT_REGISTER_DECLARATION(FloatRegister, f7     , ( 7));
205 CONSTANT_REGISTER_DECLARATION(FloatRegister, f8     , ( 8));
206 CONSTANT_REGISTER_DECLARATION(FloatRegister, f9     , ( 9));
207 CONSTANT_REGISTER_DECLARATION(FloatRegister, f10    , (10));
208 CONSTANT_REGISTER_DECLARATION(FloatRegister, f11    , (11));
209 CONSTANT_REGISTER_DECLARATION(FloatRegister, f12    , (12));
210 CONSTANT_REGISTER_DECLARATION(FloatRegister, f13    , (13));
211 CONSTANT_REGISTER_DECLARATION(FloatRegister, f14    , (14));
212 CONSTANT_REGISTER_DECLARATION(FloatRegister, f15    , (15));
213 CONSTANT_REGISTER_DECLARATION(FloatRegister, f16    , (16));
214 CONSTANT_REGISTER_DECLARATION(FloatRegister, f17    , (17));
215 CONSTANT_REGISTER_DECLARATION(FloatRegister, f18    , (18));
216 CONSTANT_REGISTER_DECLARATION(FloatRegister, f19    , (19));
217 CONSTANT_REGISTER_DECLARATION(FloatRegister, f20    , (20));
218 CONSTANT_REGISTER_DECLARATION(FloatRegister, f21    , (21));
219 CONSTANT_REGISTER_DECLARATION(FloatRegister, f22    , (22));
220 CONSTANT_REGISTER_DECLARATION(FloatRegister, f23    , (23));
221 CONSTANT_REGISTER_DECLARATION(FloatRegister, f24    , (24));
222 CONSTANT_REGISTER_DECLARATION(FloatRegister, f25    , (25));
223 CONSTANT_REGISTER_DECLARATION(FloatRegister, f26    , (26));
224 CONSTANT_REGISTER_DECLARATION(FloatRegister, f27    , (27));
225 CONSTANT_REGISTER_DECLARATION(FloatRegister, f28    , (28));
226 CONSTANT_REGISTER_DECLARATION(FloatRegister, f29    , (29));
227 CONSTANT_REGISTER_DECLARATION(FloatRegister, f30    , (30));
228 CONSTANT_REGISTER_DECLARATION(FloatRegister, f31    , (31));
229 
230 // Use VectorRegister as shortcut
231 class VectorRegisterImpl;
232 typedef VectorRegisterImpl* VectorRegister;
233 
234 inline VectorRegister as_VectorRegister(int encoding) {
235   return (VectorRegister)(intptr_t) encoding;
236 }
237 
238 // The implementation of vector registers for RVV
239 class VectorRegisterImpl: public AbstractRegisterImpl {
240 
241  public:
242   enum {
243     number_of_registers    = 32,
244     max_slots_per_register = 4
245   };
246 
247   // construction
248   inline friend VectorRegister as_VectorRegister(int encoding);
249 
250   VMReg as_VMReg();
251 
252   // derived registers, offsets, and addresses
253   VectorRegister successor() const { return as_VectorRegister(encoding() + 1); }
254 
255   // accessors
256   int encoding() const            { assert(is_valid(), "invalid register"); return encoding_nocheck(); }
257   int encoding_nocheck() const    { return (intptr_t)this; }
258   bool is_valid() const           { return 0 <= encoding_nocheck() && encoding_nocheck() < number_of_registers; }
259   const char* name() const;
260 
261 };
262 
263 // The vector registers of RVV
264 CONSTANT_REGISTER_DECLARATION(VectorRegister, vnoreg , (-1));
265 
266 CONSTANT_REGISTER_DECLARATION(VectorRegister, v0     , ( 0));
267 CONSTANT_REGISTER_DECLARATION(VectorRegister, v1     , ( 1));
268 CONSTANT_REGISTER_DECLARATION(VectorRegister, v2     , ( 2));
269 CONSTANT_REGISTER_DECLARATION(VectorRegister, v3     , ( 3));
270 CONSTANT_REGISTER_DECLARATION(VectorRegister, v4     , ( 4));
271 CONSTANT_REGISTER_DECLARATION(VectorRegister, v5     , ( 5));
272 CONSTANT_REGISTER_DECLARATION(VectorRegister, v6     , ( 6));
273 CONSTANT_REGISTER_DECLARATION(VectorRegister, v7     , ( 7));
274 CONSTANT_REGISTER_DECLARATION(VectorRegister, v8     , ( 8));
275 CONSTANT_REGISTER_DECLARATION(VectorRegister, v9     , ( 9));
276 CONSTANT_REGISTER_DECLARATION(VectorRegister, v10    , (10));
277 CONSTANT_REGISTER_DECLARATION(VectorRegister, v11    , (11));
278 CONSTANT_REGISTER_DECLARATION(VectorRegister, v12    , (12));
279 CONSTANT_REGISTER_DECLARATION(VectorRegister, v13    , (13));
280 CONSTANT_REGISTER_DECLARATION(VectorRegister, v14    , (14));
281 CONSTANT_REGISTER_DECLARATION(VectorRegister, v15    , (15));
282 CONSTANT_REGISTER_DECLARATION(VectorRegister, v16    , (16));
283 CONSTANT_REGISTER_DECLARATION(VectorRegister, v17    , (17));
284 CONSTANT_REGISTER_DECLARATION(VectorRegister, v18    , (18));
285 CONSTANT_REGISTER_DECLARATION(VectorRegister, v19    , (19));
286 CONSTANT_REGISTER_DECLARATION(VectorRegister, v20    , (20));
287 CONSTANT_REGISTER_DECLARATION(VectorRegister, v21    , (21));
288 CONSTANT_REGISTER_DECLARATION(VectorRegister, v22    , (22));
289 CONSTANT_REGISTER_DECLARATION(VectorRegister, v23    , (23));
290 CONSTANT_REGISTER_DECLARATION(VectorRegister, v24    , (24));
291 CONSTANT_REGISTER_DECLARATION(VectorRegister, v25    , (25));
292 CONSTANT_REGISTER_DECLARATION(VectorRegister, v26    , (26));
293 CONSTANT_REGISTER_DECLARATION(VectorRegister, v27    , (27));
294 CONSTANT_REGISTER_DECLARATION(VectorRegister, v28    , (28));
295 CONSTANT_REGISTER_DECLARATION(VectorRegister, v29    , (29));
296 CONSTANT_REGISTER_DECLARATION(VectorRegister, v30    , (30));
297 CONSTANT_REGISTER_DECLARATION(VectorRegister, v31    , (31));
298 
299 
300 // Need to know the total number of registers of all sorts for SharedInfo.
301 // Define a class that exports it.
302 class ConcreteRegisterImpl : public AbstractRegisterImpl {
303  public:
304   enum {
305   // A big enough number for C2: all the registers plus flags
306   // This number must be large enough to cover REG_COUNT (defined by c2) registers.
307   // There is no requirement that any ordering here matches any ordering c2 gives
308   // it's optoregs.
309 
310     number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
311                            FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
312                            VectorRegisterImpl::max_slots_per_register * VectorRegisterImpl::number_of_registers)
313   };
314 
315   // added to make it compile
316   static const int max_gpr;
317   static const int max_fpr;
318   static const int max_vpr;
319 };
320 
321 // A set of registers
322 template<class RegImpl>
323 class AbstractRegSet {
324   uint32_t _bitset;
325 
326   AbstractRegSet(uint32_t bitset) : _bitset(bitset) { }
327 
328  public:
329   AbstractRegSet() : _bitset(0) { }
330 
331   AbstractRegSet(RegImpl r1) : _bitset(1 << r1->encoding()) { }
332 
333   AbstractRegSet operator+(const AbstractRegSet aSet) const {
334     AbstractRegSet result(_bitset | aSet._bitset);
335     return result;
336   }
337 
338   AbstractRegSet operator-(const AbstractRegSet aSet) const {
339     AbstractRegSet result(_bitset & ~aSet._bitset);
340     return result;
341   }
342 
343   AbstractRegSet &operator+=(const AbstractRegSet aSet) {
344     *this = *this + aSet;
345     return *this;
346   }
347 
348   AbstractRegSet &operator-=(const AbstractRegSet aSet) {
349     *this = *this - aSet;
350     return *this;
351   }
352 
353   static AbstractRegSet of(RegImpl r1) {
354     return AbstractRegSet(r1);
355   }
356 
357   static AbstractRegSet of(RegImpl r1, RegImpl r2) {
358     return of(r1) + r2;
359   }
360 
361   static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3) {
362     return of(r1, r2) + r3;
363   }
364 
365   static AbstractRegSet of(RegImpl r1, RegImpl r2, RegImpl r3, RegImpl r4) {
366     return of(r1, r2, r3) + r4;
367   }
368 
369   static AbstractRegSet range(RegImpl start, RegImpl end) {
370     uint32_t bits = ~0;
371     bits <<= start->encoding();
372     bits <<= (31 - end->encoding());
373     bits >>= (31 - end->encoding());
374 
375     return AbstractRegSet(bits);
376   }
377 
378   uint32_t bits() const { return _bitset; }
379 };
380 
381 typedef AbstractRegSet<Register> RegSet;
382 typedef AbstractRegSet<FloatRegister> FloatRegSet;
383 typedef AbstractRegSet<VectorRegister> VectorRegSet;
384 
385 #endif // CPU_RISCV_REGISTER_RISCV_HPP