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