1 /*
  2  * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
  4  * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
  5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  6  *
  7  * This code is free software; you can redistribute it and/or modify it
  8  * under the terms of the GNU General Public License version 2 only, as
  9  * published by the Free Software Foundation.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  *
 25  */
 26 
 27 #ifndef CPU_RISCV_REGISTER_RISCV_HPP
 28 #define CPU_RISCV_REGISTER_RISCV_HPP
 29 
 30 #include "asm/register.hpp"
 31 
 32 #define CSR_FFLAGS   0x001        // Floating-Point Accrued Exceptions.
 33 #define CSR_FRM      0x002        // Floating-Point Dynamic Rounding Mode.
 34 #define CSR_FCSR     0x003        // Floating-Point Control and Status Register (frm + fflags).
 35 #define CSR_VSTART   0x008        // Vector start position
 36 #define CSR_VXSAT    0x009        // Fixed-Point Saturate Flag
 37 #define CSR_VXRM     0x00A        // Fixed-Point Rounding Mode
 38 #define CSR_VCSR     0x00F        // Vector control and status register
 39 #define CSR_VL       0xC20        // Vector length
 40 #define CSR_VTYPE    0xC21        // Vector data type register
 41 #define CSR_VLENB    0xC22        // VLEN/8 (vector register length in bytes)
 42 #define CSR_CYCLE    0xc00        // Cycle counter for RDCYCLE instruction.
 43 #define CSR_TIME     0xc01        // Timer for RDTIME instruction.
 44 #define CSR_INSTERT  0xc02        // Instructions-retired counter for RDINSTRET instruction.
 45 
 46 class VMRegImpl;
 47 typedef VMRegImpl* VMReg;
 48 
 49 // Use Register as shortcut
 50 class RegisterImpl;
 51 typedef RegisterImpl* Register;
 52 
 53 inline Register as_Register(int encoding) {
 54   return (Register)(intptr_t) encoding;
 55 }
 56 
 57 class RegisterImpl: public AbstractRegisterImpl {
 58  public:
 59   enum {
 60     number_of_registers      = 32,
 61     number_of_byte_registers = 32,
 62     max_slots_per_register   = 2
 63   };
 64 
 65   // derived registers, offsets, and addresses
 66   Register successor() const                          { return as_Register(encoding() + 1); }
 67 
 68   // construction
 69   inline friend Register as_Register(int encoding);
 70 
 71   VMReg as_VMReg();
 72 
 73   // accessors
 74   int   encoding() const                         { assert(is_valid(), "invalid register"); return (intptr_t)this; }
 75   bool  is_valid() const                         { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
 76   bool  has_byte_register() const                { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; }
 77   const char* name() const;
 78   int   encoding_nocheck() const                 { return (intptr_t)this; }
 79 
 80   // Return the bit which represents this register.  This is intended
 81   // to be ORed into a bitmask: for usage see class RegSet below.
 82   unsigned long bit(bool should_set = true) const { return should_set ? 1 << encoding() : 0; }
 83 };
 84 
 85 // The integer registers of the riscv64 architecture
 86 
 87 CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
 88 
 89 CONSTANT_REGISTER_DECLARATION(Register, x0,    (0));
 90 CONSTANT_REGISTER_DECLARATION(Register, x1,    (1));
 91 CONSTANT_REGISTER_DECLARATION(Register, x2,    (2));
 92 CONSTANT_REGISTER_DECLARATION(Register, x3,    (3));
 93 CONSTANT_REGISTER_DECLARATION(Register, x4,    (4));
 94 CONSTANT_REGISTER_DECLARATION(Register, x5,    (5));
 95 CONSTANT_REGISTER_DECLARATION(Register, x6,    (6));
 96 CONSTANT_REGISTER_DECLARATION(Register, x7,    (7));
 97 CONSTANT_REGISTER_DECLARATION(Register, x8,    (8));
 98 CONSTANT_REGISTER_DECLARATION(Register, x9,    (9));
 99 CONSTANT_REGISTER_DECLARATION(Register, x10,  (10));
100 CONSTANT_REGISTER_DECLARATION(Register, x11,  (11));
101 CONSTANT_REGISTER_DECLARATION(Register, x12,  (12));
102 CONSTANT_REGISTER_DECLARATION(Register, x13,  (13));
103 CONSTANT_REGISTER_DECLARATION(Register, x14,  (14));
104 CONSTANT_REGISTER_DECLARATION(Register, x15,  (15));
105 CONSTANT_REGISTER_DECLARATION(Register, x16,  (16));
106 CONSTANT_REGISTER_DECLARATION(Register, x17,  (17));
107 CONSTANT_REGISTER_DECLARATION(Register, x18,  (18));
108 CONSTANT_REGISTER_DECLARATION(Register, x19,  (19));
109 CONSTANT_REGISTER_DECLARATION(Register, x20,  (20));
110 CONSTANT_REGISTER_DECLARATION(Register, x21,  (21));
111 CONSTANT_REGISTER_DECLARATION(Register, x22,  (22));
112 CONSTANT_REGISTER_DECLARATION(Register, x23,  (23));
113 CONSTANT_REGISTER_DECLARATION(Register, x24,  (24));
114 CONSTANT_REGISTER_DECLARATION(Register, x25,  (25));
115 CONSTANT_REGISTER_DECLARATION(Register, x26,  (26));
116 CONSTANT_REGISTER_DECLARATION(Register, x27,  (27));
117 CONSTANT_REGISTER_DECLARATION(Register, x28,  (28));
118 CONSTANT_REGISTER_DECLARATION(Register, x29,  (29));
119 CONSTANT_REGISTER_DECLARATION(Register, x30,  (30));
120 CONSTANT_REGISTER_DECLARATION(Register, x31,  (31));
121 
122 // Use FloatRegister as shortcut
123 class FloatRegisterImpl;
124 typedef FloatRegisterImpl* FloatRegister;
125 
126 inline FloatRegister as_FloatRegister(int encoding) {
127   return (FloatRegister)(intptr_t) encoding;
128 }
129 
130 // The implementation of floating point registers for the architecture
131 class FloatRegisterImpl: public AbstractRegisterImpl {
132  public:
133   enum {
134     number_of_registers     = 32,
135     max_slots_per_register  = 2
136   };
137 
138   // construction
139   inline friend FloatRegister as_FloatRegister(int encoding);
140 
141   VMReg as_VMReg();
142 
143   // derived registers, offsets, and addresses
144   FloatRegister successor() const                          { return as_FloatRegister(encoding() + 1); }
145 
146   // accessors
147   int   encoding() const                          { assert(is_valid(), "invalid register"); return (intptr_t)this; }
148   int   encoding_nocheck() const                         { return (intptr_t)this; }
149   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
150   const char* name() const;
151 
152 };
153 
154 // The float registers of the RISCV64 architecture
155 
156 CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
157 
158 CONSTANT_REGISTER_DECLARATION(FloatRegister, f0     , ( 0));
159 CONSTANT_REGISTER_DECLARATION(FloatRegister, f1     , ( 1));
160 CONSTANT_REGISTER_DECLARATION(FloatRegister, f2     , ( 2));
161 CONSTANT_REGISTER_DECLARATION(FloatRegister, f3     , ( 3));
162 CONSTANT_REGISTER_DECLARATION(FloatRegister, f4     , ( 4));
163 CONSTANT_REGISTER_DECLARATION(FloatRegister, f5     , ( 5));
164 CONSTANT_REGISTER_DECLARATION(FloatRegister, f6     , ( 6));
165 CONSTANT_REGISTER_DECLARATION(FloatRegister, f7     , ( 7));
166 CONSTANT_REGISTER_DECLARATION(FloatRegister, f8     , ( 8));
167 CONSTANT_REGISTER_DECLARATION(FloatRegister, f9     , ( 9));
168 CONSTANT_REGISTER_DECLARATION(FloatRegister, f10    , (10));
169 CONSTANT_REGISTER_DECLARATION(FloatRegister, f11    , (11));
170 CONSTANT_REGISTER_DECLARATION(FloatRegister, f12    , (12));
171 CONSTANT_REGISTER_DECLARATION(FloatRegister, f13    , (13));
172 CONSTANT_REGISTER_DECLARATION(FloatRegister, f14    , (14));
173 CONSTANT_REGISTER_DECLARATION(FloatRegister, f15    , (15));
174 CONSTANT_REGISTER_DECLARATION(FloatRegister, f16    , (16));
175 CONSTANT_REGISTER_DECLARATION(FloatRegister, f17    , (17));
176 CONSTANT_REGISTER_DECLARATION(FloatRegister, f18    , (18));
177 CONSTANT_REGISTER_DECLARATION(FloatRegister, f19    , (19));
178 CONSTANT_REGISTER_DECLARATION(FloatRegister, f20    , (20));
179 CONSTANT_REGISTER_DECLARATION(FloatRegister, f21    , (21));
180 CONSTANT_REGISTER_DECLARATION(FloatRegister, f22    , (22));
181 CONSTANT_REGISTER_DECLARATION(FloatRegister, f23    , (23));
182 CONSTANT_REGISTER_DECLARATION(FloatRegister, f24    , (24));
183 CONSTANT_REGISTER_DECLARATION(FloatRegister, f25    , (25));
184 CONSTANT_REGISTER_DECLARATION(FloatRegister, f26    , (26));
185 CONSTANT_REGISTER_DECLARATION(FloatRegister, f27    , (27));
186 CONSTANT_REGISTER_DECLARATION(FloatRegister, f28    , (28));
187 CONSTANT_REGISTER_DECLARATION(FloatRegister, f29    , (29));
188 CONSTANT_REGISTER_DECLARATION(FloatRegister, f30    , (30));
189 CONSTANT_REGISTER_DECLARATION(FloatRegister, f31    , (31));
190 
191 // Use VectorRegister as shortcut
192 class VectorRegisterImpl;
193 typedef VectorRegisterImpl* VectorRegister;
194 
195 inline VectorRegister as_VectorRegister(int encoding) {
196   return (VectorRegister)(intptr_t) encoding;
197 }
198 
199 // The implementation of vector registers for riscv-v
200 class VectorRegisterImpl: public AbstractRegisterImpl {
201  public:
202   enum {
203     number_of_registers    = 32,
204     max_slots_per_register = 4
205   };
206 
207   // construction
208   inline friend VectorRegister as_VectorRegister(int encoding);
209 
210   VMReg as_VMReg();
211 
212   // derived registers, offsets, and addresses
213   VectorRegister successor() const { return as_VectorRegister(encoding() + 1); }
214 
215   // accessors
216   int encoding() const             { assert(is_valid(), "invalid register"); return (intptr_t)this; }
217   int encoding_nocheck() const     { return (intptr_t)this; }
218   bool is_valid() const            { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
219   const char* name() const;
220 
221 };
222 
223 // The vector registers of RVV
224 CONSTANT_REGISTER_DECLARATION(VectorRegister, vnoreg , (-1));
225 
226 CONSTANT_REGISTER_DECLARATION(VectorRegister, v0     , ( 0));
227 CONSTANT_REGISTER_DECLARATION(VectorRegister, v1     , ( 1));
228 CONSTANT_REGISTER_DECLARATION(VectorRegister, v2     , ( 2));
229 CONSTANT_REGISTER_DECLARATION(VectorRegister, v3     , ( 3));
230 CONSTANT_REGISTER_DECLARATION(VectorRegister, v4     , ( 4));
231 CONSTANT_REGISTER_DECLARATION(VectorRegister, v5     , ( 5));
232 CONSTANT_REGISTER_DECLARATION(VectorRegister, v6     , ( 6));
233 CONSTANT_REGISTER_DECLARATION(VectorRegister, v7     , ( 7));
234 CONSTANT_REGISTER_DECLARATION(VectorRegister, v8     , ( 8));
235 CONSTANT_REGISTER_DECLARATION(VectorRegister, v9     , ( 9));
236 CONSTANT_REGISTER_DECLARATION(VectorRegister, v10    , (10));
237 CONSTANT_REGISTER_DECLARATION(VectorRegister, v11    , (11));
238 CONSTANT_REGISTER_DECLARATION(VectorRegister, v12    , (12));
239 CONSTANT_REGISTER_DECLARATION(VectorRegister, v13    , (13));
240 CONSTANT_REGISTER_DECLARATION(VectorRegister, v14    , (14));
241 CONSTANT_REGISTER_DECLARATION(VectorRegister, v15    , (15));
242 CONSTANT_REGISTER_DECLARATION(VectorRegister, v16    , (16));
243 CONSTANT_REGISTER_DECLARATION(VectorRegister, v17    , (17));
244 CONSTANT_REGISTER_DECLARATION(VectorRegister, v18    , (18));
245 CONSTANT_REGISTER_DECLARATION(VectorRegister, v19    , (19));
246 CONSTANT_REGISTER_DECLARATION(VectorRegister, v20    , (20));
247 CONSTANT_REGISTER_DECLARATION(VectorRegister, v21    , (21));
248 CONSTANT_REGISTER_DECLARATION(VectorRegister, v22    , (22));
249 CONSTANT_REGISTER_DECLARATION(VectorRegister, v23    , (23));
250 CONSTANT_REGISTER_DECLARATION(VectorRegister, v24    , (24));
251 CONSTANT_REGISTER_DECLARATION(VectorRegister, v25    , (25));
252 CONSTANT_REGISTER_DECLARATION(VectorRegister, v26    , (26));
253 CONSTANT_REGISTER_DECLARATION(VectorRegister, v27    , (27));
254 CONSTANT_REGISTER_DECLARATION(VectorRegister, v28    , (28));
255 CONSTANT_REGISTER_DECLARATION(VectorRegister, v29    , (29));
256 CONSTANT_REGISTER_DECLARATION(VectorRegister, v30    , (30));
257 CONSTANT_REGISTER_DECLARATION(VectorRegister, v31    , (31));
258 
259 
260 // Need to know the total number of registers of all sorts for SharedInfo.
261 // Define a class that exports it.
262 class ConcreteRegisterImpl : public AbstractRegisterImpl {
263  public:
264   enum {
265   // A big enough number for C2: all the registers plus flags
266   // This number must be large enough to cover REG_COUNT (defined by c2) registers.
267   // There is no requirement that any ordering here matches any ordering c2 gives
268   // it's optoregs.
269 
270     number_of_registers = (RegisterImpl::max_slots_per_register * RegisterImpl::number_of_registers +
271                            FloatRegisterImpl::max_slots_per_register * FloatRegisterImpl::number_of_registers +
272                            VectorRegisterImpl::max_slots_per_register * VectorRegisterImpl::number_of_registers)
273   };
274 
275   // added to make it compile
276   static const int max_gpr;
277   static const int max_fpr;
278   static const int max_vpr;
279 };
280 
281 // A set of registers
282 class RegSet {
283   uint32_t _bitset;
284 
285 public:
286   RegSet(uint32_t bitset) : _bitset(bitset) { }
287 
288   RegSet() : _bitset(0) { }
289 
290   RegSet(Register r1) : _bitset(r1->bit()) { }
291 
292   ~RegSet() {}
293 
294   RegSet operator+(const RegSet aSet) const {
295     RegSet result(_bitset | aSet._bitset);
296     return result;
297   }
298 
299   RegSet operator-(const RegSet aSet) const {
300     RegSet result(_bitset & ~aSet._bitset);
301     return result;
302   }
303 
304   RegSet &operator+=(const RegSet aSet) {
305     *this = *this + aSet;
306     return *this;
307   }
308 
309   RegSet &operator-=(const RegSet aSet) {
310     *this = *this - aSet;
311     return *this;
312   }
313 
314   static RegSet of(Register r1) {
315     return RegSet(r1);
316   }
317 
318   static RegSet of(Register r1, Register r2) {
319     return of(r1) + r2;
320   }
321 
322   static RegSet of(Register r1, Register r2, Register r3) {
323     return of(r1, r2) + r3;
324   }
325 
326   static RegSet of(Register r1, Register r2, Register r3, Register r4) {
327     return of(r1, r2, r3) + r4;
328   }
329 
330   static RegSet range(Register start, Register end) {
331     uint32_t bits = ~0;
332     bits <<= start->encoding();
333     bits <<= (31 - end->encoding());
334     bits >>= (31 - end->encoding());
335 
336     return RegSet(bits);
337   }
338 
339   uint32_t bits() const { return _bitset; }
340 };
341 
342 #endif // CPU_RISCV_REGISTER_RISCV_HPP