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