1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_CODEGEN_RISCV64_CONSTANTS_RISCV64_H_
6 #define V8_CODEGEN_RISCV64_CONSTANTS_RISCV64_H_
7
8 #include "src/base/logging.h"
9 #include "src/base/macros.h"
10 #include "src/common/globals.h"
11 #include "src/flags/flags.h"
12
13 // UNIMPLEMENTED_ macro for RISCV.
14 #ifdef DEBUG
15 #define UNIMPLEMENTED_RISCV() \
16 v8::internal::PrintF("%s, \tline %d: \tfunction %s not implemented. \n", \
17 __FILE__, __LINE__, __func__);
18 #else
19 #define UNIMPLEMENTED_RISCV()
20 #endif
21
22 #define UNSUPPORTED_RISCV() \
23 v8::internal::PrintF("Unsupported instruction %d.\n", __LINE__)
24
25 enum Endianness { kLittle, kBig };
26
27 #if defined(V8_TARGET_LITTLE_ENDIAN)
28 static const Endianness kArchEndian = kLittle;
29 #elif defined(V8_TARGET_BIG_ENDIAN)
30 static const Endianness kArchEndian = kBig;
31 #else
32 #error Unknown endianness
33 #endif
34
35 #if defined(V8_TARGET_LITTLE_ENDIAN)
36 const uint32_t kLeastSignificantByteInInt32Offset = 0;
37 const uint32_t kLessSignificantWordInDoublewordOffset = 0;
38 #elif defined(V8_TARGET_BIG_ENDIAN)
39 const uint32_t kLeastSignificantByteInInt32Offset = 3;
40 const uint32_t kLessSignificantWordInDoublewordOffset = 4;
41 #else
42 #error Unknown endianness
43 #endif
44
45 #ifndef __STDC_FORMAT_MACROS
46 #define __STDC_FORMAT_MACROS
47 #endif
48 #include <inttypes.h>
49
50 // Defines constants and accessor classes to assemble, disassemble and
51 // simulate RISC-V instructions.
52 //
53 // See: The RISC-V Instruction Set Manual
54 // Volume I: User-Level ISA
55 // Try https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf.
56
57 namespace v8 {
58 namespace internal {
59
60 constexpr size_t kMaxPCRelativeCodeRangeInMB = 4094;
61
62 // -----------------------------------------------------------------------------
63 // Registers and FPURegisters.
64
65 // Number of general purpose registers.
66 const int kNumRegisters = 32;
67 const int kInvalidRegister = -1;
68
69 // Number of registers with pc.
70 const int kNumSimuRegisters = 33;
71
72 // In the simulator, the PC register is simulated as the 34th register.
73 const int kPCRegister = 34;
74
75 // Number coprocessor registers.
76 const int kNumFPURegisters = 32;
77 const int kInvalidFPURegister = -1;
78
79 // Number vectotr registers
80 const int kNumVRegisters = 32;
81 const int kInvalidVRegister = -1;
82 // 'pref' instruction hints
83 const int32_t kPrefHintLoad = 0;
84 const int32_t kPrefHintStore = 1;
85 const int32_t kPrefHintLoadStreamed = 4;
86 const int32_t kPrefHintStoreStreamed = 5;
87 const int32_t kPrefHintLoadRetained = 6;
88 const int32_t kPrefHintStoreRetained = 7;
89 const int32_t kPrefHintWritebackInvalidate = 25;
90 const int32_t kPrefHintPrepareForStore = 30;
91
92 // Actual value of root register is offset from the root array's start
93 // to take advantage of negative displacement values.
94 // TODO(sigurds): Choose best value.
95 constexpr int kRootRegisterBias = 256;
96
97 // Helper functions for converting between register numbers and names.
98 class Registers {
99 public:
100 // Return the name of the register.
101 static const char* Name(int reg);
102
103 // Lookup the register number for the name provided.
104 static int Number(const char* name);
105
106 struct RegisterAlias {
107 int reg;
108 const char* name;
109 };
110
111 static const int64_t kMaxValue = 0x7fffffffffffffffl;
112 static const int64_t kMinValue = 0x8000000000000000l;
113
114 private:
115 static const char* names_[kNumSimuRegisters];
116 static const RegisterAlias aliases_[];
117 };
118
119 // Helper functions for converting between register numbers and names.
120 class FPURegisters {
121 public:
122 // Return the name of the register.
123 static const char* Name(int reg);
124
125 // Lookup the register number for the name provided.
126 static int Number(const char* name);
127
128 struct RegisterAlias {
129 int creg;
130 const char* name;
131 };
132
133 private:
134 static const char* names_[kNumFPURegisters];
135 static const RegisterAlias aliases_[];
136 };
137
138 class VRegisters {
139 public:
140 // Return the name of the register.
141 static const char* Name(int reg);
142
143 // Lookup the register number for the name provided.
144 static int Number(const char* name);
145
146 struct RegisterAlias {
147 int creg;
148 const char* name;
149 };
150
151 private:
152 static const char* names_[kNumVRegisters];
153 static const RegisterAlias aliases_[];
154 };
155
156 // -----------------------------------------------------------------------------
157 // Instructions encoding constants.
158
159 // On RISCV all instructions are 32 bits, except for RVC.
160 using Instr = int32_t;
161 using ShortInstr = int16_t;
162
163 // Special Software Interrupt codes when used in the presence of the RISC-V
164 // simulator.
165 enum SoftwareInterruptCodes {
166 // Transition to C code.
167 call_rt_redirected = 0xfffff
168 };
169
170 // On RISC-V Simulator breakpoints can have different codes:
171 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
172 // the simulator will run through them and print the registers.
173 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
174 // instructions (see Assembler::stop()).
175 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
176 // debugger.
177 const uint32_t kMaxWatchpointCode = 31;
178 const uint32_t kMaxStopCode = 127;
179 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
180
181 // ----- Fields offset and length.
182 // RISCV constants
183 const int kBaseOpcodeShift = 0;
184 const int kBaseOpcodeBits = 7;
185 const int kFunct7Shift = 25;
186 const int kFunct7Bits = 7;
187 const int kFunct5Shift = 27;
188 const int kFunct5Bits = 5;
189 const int kFunct3Shift = 12;
190 const int kFunct3Bits = 3;
191 const int kFunct2Shift = 25;
192 const int kFunct2Bits = 2;
193 const int kRs1Shift = 15;
194 const int kRs1Bits = 5;
195 const int kVs1Shift = 15;
196 const int kVs1Bits = 5;
197 const int kVs2Shift = 20;
198 const int kVs2Bits = 5;
199 const int kVdShift = 7;
200 const int kVdBits = 5;
201 const int kRs2Shift = 20;
202 const int kRs2Bits = 5;
203 const int kRs3Shift = 27;
204 const int kRs3Bits = 5;
205 const int kRdShift = 7;
206 const int kRdBits = 5;
207 const int kRlShift = 25;
208 const int kAqShift = 26;
209 const int kImm12Shift = 20;
210 const int kImm12Bits = 12;
211 const int kImm11Shift = 2;
212 const int kImm11Bits = 11;
213 const int kShamtShift = 20;
214 const int kShamtBits = 5;
215 const int kShamtWShift = 20;
216 const int kShamtWBits = 6;
217 const int kArithShiftShift = 30;
218 const int kImm20Shift = 12;
219 const int kImm20Bits = 20;
220 const int kCsrShift = 20;
221 const int kCsrBits = 12;
222 const int kMemOrderBits = 4;
223 const int kPredOrderShift = 24;
224 const int kSuccOrderShift = 20;
225 // for C extension
226 const int kRvcFunct4Shift = 12;
227 const int kRvcFunct4Bits = 4;
228 const int kRvcFunct3Shift = 13;
229 const int kRvcFunct3Bits = 3;
230 const int kRvcRs1Shift = 7;
231 const int kRvcRs1Bits = 5;
232 const int kRvcRs2Shift = 2;
233 const int kRvcRs2Bits = 5;
234 const int kRvcRdShift = 7;
235 const int kRvcRdBits = 5;
236 const int kRvcRs1sShift = 7;
237 const int kRvcRs1sBits = 3;
238 const int kRvcRs2sShift = 2;
239 const int kRvcRs2sBits = 3;
240 const int kRvcFunct2Shift = 5;
241 const int kRvcFunct2BShift = 10;
242 const int kRvcFunct2Bits = 2;
243 const int kRvcFunct6Shift = 10;
244 const int kRvcFunct6Bits = 6;
245
246 // for RVV extension
247 constexpr int kRvvELEN = 64;
248 constexpr int kRvvVLEN = 128;
249 constexpr int kRvvSLEN = kRvvVLEN;
250 const int kRvvFunct6Shift = 26;
251 const int kRvvFunct6Bits = 6;
252 const uint32_t kRvvFunct6Mask =
253 (((1 << kRvvFunct6Bits) - 1) << kRvvFunct6Shift);
254
255 const int kRvvVmBits = 1;
256 const int kRvvVmShift = 25;
257 const uint32_t kRvvVmMask = (((1 << kRvvVmBits) - 1) << kRvvVmShift);
258
259 const int kRvvVs2Bits = 5;
260 const int kRvvVs2Shift = 20;
261 const uint32_t kRvvVs2Mask = (((1 << kRvvVs2Bits) - 1) << kRvvVs2Shift);
262
263 const int kRvvVs1Bits = 5;
264 const int kRvvVs1Shift = 15;
265 const uint32_t kRvvVs1Mask = (((1 << kRvvVs1Bits) - 1) << kRvvVs1Shift);
266
267 const int kRvvRs1Bits = kRvvVs1Bits;
268 const int kRvvRs1Shift = kRvvVs1Shift;
269 const uint32_t kRvvRs1Mask = (((1 << kRvvRs1Bits) - 1) << kRvvRs1Shift);
270
271 const int kRvvRs2Bits = 5;
272 const int kRvvRs2Shift = 20;
273 const uint32_t kRvvRs2Mask = (((1 << kRvvRs2Bits) - 1) << kRvvRs2Shift);
274
275 const int kRvvImm5Bits = kRvvVs1Bits;
276 const int kRvvImm5Shift = kRvvVs1Shift;
277 const uint32_t kRvvImm5Mask = (((1 << kRvvImm5Bits) - 1) << kRvvImm5Shift);
278
279 const int kRvvVdBits = 5;
280 const int kRvvVdShift = 7;
281 const uint32_t kRvvVdMask = (((1 << kRvvVdBits) - 1) << kRvvVdShift);
282
283 const int kRvvRdBits = kRvvVdBits;
284 const int kRvvRdShift = kRvvVdShift;
285 const uint32_t kRvvRdMask = (((1 << kRvvRdBits) - 1) << kRvvRdShift);
286
287 const int kRvvZimmBits = 11;
288 const int kRvvZimmShift = 20;
289 const uint32_t kRvvZimmMask = (((1 << kRvvZimmBits) - 1) << kRvvZimmShift);
290
291 const int kRvvUimmShift = kRvvRs1Shift;
292 const int kRvvUimmBits = kRvvRs1Bits;
293 const uint32_t kRvvUimmMask = (((1 << kRvvUimmBits) - 1) << kRvvUimmShift);
294
295 const int kRvvWidthBits = 3;
296 const int kRvvWidthShift = 12;
297 const uint32_t kRvvWidthMask = (((1 << kRvvWidthBits) - 1) << kRvvWidthShift);
298
299 const int kRvvMopBits = 2;
300 const int kRvvMopShift = 26;
301 const uint32_t kRvvMopMask = (((1 << kRvvMopBits) - 1) << kRvvMopShift);
302
303 const int kRvvMewBits = 1;
304 const int kRvvMewShift = 28;
305 const uint32_t kRvvMewMask = (((1 << kRvvMewBits) - 1) << kRvvMewShift);
306
307 const int kRvvNfBits = 3;
308 const int kRvvNfShift = 29;
309 const uint32_t kRvvNfMask = (((1 << kRvvNfBits) - 1) << kRvvNfShift);
310
311 // RISCV Instruction bit masks
312 const uint32_t kBaseOpcodeMask = ((1 << kBaseOpcodeBits) - 1)
313 << kBaseOpcodeShift;
314 const uint32_t kFunct3Mask = ((1 << kFunct3Bits) - 1) << kFunct3Shift;
315 const uint32_t kFunct5Mask = ((1 << kFunct5Bits) - 1) << kFunct5Shift;
316 const uint32_t kFunct7Mask = ((1 << kFunct7Bits) - 1) << kFunct7Shift;
317 const uint32_t kFunct2Mask = 0b11 << kFunct7Shift;
318 const uint32_t kRTypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct7Mask;
319 const uint32_t kRATypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct5Mask;
320 const uint32_t kRFPTypeMask = kBaseOpcodeMask | kFunct7Mask;
321 const uint32_t kR4TypeMask = kBaseOpcodeMask | kFunct3Mask | kFunct2Mask;
322 const uint32_t kITypeMask = kBaseOpcodeMask | kFunct3Mask;
323 const uint32_t kSTypeMask = kBaseOpcodeMask | kFunct3Mask;
324 const uint32_t kBTypeMask = kBaseOpcodeMask | kFunct3Mask;
325 const uint32_t kUTypeMask = kBaseOpcodeMask;
326 const uint32_t kJTypeMask = kBaseOpcodeMask;
327 const uint32_t kVTypeMask = kRvvFunct6Mask | kFunct3Mask | kBaseOpcodeMask;
328 const uint32_t kRs1FieldMask = ((1 << kRs1Bits) - 1) << kRs1Shift;
329 const uint32_t kRs2FieldMask = ((1 << kRs2Bits) - 1) << kRs2Shift;
330 const uint32_t kRs3FieldMask = ((1 << kRs3Bits) - 1) << kRs3Shift;
331 const uint32_t kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
332 const uint32_t kBImm12Mask = kFunct7Mask | kRdFieldMask;
333 const uint32_t kImm20Mask = ((1 << kImm20Bits) - 1) << kImm20Shift;
334 const uint32_t kImm12Mask = ((1 << kImm12Bits) - 1) << kImm12Shift;
335 const uint32_t kImm11Mask = ((1 << kImm11Bits) - 1) << kImm11Shift;
336 const uint32_t kImm31_12Mask = ((1 << 20) - 1) << 12;
337 const uint32_t kImm19_0Mask = ((1 << 20) - 1);
338 const uint32_t kRvcOpcodeMask =
339 0b11 | (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
340 const uint32_t kRvcFunct3Mask =
341 (((1 << kRvcFunct3Bits) - 1) << kRvcFunct3Shift);
342 const uint32_t kRvcFunct4Mask =
343 (((1 << kRvcFunct4Bits) - 1) << kRvcFunct4Shift);
344 const uint32_t kRvcFunct6Mask =
345 (((1 << kRvcFunct6Bits) - 1) << kRvcFunct6Shift);
346 const uint32_t kRvcFunct2Mask =
347 (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2Shift);
348 const uint32_t kRvcFunct2BMask =
349 (((1 << kRvcFunct2Bits) - 1) << kRvcFunct2BShift);
350 const uint32_t kCRTypeMask = kRvcOpcodeMask | kRvcFunct4Mask;
351 const uint32_t kCSTypeMask = kRvcOpcodeMask | kRvcFunct6Mask;
352 const uint32_t kCATypeMask = kRvcOpcodeMask | kRvcFunct6Mask | kRvcFunct2Mask;
353 const uint32_t kRvcBImm8Mask = (((1 << 5) - 1) << 2) | (((1 << 3) - 1) << 10);
354
355 // RISCV CSR related bit mask and shift
356 const int kFcsrFlagsBits = 5;
357 const uint32_t kFcsrFlagsMask = (1 << kFcsrFlagsBits) - 1;
358 const int kFcsrFrmBits = 3;
359 const int kFcsrFrmShift = kFcsrFlagsBits;
360 const uint32_t kFcsrFrmMask = ((1 << kFcsrFrmBits) - 1) << kFcsrFrmShift;
361 const int kFcsrBits = kFcsrFlagsBits + kFcsrFrmBits;
362 const uint32_t kFcsrMask = kFcsrFlagsMask | kFcsrFrmMask;
363
364 const int kNopByte = 0x00000013;
365 // Original MIPS constants
366 // TODO(RISCV): to be cleaned up
367 const int kImm16Shift = 0;
368 const int kImm16Bits = 16;
369 const uint32_t kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
370 // end of TODO(RISCV): to be cleaned up
371
372 // ----- RISCV Base Opcodes
373
374 enum BaseOpcode : uint32_t {};
375
376 // ----- RISC-V Opcodes and Function Fields.
377 enum Opcode : uint32_t {
378 LOAD = 0b0000011, // I form: LB LH LW LBU LHU
379 LOAD_FP = 0b0000111, // I form: FLW FLD FLQ
380 MISC_MEM = 0b0001111, // I special form: FENCE FENCE.I
381 OP_IMM = 0b0010011, // I form: ADDI SLTI SLTIU XORI ORI ANDI SLLI SRLI SARI
382 // Note: SLLI/SRLI/SRAI I form first, then func3 001/101 => R type
383 AUIPC = 0b0010111, // U form: AUIPC
384 OP_IMM_32 = 0b0011011, // I form: ADDIW SLLIW SRLIW SRAIW
385 // Note: SRLIW SRAIW I form first, then func3 101 special shift encoding
386 STORE = 0b0100011, // S form: SB SH SW SD
387 STORE_FP = 0b0100111, // S form: FSW FSD FSQ
388 AMO = 0b0101111, // R form: All A instructions
389 OP = 0b0110011, // R: ADD SUB SLL SLT SLTU XOR SRL SRA OR AND and 32M set
390 LUI = 0b0110111, // U form: LUI
391 OP_32 = 0b0111011, // R: ADDW SUBW SLLW SRLW SRAW MULW DIVW DIVUW REMW REMUW
392 MADD = 0b1000011, // R4 type: FMADD.S FMADD.D FMADD.Q
393 MSUB = 0b1000111, // R4 type: FMSUB.S FMSUB.D FMSUB.Q
394 NMSUB = 0b1001011, // R4 type: FNMSUB.S FNMSUB.D FNMSUB.Q
395 NMADD = 0b1001111, // R4 type: FNMADD.S FNMADD.D FNMADD.Q
396 OP_FP = 0b1010011, // R type: Q ext
397 BRANCH = 0b1100011, // B form: BEQ BNE, BLT, BGE, BLTU BGEU
398 JALR = 0b1100111, // I form: JALR
399 JAL = 0b1101111, // J form: JAL
400 SYSTEM = 0b1110011, // I form: ECALL EBREAK Zicsr ext
401 // C extension
402 C0 = 0b00,
403 C1 = 0b01,
404 C2 = 0b10,
405 FUNCT2_0 = 0b00,
406 FUNCT2_1 = 0b01,
407 FUNCT2_2 = 0b10,
408 FUNCT2_3 = 0b11,
409
410 // Note use RO (RiscV Opcode) prefix
411 // RV32I Base Instruction Set
412 RO_LUI = LUI,
413 RO_AUIPC = AUIPC,
414 RO_JAL = JAL,
415 RO_JALR = JALR | (0b000 << kFunct3Shift),
416 RO_BEQ = BRANCH | (0b000 << kFunct3Shift),
417 RO_BNE = BRANCH | (0b001 << kFunct3Shift),
418 RO_BLT = BRANCH | (0b100 << kFunct3Shift),
419 RO_BGE = BRANCH | (0b101 << kFunct3Shift),
420 RO_BLTU = BRANCH | (0b110 << kFunct3Shift),
421 RO_BGEU = BRANCH | (0b111 << kFunct3Shift),
422 RO_LB = LOAD | (0b000 << kFunct3Shift),
423 RO_LH = LOAD | (0b001 << kFunct3Shift),
424 RO_LW = LOAD | (0b010 << kFunct3Shift),
425 RO_LBU = LOAD | (0b100 << kFunct3Shift),
426 RO_LHU = LOAD | (0b101 << kFunct3Shift),
427 RO_SB = STORE | (0b000 << kFunct3Shift),
428 RO_SH = STORE | (0b001 << kFunct3Shift),
429 RO_SW = STORE | (0b010 << kFunct3Shift),
430 RO_ADDI = OP_IMM | (0b000 << kFunct3Shift),
431 RO_SLTI = OP_IMM | (0b010 << kFunct3Shift),
432 RO_SLTIU = OP_IMM | (0b011 << kFunct3Shift),
433 RO_XORI = OP_IMM | (0b100 << kFunct3Shift),
434 RO_ORI = OP_IMM | (0b110 << kFunct3Shift),
435 RO_ANDI = OP_IMM | (0b111 << kFunct3Shift),
436 RO_SLLI = OP_IMM | (0b001 << kFunct3Shift),
437 RO_SRLI = OP_IMM | (0b101 << kFunct3Shift),
438 // RO_SRAI = OP_IMM | (0b101 << kFunct3Shift), // Same as SRLI, use func7
439 RO_ADD = OP | (0b000 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
440 RO_SUB = OP | (0b000 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
441 RO_SLL = OP | (0b001 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
442 RO_SLT = OP | (0b010 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
443 RO_SLTU = OP | (0b011 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
444 RO_XOR = OP | (0b100 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
445 RO_SRL = OP | (0b101 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
446 RO_SRA = OP | (0b101 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
447 RO_OR = OP | (0b110 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
448 RO_AND = OP | (0b111 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
449 RO_FENCE = MISC_MEM | (0b000 << kFunct3Shift),
450 RO_ECALL = SYSTEM | (0b000 << kFunct3Shift),
451 // RO_EBREAK = SYSTEM | (0b000 << kFunct3Shift), // Same as ECALL, use imm12
452
453 // RV64I Base Instruction Set (in addition to RV32I)
454 RO_LWU = LOAD | (0b110 << kFunct3Shift),
455 RO_LD = LOAD | (0b011 << kFunct3Shift),
456 RO_SD = STORE | (0b011 << kFunct3Shift),
457 RO_ADDIW = OP_IMM_32 | (0b000 << kFunct3Shift),
458 RO_SLLIW = OP_IMM_32 | (0b001 << kFunct3Shift),
459 RO_SRLIW = OP_IMM_32 | (0b101 << kFunct3Shift),
460 // RO_SRAIW = OP_IMM_32 | (0b101 << kFunct3Shift), // Same as SRLIW, use func7
461 RO_ADDW = OP_32 | (0b000 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
462 RO_SUBW = OP_32 | (0b000 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
463 RO_SLLW = OP_32 | (0b001 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
464 RO_SRLW = OP_32 | (0b101 << kFunct3Shift) | (0b0000000 << kFunct7Shift),
465 RO_SRAW = OP_32 | (0b101 << kFunct3Shift) | (0b0100000 << kFunct7Shift),
466
467 // RV32/RV64 Zifencei Standard Extension
468 RO_FENCE_I = MISC_MEM | (0b001 << kFunct3Shift),
469
470 // RV32/RV64 Zicsr Standard Extension
471 RO_CSRRW = SYSTEM | (0b001 << kFunct3Shift),
472 RO_CSRRS = SYSTEM | (0b010 << kFunct3Shift),
473 RO_CSRRC = SYSTEM | (0b011 << kFunct3Shift),
474 RO_CSRRWI = SYSTEM | (0b101 << kFunct3Shift),
475 RO_CSRRSI = SYSTEM | (0b110 << kFunct3Shift),
476 RO_CSRRCI = SYSTEM | (0b111 << kFunct3Shift),
477
478 // RV32M Standard Extension
479 RO_MUL = OP | (0b000 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
480 RO_MULH = OP | (0b001 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
481 RO_MULHSU = OP | (0b010 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
482 RO_MULHU = OP | (0b011 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
483 RO_DIV = OP | (0b100 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
484 RO_DIVU = OP | (0b101 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
485 RO_REM = OP | (0b110 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
486 RO_REMU = OP | (0b111 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
487
488 // RV64M Standard Extension (in addition to RV32M)
489 RO_MULW = OP_32 | (0b000 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
490 RO_DIVW = OP_32 | (0b100 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
491 RO_DIVUW = OP_32 | (0b101 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
492 RO_REMW = OP_32 | (0b110 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
493 RO_REMUW = OP_32 | (0b111 << kFunct3Shift) | (0b0000001 << kFunct7Shift),
494
495 // RV32A Standard Extension
496 RO_LR_W = AMO | (0b010 << kFunct3Shift) | (0b00010 << kFunct5Shift),
497 RO_SC_W = AMO | (0b010 << kFunct3Shift) | (0b00011 << kFunct5Shift),
498 RO_AMOSWAP_W = AMO | (0b010 << kFunct3Shift) | (0b00001 << kFunct5Shift),
499 RO_AMOADD_W = AMO | (0b010 << kFunct3Shift) | (0b00000 << kFunct5Shift),
500 RO_AMOXOR_W = AMO | (0b010 << kFunct3Shift) | (0b00100 << kFunct5Shift),
501 RO_AMOAND_W = AMO | (0b010 << kFunct3Shift) | (0b01100 << kFunct5Shift),
502 RO_AMOOR_W = AMO | (0b010 << kFunct3Shift) | (0b01000 << kFunct5Shift),
503 RO_AMOMIN_W = AMO | (0b010 << kFunct3Shift) | (0b10000 << kFunct5Shift),
504 RO_AMOMAX_W = AMO | (0b010 << kFunct3Shift) | (0b10100 << kFunct5Shift),
505 RO_AMOMINU_W = AMO | (0b010 << kFunct3Shift) | (0b11000 << kFunct5Shift),
506 RO_AMOMAXU_W = AMO | (0b010 << kFunct3Shift) | (0b11100 << kFunct5Shift),
507
508 // RV64A Standard Extension (in addition to RV32A)
509 RO_LR_D = AMO | (0b011 << kFunct3Shift) | (0b00010 << kFunct5Shift),
510 RO_SC_D = AMO | (0b011 << kFunct3Shift) | (0b00011 << kFunct5Shift),
511 RO_AMOSWAP_D = AMO | (0b011 << kFunct3Shift) | (0b00001 << kFunct5Shift),
512 RO_AMOADD_D = AMO | (0b011 << kFunct3Shift) | (0b00000 << kFunct5Shift),
513 RO_AMOXOR_D = AMO | (0b011 << kFunct3Shift) | (0b00100 << kFunct5Shift),
514 RO_AMOAND_D = AMO | (0b011 << kFunct3Shift) | (0b01100 << kFunct5Shift),
515 RO_AMOOR_D = AMO | (0b011 << kFunct3Shift) | (0b01000 << kFunct5Shift),
516 RO_AMOMIN_D = AMO | (0b011 << kFunct3Shift) | (0b10000 << kFunct5Shift),
517 RO_AMOMAX_D = AMO | (0b011 << kFunct3Shift) | (0b10100 << kFunct5Shift),
518 RO_AMOMINU_D = AMO | (0b011 << kFunct3Shift) | (0b11000 << kFunct5Shift),
519 RO_AMOMAXU_D = AMO | (0b011 << kFunct3Shift) | (0b11100 << kFunct5Shift),
520
521 // RV32F Standard Extension
522 RO_FLW = LOAD_FP | (0b010 << kFunct3Shift),
523 RO_FSW = STORE_FP | (0b010 << kFunct3Shift),
524 RO_FMADD_S = MADD | (0b00 << kFunct2Shift),
525 RO_FMSUB_S = MSUB | (0b00 << kFunct2Shift),
526 RO_FNMSUB_S = NMSUB | (0b00 << kFunct2Shift),
527 RO_FNMADD_S = NMADD | (0b00 << kFunct2Shift),
528 RO_FADD_S = OP_FP | (0b0000000 << kFunct7Shift),
529 RO_FSUB_S = OP_FP | (0b0000100 << kFunct7Shift),
530 RO_FMUL_S = OP_FP | (0b0001000 << kFunct7Shift),
531 RO_FDIV_S = OP_FP | (0b0001100 << kFunct7Shift),
532 RO_FSQRT_S = OP_FP | (0b0101100 << kFunct7Shift) | (0b00000 << kRs2Shift),
533 RO_FSGNJ_S = OP_FP | (0b000 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
534 RO_FSGNJN_S = OP_FP | (0b001 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
535 RO_FSQNJX_S = OP_FP | (0b010 << kFunct3Shift) | (0b0010000 << kFunct7Shift),
536 RO_FMIN_S = OP_FP | (0b000 << kFunct3Shift) | (0b0010100 << kFunct7Shift),
537 RO_FMAX_S = OP_FP | (0b001 << kFunct3Shift) | (0b0010100 << kFunct7Shift),
538 RO_FCVT_W_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00000 << kRs2Shift),
539 RO_FCVT_WU_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00001 << kRs2Shift),
540 RO_FMV = OP_FP | (0b1110000 << kFunct7Shift) | (0b000 << kFunct3Shift) |
541 (0b00000 << kRs2Shift),
542 RO_FEQ_S = OP_FP | (0b010 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
543 RO_FLT_S = OP_FP | (0b001 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
544 RO_FLE_S = OP_FP | (0b000 << kFunct3Shift) | (0b1010000 << kFunct7Shift),
545 RO_FCLASS_S = OP_FP | (0b001 << kFunct3Shift) | (0b1110000 << kFunct7Shift),
546 RO_FCVT_S_W = OP_FP | (0b1101000 << kFunct7Shift) | (0b00000 << kRs2Shift),
547 RO_FCVT_S_WU = OP_FP | (0b1101000 << kFunct7Shift) | (0b00001 << kRs2Shift),
548 RO_FMV_W_X = OP_FP | (0b000 << kFunct3Shift) | (0b1111000 << kFunct7Shift),
549
550 // RV64F Standard Extension (in addition to RV32F)
551 RO_FCVT_L_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00010 << kRs2Shift),
552 RO_FCVT_LU_S = OP_FP | (0b1100000 << kFunct7Shift) | (0b00011 << kRs2Shift),
553 RO_FCVT_S_L = OP_FP | (0b1101000 << kFunct7Shift) | (0b00010 << kRs2Shift),
554 RO_FCVT_S_LU = OP_FP | (0b1101000 << kFunct7Shift) | (0b00011 << kRs2Shift),
555
556 // RV32D Standard Extension
557 RO_FLD = LOAD_FP | (0b011 << kFunct3Shift),
558 RO_FSD = STORE_FP | (0b011 << kFunct3Shift),
559 RO_FMADD_D = MADD | (0b01 << kFunct2Shift),
560 RO_FMSUB_D = MSUB | (0b01 << kFunct2Shift),
561 RO_FNMSUB_D = NMSUB | (0b01 << kFunct2Shift),
562 RO_FNMADD_D = NMADD | (0b01 << kFunct2Shift),
563 RO_FADD_D = OP_FP | (0b0000001 << kFunct7Shift),
564 RO_FSUB_D = OP_FP | (0b0000101 << kFunct7Shift),
565 RO_FMUL_D = OP_FP | (0b0001001 << kFunct7Shift),
566 RO_FDIV_D = OP_FP | (0b0001101 << kFunct7Shift),
567 RO_FSQRT_D = OP_FP | (0b0101101 << kFunct7Shift) | (0b00000 << kRs2Shift),
568 RO_FSGNJ_D = OP_FP | (0b000 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
569 RO_FSGNJN_D = OP_FP | (0b001 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
570 RO_FSQNJX_D = OP_FP | (0b010 << kFunct3Shift) | (0b0010001 << kFunct7Shift),
571 RO_FMIN_D = OP_FP | (0b000 << kFunct3Shift) | (0b0010101 << kFunct7Shift),
572 RO_FMAX_D = OP_FP | (0b001 << kFunct3Shift) | (0b0010101 << kFunct7Shift),
573 RO_FCVT_S_D = OP_FP | (0b0100000 << kFunct7Shift) | (0b00001 << kRs2Shift),
574 RO_FCVT_D_S = OP_FP | (0b0100001 << kFunct7Shift) | (0b00000 << kRs2Shift),
575 RO_FEQ_D = OP_FP | (0b010 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
576 RO_FLT_D = OP_FP | (0b001 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
577 RO_FLE_D = OP_FP | (0b000 << kFunct3Shift) | (0b1010001 << kFunct7Shift),
578 RO_FCLASS_D = OP_FP | (0b001 << kFunct3Shift) | (0b1110001 << kFunct7Shift) |
579 (0b00000 << kRs2Shift),
580 RO_FCVT_W_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00000 << kRs2Shift),
581 RO_FCVT_WU_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00001 << kRs2Shift),
582 RO_FCVT_D_W = OP_FP | (0b1101001 << kFunct7Shift) | (0b00000 << kRs2Shift),
583 RO_FCVT_D_WU = OP_FP | (0b1101001 << kFunct7Shift) | (0b00001 << kRs2Shift),
584
585 // RV64D Standard Extension (in addition to RV32D)
586 RO_FCVT_L_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00010 << kRs2Shift),
587 RO_FCVT_LU_D = OP_FP | (0b1100001 << kFunct7Shift) | (0b00011 << kRs2Shift),
588 RO_FMV_X_D = OP_FP | (0b000 << kFunct3Shift) | (0b1110001 << kFunct7Shift) |
589 (0b00000 << kRs2Shift),
590 RO_FCVT_D_L = OP_FP | (0b1101001 << kFunct7Shift) | (0b00010 << kRs2Shift),
591 RO_FCVT_D_LU = OP_FP | (0b1101001 << kFunct7Shift) | (0b00011 << kRs2Shift),
592 RO_FMV_D_X = OP_FP | (0b000 << kFunct3Shift) | (0b1111001 << kFunct7Shift) |
593 (0b00000 << kRs2Shift),
594
595 // RV64C Standard Extension
596 RO_C_ADDI4SPN = C0 | (0b000 << kRvcFunct3Shift),
597 RO_C_FLD = C0 | (0b001 << kRvcFunct3Shift),
598 RO_C_LW = C0 | (0b010 << kRvcFunct3Shift),
599 RO_C_LD = C0 | (0b011 << kRvcFunct3Shift),
600 RO_C_FSD = C0 | (0b101 << kRvcFunct3Shift),
601 RO_C_SW = C0 | (0b110 << kRvcFunct3Shift),
602 RO_C_SD = C0 | (0b111 << kRvcFunct3Shift),
603 RO_C_NOP_ADDI = C1 | (0b000 << kRvcFunct3Shift),
604 RO_C_ADDIW = C1 | (0b001 << kRvcFunct3Shift),
605 RO_C_LI = C1 | (0b010 << kRvcFunct3Shift),
606 RO_C_SUB = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_0 << kRvcFunct2Shift),
607 RO_C_XOR = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_1 << kRvcFunct2Shift),
608 RO_C_OR = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_2 << kRvcFunct2Shift),
609 RO_C_AND = C1 | (0b100011 << kRvcFunct6Shift) | (FUNCT2_3 << kRvcFunct2Shift),
610 RO_C_SUBW =
611 C1 | (0b100111 << kRvcFunct6Shift) | (FUNCT2_0 << kRvcFunct2Shift),
612 RO_C_ADDW =
613 C1 | (0b100111 << kRvcFunct6Shift) | (FUNCT2_1 << kRvcFunct2Shift),
614 RO_C_LUI_ADD = C1 | (0b011 << kRvcFunct3Shift),
615 RO_C_MISC_ALU = C1 | (0b100 << kRvcFunct3Shift),
616 RO_C_J = C1 | (0b101 << kRvcFunct3Shift),
617 RO_C_BEQZ = C1 | (0b110 << kRvcFunct3Shift),
618 RO_C_BNEZ = C1 | (0b111 << kRvcFunct3Shift),
619 RO_C_SLLI = C2 | (0b000 << kRvcFunct3Shift),
620 RO_C_FLDSP = C2 | (0b001 << kRvcFunct3Shift),
621 RO_C_LWSP = C2 | (0b010 << kRvcFunct3Shift),
622 RO_C_LDSP = C2 | (0b011 << kRvcFunct3Shift),
623 RO_C_JR_MV_ADD = C2 | (0b100 << kRvcFunct3Shift),
624 RO_C_JR = C2 | (0b1000 << kRvcFunct4Shift),
625 RO_C_MV = C2 | (0b1000 << kRvcFunct4Shift),
626 RO_C_EBREAK = C2 | (0b1001 << kRvcFunct4Shift),
627 RO_C_JALR = C2 | (0b1001 << kRvcFunct4Shift),
628 RO_C_ADD = C2 | (0b1001 << kRvcFunct4Shift),
629 RO_C_FSDSP = C2 | (0b101 << kRvcFunct3Shift),
630 RO_C_SWSP = C2 | (0b110 << kRvcFunct3Shift),
631 RO_C_SDSP = C2 | (0b111 << kRvcFunct3Shift),
632
633 // RVV Extension
634 OP_V = 0b1010111,
635 OP_IVV = OP_V | (0b000 << kFunct3Shift),
636 OP_FVV = OP_V | (0b001 << kFunct3Shift),
637 OP_MVV = OP_V | (0b010 << kFunct3Shift),
638 OP_IVI = OP_V | (0b011 << kFunct3Shift),
639 OP_IVX = OP_V | (0b100 << kFunct3Shift),
640 OP_FVF = OP_V | (0b101 << kFunct3Shift),
641 OP_MVX = OP_V | (0b110 << kFunct3Shift),
642
643 RO_V_VSETVLI = OP_V | (0b111 << kFunct3Shift) | 0b0 << 31,
644 RO_V_VSETIVLI = OP_V | (0b111 << kFunct3Shift) | 0b11 << 30,
645 RO_V_VSETVL = OP_V | (0b111 << kFunct3Shift) | 0b1 << 31,
646
647 // RVV LOAD/STORE
648 RO_V_VL = LOAD_FP | (0b00 << kRvvMopShift) | (0b000 << kRvvNfShift),
649 RO_V_VLS = LOAD_FP | (0b10 << kRvvMopShift) | (0b000 << kRvvNfShift),
650 RO_V_VLX = LOAD_FP | (0b11 << kRvvMopShift) | (0b000 << kRvvNfShift),
651
652 RO_V_VS = STORE_FP | (0b00 << kRvvMopShift) | (0b000 << kRvvNfShift),
653 RO_V_VSS = STORE_FP | (0b10 << kRvvMopShift) | (0b000 << kRvvNfShift),
654 RO_V_VSX = STORE_FP | (0b11 << kRvvMopShift) | (0b000 << kRvvNfShift),
655 RO_V_VSU = STORE_FP | (0b01 << kRvvMopShift) | (0b000 << kRvvNfShift),
656 // THE kFunct6Shift is mop
657 RO_V_VLSEG2 = LOAD_FP | (0b00 << kRvvMopShift) | (0b001 << kRvvNfShift),
658 RO_V_VLSEG3 = LOAD_FP | (0b00 << kRvvMopShift) | (0b010 << kRvvNfShift),
659 RO_V_VLSEG4 = LOAD_FP | (0b00 << kRvvMopShift) | (0b011 << kRvvNfShift),
660 RO_V_VLSEG5 = LOAD_FP | (0b00 << kRvvMopShift) | (0b100 << kRvvNfShift),
661 RO_V_VLSEG6 = LOAD_FP | (0b00 << kRvvMopShift) | (0b101 << kRvvNfShift),
662 RO_V_VLSEG7 = LOAD_FP | (0b00 << kRvvMopShift) | (0b110 << kRvvNfShift),
663 RO_V_VLSEG8 = LOAD_FP | (0b00 << kRvvMopShift) | (0b111 << kRvvNfShift),
664
665 RO_V_VSSEG2 = STORE_FP | (0b00 << kRvvMopShift) | (0b001 << kRvvNfShift),
666 RO_V_VSSEG3 = STORE_FP | (0b00 << kRvvMopShift) | (0b010 << kRvvNfShift),
667 RO_V_VSSEG4 = STORE_FP | (0b00 << kRvvMopShift) | (0b011 << kRvvNfShift),
668 RO_V_VSSEG5 = STORE_FP | (0b00 << kRvvMopShift) | (0b100 << kRvvNfShift),
669 RO_V_VSSEG6 = STORE_FP | (0b00 << kRvvMopShift) | (0b101 << kRvvNfShift),
670 RO_V_VSSEG7 = STORE_FP | (0b00 << kRvvMopShift) | (0b110 << kRvvNfShift),
671 RO_V_VSSEG8 = STORE_FP | (0b00 << kRvvMopShift) | (0b111 << kRvvNfShift),
672
673 RO_V_VLSSEG2 = LOAD_FP | (0b10 << kRvvMopShift) | (0b001 << kRvvNfShift),
674 RO_V_VLSSEG3 = LOAD_FP | (0b10 << kRvvMopShift) | (0b010 << kRvvNfShift),
675 RO_V_VLSSEG4 = LOAD_FP | (0b10 << kRvvMopShift) | (0b011 << kRvvNfShift),
676 RO_V_VLSSEG5 = LOAD_FP | (0b10 << kRvvMopShift) | (0b100 << kRvvNfShift),
677 RO_V_VLSSEG6 = LOAD_FP | (0b10 << kRvvMopShift) | (0b101 << kRvvNfShift),
678 RO_V_VLSSEG7 = LOAD_FP | (0b10 << kRvvMopShift) | (0b110 << kRvvNfShift),
679 RO_V_VLSSEG8 = LOAD_FP | (0b10 << kRvvMopShift) | (0b111 << kRvvNfShift),
680
681 RO_V_VSSSEG2 = STORE_FP | (0b10 << kRvvMopShift) | (0b001 << kRvvNfShift),
682 RO_V_VSSSEG3 = STORE_FP | (0b10 << kRvvMopShift) | (0b010 << kRvvNfShift),
683 RO_V_VSSSEG4 = STORE_FP | (0b10 << kRvvMopShift) | (0b011 << kRvvNfShift),
684 RO_V_VSSSEG5 = STORE_FP | (0b10 << kRvvMopShift) | (0b100 << kRvvNfShift),
685 RO_V_VSSSEG6 = STORE_FP | (0b10 << kRvvMopShift) | (0b101 << kRvvNfShift),
686 RO_V_VSSSEG7 = STORE_FP | (0b10 << kRvvMopShift) | (0b110 << kRvvNfShift),
687 RO_V_VSSSEG8 = STORE_FP | (0b10 << kRvvMopShift) | (0b111 << kRvvNfShift),
688
689 RO_V_VLXSEG2 = LOAD_FP | (0b11 << kRvvMopShift) | (0b001 << kRvvNfShift),
690 RO_V_VLXSEG3 = LOAD_FP | (0b11 << kRvvMopShift) | (0b010 << kRvvNfShift),
691 RO_V_VLXSEG4 = LOAD_FP | (0b11 << kRvvMopShift) | (0b011 << kRvvNfShift),
692 RO_V_VLXSEG5 = LOAD_FP | (0b11 << kRvvMopShift) | (0b100 << kRvvNfShift),
693 RO_V_VLXSEG6 = LOAD_FP | (0b11 << kRvvMopShift) | (0b101 << kRvvNfShift),
694 RO_V_VLXSEG7 = LOAD_FP | (0b11 << kRvvMopShift) | (0b110 << kRvvNfShift),
695 RO_V_VLXSEG8 = LOAD_FP | (0b11 << kRvvMopShift) | (0b111 << kRvvNfShift),
696
697 RO_V_VSXSEG2 = STORE_FP | (0b11 << kRvvMopShift) | (0b001 << kRvvNfShift),
698 RO_V_VSXSEG3 = STORE_FP | (0b11 << kRvvMopShift) | (0b010 << kRvvNfShift),
699 RO_V_VSXSEG4 = STORE_FP | (0b11 << kRvvMopShift) | (0b011 << kRvvNfShift),
700 RO_V_VSXSEG5 = STORE_FP | (0b11 << kRvvMopShift) | (0b100 << kRvvNfShift),
701 RO_V_VSXSEG6 = STORE_FP | (0b11 << kRvvMopShift) | (0b101 << kRvvNfShift),
702 RO_V_VSXSEG7 = STORE_FP | (0b11 << kRvvMopShift) | (0b110 << kRvvNfShift),
703 RO_V_VSXSEG8 = STORE_FP | (0b11 << kRvvMopShift) | (0b111 << kRvvNfShift),
704
705 // RVV Vector Arithmetic Instruction
706 VADD_FUNCT6 = 0b000000,
707 RO_V_VADD_VI = OP_IVI | (VADD_FUNCT6 << kRvvFunct6Shift),
708 RO_V_VADD_VV = OP_IVV | (VADD_FUNCT6 << kRvvFunct6Shift),
709 RO_V_VADD_VX = OP_IVX | (VADD_FUNCT6 << kRvvFunct6Shift),
710
711 VSUB_FUNCT6 = 0b000010,
712 RO_V_VSUB_VX = OP_IVX | (VSUB_FUNCT6 << kRvvFunct6Shift),
713 RO_V_VSUB_VV = OP_IVV | (VSUB_FUNCT6 << kRvvFunct6Shift),
714
715 VSADDU_FUNCT6 = 0b100000,
716 RO_V_VSADDU_VI = OP_IVI | (VSADDU_FUNCT6 << kRvvFunct6Shift),
717 RO_V_VSADDU_VV = OP_IVV | (VSADDU_FUNCT6 << kRvvFunct6Shift),
718 RO_V_VSADDU_VX = OP_IVX | (VSADDU_FUNCT6 << kRvvFunct6Shift),
719
720 VSADD_FUNCT6 = 0b100001,
721 RO_V_VSADD_VI = OP_IVI | (VSADD_FUNCT6 << kRvvFunct6Shift),
722 RO_V_VSADD_VV = OP_IVV | (VSADD_FUNCT6 << kRvvFunct6Shift),
723 RO_V_VSADD_VX = OP_IVX | (VSADD_FUNCT6 << kRvvFunct6Shift),
724
725 VSSUB_FUNCT6 = 0b100011,
726 RO_V_VSSUB_VV = OP_IVV | (VSSUB_FUNCT6 << kRvvFunct6Shift),
727 RO_V_VSSUB_VX = OP_IVX | (VSSUB_FUNCT6 << kRvvFunct6Shift),
728
729 VSSUBU_FUNCT6 = 0b100010,
730 RO_V_VSSUBU_VV = OP_IVV | (VSSUBU_FUNCT6 << kRvvFunct6Shift),
731 RO_V_VSSUBU_VX = OP_IVX | (VSSUBU_FUNCT6 << kRvvFunct6Shift),
732
733 VRSUB_FUNCT6 = 0b000011,
734 RO_V_VRSUB_VX = OP_IVX | (VRSUB_FUNCT6 << kRvvFunct6Shift),
735 RO_V_VRSUB_VI = OP_IVI | (VRSUB_FUNCT6 << kRvvFunct6Shift),
736
737 VMINU_FUNCT6 = 0b000100,
738 RO_V_VMINU_VX = OP_IVX | (VMINU_FUNCT6 << kRvvFunct6Shift),
739 RO_V_VMINU_VV = OP_IVV | (VMINU_FUNCT6 << kRvvFunct6Shift),
740
741 VMIN_FUNCT6 = 0b000101,
742 RO_V_VMIN_VX = OP_IVX | (VMIN_FUNCT6 << kRvvFunct6Shift),
743 RO_V_VMIN_VV = OP_IVV | (VMIN_FUNCT6 << kRvvFunct6Shift),
744
745 VMAXU_FUNCT6 = 0b000110,
746 RO_V_VMAXU_VX = OP_IVX | (VMAXU_FUNCT6 << kRvvFunct6Shift),
747 RO_V_VMAXU_VV = OP_IVV | (VMAXU_FUNCT6 << kRvvFunct6Shift),
748
749 VMAX_FUNCT6 = 0b000111,
750 RO_V_VMAX_VX = OP_IVX | (VMAX_FUNCT6 << kRvvFunct6Shift),
751 RO_V_VMAX_VV = OP_IVV | (VMAX_FUNCT6 << kRvvFunct6Shift),
752
753 VAND_FUNCT6 = 0b001001,
754 RO_V_VAND_VI = OP_IVI | (VAND_FUNCT6 << kRvvFunct6Shift),
755 RO_V_VAND_VV = OP_IVV | (VAND_FUNCT6 << kRvvFunct6Shift),
756 RO_V_VAND_VX = OP_IVX | (VAND_FUNCT6 << kRvvFunct6Shift),
757
758 VOR_FUNCT6 = 0b001010,
759 RO_V_VOR_VI = OP_IVI | (VOR_FUNCT6 << kRvvFunct6Shift),
760 RO_V_VOR_VV = OP_IVV | (VOR_FUNCT6 << kRvvFunct6Shift),
761 RO_V_VOR_VX = OP_IVX | (VOR_FUNCT6 << kRvvFunct6Shift),
762
763 VXOR_FUNCT6 = 0b001011,
764 RO_V_VXOR_VI = OP_IVI | (VXOR_FUNCT6 << kRvvFunct6Shift),
765 RO_V_VXOR_VV = OP_IVV | (VXOR_FUNCT6 << kRvvFunct6Shift),
766 RO_V_VXOR_VX = OP_IVX | (VXOR_FUNCT6 << kRvvFunct6Shift),
767
768 VRGATHER_FUNCT6 = 0b001100,
769 RO_V_VRGATHER_VI = OP_IVI | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
770 RO_V_VRGATHER_VV = OP_IVV | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
771 RO_V_VRGATHER_VX = OP_IVX | (VRGATHER_FUNCT6 << kRvvFunct6Shift),
772
773 VMV_FUNCT6 = 0b010111,
774 RO_V_VMV_VI = OP_IVI | (VMV_FUNCT6 << kRvvFunct6Shift),
775 RO_V_VMV_VV = OP_IVV | (VMV_FUNCT6 << kRvvFunct6Shift),
776 RO_V_VMV_VX = OP_IVX | (VMV_FUNCT6 << kRvvFunct6Shift),
777
778 RO_V_VMERGE_VI = RO_V_VMV_VI,
779 RO_V_VMERGE_VV = RO_V_VMV_VV,
780 RO_V_VMERGE_VX = RO_V_VMV_VX,
781
782 VMSEQ_FUNCT6 = 0b011000,
783 RO_V_VMSEQ_VI = OP_IVI | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
784 RO_V_VMSEQ_VV = OP_IVV | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
785 RO_V_VMSEQ_VX = OP_IVX | (VMSEQ_FUNCT6 << kRvvFunct6Shift),
786
787 VMSNE_FUNCT6 = 0b011001,
788 RO_V_VMSNE_VI = OP_IVI | (VMSNE_FUNCT6 << kRvvFunct6Shift),
789 RO_V_VMSNE_VV = OP_IVV | (VMSNE_FUNCT6 << kRvvFunct6Shift),
790 RO_V_VMSNE_VX = OP_IVX | (VMSNE_FUNCT6 << kRvvFunct6Shift),
791
792 VMSLTU_FUNCT6 = 0b011010,
793 RO_V_VMSLTU_VV = OP_IVV | (VMSLTU_FUNCT6 << kRvvFunct6Shift),
794 RO_V_VMSLTU_VX = OP_IVX | (VMSLTU_FUNCT6 << kRvvFunct6Shift),
795
796 VMSLT_FUNCT6 = 0b011011,
797 RO_V_VMSLT_VV = OP_IVV | (VMSLT_FUNCT6 << kRvvFunct6Shift),
798 RO_V_VMSLT_VX = OP_IVX | (VMSLT_FUNCT6 << kRvvFunct6Shift),
799
800 VMSLE_FUNCT6 = 0b011101,
801 RO_V_VMSLE_VI = OP_IVI | (VMSLE_FUNCT6 << kRvvFunct6Shift),
802 RO_V_VMSLE_VV = OP_IVV | (VMSLE_FUNCT6 << kRvvFunct6Shift),
803 RO_V_VMSLE_VX = OP_IVX | (VMSLE_FUNCT6 << kRvvFunct6Shift),
804
805 VMSLEU_FUNCT6 = 0b011100,
806 RO_V_VMSLEU_VI = OP_IVI | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
807 RO_V_VMSLEU_VV = OP_IVV | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
808 RO_V_VMSLEU_VX = OP_IVX | (VMSLEU_FUNCT6 << kRvvFunct6Shift),
809
810 VMSGTU_FUNCT6 = 0b011110,
811 RO_V_VMSGTU_VI = OP_IVI | (VMSGTU_FUNCT6 << kRvvFunct6Shift),
812 RO_V_VMSGTU_VX = OP_IVX | (VMSGTU_FUNCT6 << kRvvFunct6Shift),
813
814 VMSGT_FUNCT6 = 0b011111,
815 RO_V_VMSGT_VI = OP_IVI | (VMSGT_FUNCT6 << kRvvFunct6Shift),
816 RO_V_VMSGT_VX = OP_IVX | (VMSGT_FUNCT6 << kRvvFunct6Shift),
817
818 VSLIDEUP_FUNCT6 = 0b001110,
819 RO_V_VSLIDEUP_VI = OP_IVI | (VSLIDEUP_FUNCT6 << kRvvFunct6Shift),
820 RO_V_VSLIDEUP_VX = OP_IVX | (VSLIDEUP_FUNCT6 << kRvvFunct6Shift),
821
822 VSLIDEDOWN_FUNCT6 = 0b001111,
823 RO_V_VSLIDEDOWN_VI = OP_IVI | (VSLIDEDOWN_FUNCT6 << kRvvFunct6Shift),
824 RO_V_VSLIDEDOWN_VX = OP_IVX | (VSLIDEDOWN_FUNCT6 << kRvvFunct6Shift),
825
826 VSRL_FUNCT6 = 0b101000,
827 RO_V_VSRL_VI = OP_IVI | (VSRL_FUNCT6 << kRvvFunct6Shift),
828 RO_V_VSRL_VV = OP_IVV | (VSRL_FUNCT6 << kRvvFunct6Shift),
829 RO_V_VSRL_VX = OP_IVX | (VSRL_FUNCT6 << kRvvFunct6Shift),
830
831 VSLL_FUNCT6 = 0b100101,
832 RO_V_VSLL_VI = OP_IVI | (VSLL_FUNCT6 << kRvvFunct6Shift),
833 RO_V_VSLL_VV = OP_IVV | (VSLL_FUNCT6 << kRvvFunct6Shift),
834 RO_V_VSLL_VX = OP_IVX | (VSLL_FUNCT6 << kRvvFunct6Shift),
835
836 VADC_FUNCT6 = 0b010000,
837 RO_V_VADC_VI = OP_IVI | (VADC_FUNCT6 << kRvvFunct6Shift),
838 RO_V_VADC_VV = OP_IVV | (VADC_FUNCT6 << kRvvFunct6Shift),
839 RO_V_VADC_VX = OP_IVX | (VADC_FUNCT6 << kRvvFunct6Shift),
840
841 VMADC_FUNCT6 = 0b010001,
842 RO_V_VMADC_VI = OP_IVI | (VMADC_FUNCT6 << kRvvFunct6Shift),
843 RO_V_VMADC_VV = OP_IVV | (VMADC_FUNCT6 << kRvvFunct6Shift),
844 RO_V_VMADC_VX = OP_IVX | (VMADC_FUNCT6 << kRvvFunct6Shift),
845
846 VWXUNARY0_FUNCT6 = 0b010000,
847 VRXUNARY0_FUNCT6 = 0b010000,
848
849 RO_V_VWXUNARY0 = OP_MVV | (VWXUNARY0_FUNCT6 << kRvvFunct6Shift),
850 RO_V_VRXUNARY0 = OP_MVX | (VRXUNARY0_FUNCT6 << kRvvFunct6Shift),
851
852 VREDMAXU_FUNCT6 = 0b000110,
853 RO_V_VREDMAXU = OP_MVV | (VREDMAXU_FUNCT6 << kRvvFunct6Shift),
854 VREDMAX_FUNCT6 = 0b000111,
855 RO_V_VREDMAX = OP_MVV | (VREDMAX_FUNCT6 << kRvvFunct6Shift),
856
857 VREDMINU_FUNCT6 = 0b000100,
858 RO_V_VREDMINU = OP_MVV | (VREDMINU_FUNCT6 << kRvvFunct6Shift),
859 VREDMIN_FUNCT6 = 0b000101,
860 RO_V_VREDMIN = OP_MVV | (VREDMIN_FUNCT6 << kRvvFunct6Shift),
861
862 VFUNARY0_FUNCT6 = 0b010010,
863 RO_V_VFUNARY0 = OP_FVV | (VFUNARY0_FUNCT6 << kRvvFunct6Shift),
864 VFUNARY1_FUNCT6 = 0b010011,
865 RO_V_VFUNARY1 = OP_FVV | (VFUNARY1_FUNCT6 << kRvvFunct6Shift),
866
867 VFCVT_XU_F_V = 0b00000,
868 VFCVT_X_F_V = 0b00001,
869 VFCVT_F_XU_V = 0b00010,
870 VFCVT_F_X_V = 0b00011,
871 VFNCVT_F_F_W = 0b10100,
872
873 VFCLASS_V = 0b10000,
874
875 VFADD_FUNCT6 = 0b000000,
876 RO_V_VFADD_VV = OP_FVV | (VFADD_FUNCT6 << kRvvFunct6Shift),
877 RO_V_VFADD_VF = OP_FVF | (VFADD_FUNCT6 << kRvvFunct6Shift),
878
879 VFSUB_FUNCT6 = 0b000010,
880 RO_V_VFSUB_VV = OP_FVV | (VFSUB_FUNCT6 << kRvvFunct6Shift),
881 RO_V_VFSUB_VF = OP_FVF | (VFSUB_FUNCT6 << kRvvFunct6Shift),
882
883 VFDIV_FUNCT6 = 0b100000,
884 RO_V_VFDIV_VV = OP_FVV | (VFDIV_FUNCT6 << kRvvFunct6Shift),
885 RO_V_VFDIV_VF = OP_FVF | (VFDIV_FUNCT6 << kRvvFunct6Shift),
886
887 VFMUL_FUNCT6 = 0b100100,
888 RO_V_VFMUL_VV = OP_FVV | (VFMUL_FUNCT6 << kRvvFunct6Shift),
889 RO_V_VFMUL_VF = OP_FVF | (VFMUL_FUNCT6 << kRvvFunct6Shift),
890
891 VMFEQ_FUNCT6 = 0b011000,
892 RO_V_VMFEQ_VV = OP_FVV | (VMFEQ_FUNCT6 << kRvvFunct6Shift),
893 RO_V_VMFEQ_VF = OP_FVF | (VMFEQ_FUNCT6 << kRvvFunct6Shift),
894
895 VMFNE_FUNCT6 = 0b011100,
896 RO_V_VMFNE_VV = OP_FVV | (VMFNE_FUNCT6 << kRvvFunct6Shift),
897 RO_V_VMFNE_VF = OP_FVF | (VMFNE_FUNCT6 << kRvvFunct6Shift),
898
899 VMFLT_FUNCT6 = 0b011011,
900 RO_V_VMFLT_VV = OP_FVV | (VMFLT_FUNCT6 << kRvvFunct6Shift),
901 RO_V_VMFLT_VF = OP_FVF | (VMFLT_FUNCT6 << kRvvFunct6Shift),
902
903 VMFLE_FUNCT6 = 0b011001,
904 RO_V_VMFLE_VV = OP_FVV | (VMFLE_FUNCT6 << kRvvFunct6Shift),
905 RO_V_VMFLE_VF = OP_FVF | (VMFLE_FUNCT6 << kRvvFunct6Shift),
906
907 VMFGE_FUNCT6 = 0b011111,
908 RO_V_VMFGE_VF = OP_FVF | (VMFGE_FUNCT6 << kRvvFunct6Shift),
909
910 VMFGT_FUNCT6 = 0b011101,
911 RO_V_VMFGT_VF = OP_FVF | (VMFGT_FUNCT6 << kRvvFunct6Shift),
912
913 VFMAX_FUNCT6 = 0b000110,
914 RO_V_VFMAX_VV = OP_FVV | (VFMAX_FUNCT6 << kRvvFunct6Shift),
915 RO_V_VFMAX_VF = OP_FVF | (VFMAX_FUNCT6 << kRvvFunct6Shift),
916
917 VFMIN_FUNCT6 = 0b000100,
918 RO_V_VFMIN_VV = OP_FVV | (VFMIN_FUNCT6 << kRvvFunct6Shift),
919 RO_V_VFMIN_VF = OP_FVF | (VFMIN_FUNCT6 << kRvvFunct6Shift),
920
921 VFSGNJ_FUNCT6 = 0b001000,
922 RO_V_VFSGNJ_VV = OP_FVV | (VFSGNJ_FUNCT6 << kRvvFunct6Shift),
923 RO_V_VFSGNJ_VF = OP_FVF | (VFSGNJ_FUNCT6 << kRvvFunct6Shift),
924
925 VFSGNJN_FUNCT6 = 0b001001,
926 RO_V_VFSGNJN_VV = OP_FVV | (VFSGNJN_FUNCT6 << kRvvFunct6Shift),
927 RO_V_VFSGNJN_VF = OP_FVF | (VFSGNJN_FUNCT6 << kRvvFunct6Shift),
928
929 VFSGNJX_FUNCT6 = 0b001010,
930 RO_V_VFSGNJX_VV = OP_FVV | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
931 RO_V_VFSGNJX_VF = OP_FVF | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
932 };
933
934 // ----- Emulated conditions.
935 // On RISC-V we use this enum to abstract from conditional branch instructions.
936 // The 'U' prefix is used to specify unsigned comparisons.
937 // Opposite conditions must be paired as odd/even numbers
938 // because 'NegateCondition' function flips LSB to negate condition.
939 enum Condition { // Any value < 0 is considered no_condition.
940 kNoCondition = -1,
941 overflow = 0,
942 no_overflow = 1,
943 Uless = 2,
944 Ugreater_equal = 3,
945 Uless_equal = 4,
946 Ugreater = 5,
947 equal = 6,
948 not_equal = 7, // Unordered or Not Equal.
949 less = 8,
950 greater_equal = 9,
951 less_equal = 10,
952 greater = 11,
953 cc_always = 12,
954
955 // Aliases.
956 eq = equal,
957 ne = not_equal,
958 ge = greater_equal,
959 lt = less,
960 gt = greater,
961 le = less_equal,
962 al = cc_always,
963 ult = Uless,
964 uge = Ugreater_equal,
965 ule = Uless_equal,
966 ugt = Ugreater,
967 };
968
969 // Returns the equivalent of !cc.
970 // Negation of the default kNoCondition (-1) results in a non-default
971 // no_condition value (-2). As long as tests for no_condition check
972 // for condition < 0, this will work as expected.
NegateCondition(Condition cc)973 inline Condition NegateCondition(Condition cc) {
974 DCHECK(cc != cc_always);
975 return static_cast<Condition>(cc ^ 1);
976 }
977
NegateFpuCondition(Condition cc)978 inline Condition NegateFpuCondition(Condition cc) {
979 DCHECK(cc != cc_always);
980 switch (cc) {
981 case ult:
982 return ge;
983 case ugt:
984 return le;
985 case uge:
986 return lt;
987 case ule:
988 return gt;
989 case lt:
990 return uge;
991 case gt:
992 return ule;
993 case ge:
994 return ult;
995 case le:
996 return ugt;
997 case eq:
998 return ne;
999 case ne:
1000 return eq;
1001 default:
1002 return cc;
1003 }
1004 }
1005
1006 // ----- Coprocessor conditions.
1007 enum FPUCondition {
1008 kNoFPUCondition = -1,
1009 EQ = 0x02, // Ordered and Equal
1010 NE = 0x03, // Unordered or Not Equal
1011 LT = 0x04, // Ordered and Less Than
1012 GE = 0x05, // Ordered and Greater Than or Equal
1013 LE = 0x06, // Ordered and Less Than or Equal
1014 GT = 0x07, // Ordered and Greater Than
1015 };
1016
1017 enum CheckForInexactConversion {
1018 kCheckForInexactConversion,
1019 kDontCheckForInexactConversion
1020 };
1021
1022 enum class MaxMinKind : int { kMin = 0, kMax = 1 };
1023
1024 // ----------------------------------------------------------------------------
1025 // RISCV flags
1026
1027 enum ControlStatusReg {
1028 csr_fflags = 0x001, // Floating-Point Accrued Exceptions (RW)
1029 csr_frm = 0x002, // Floating-Point Dynamic Rounding Mode (RW)
1030 csr_fcsr = 0x003, // Floating-Point Control and Status Register (RW)
1031 csr_cycle = 0xc00, // Cycle counter for RDCYCLE instruction (RO)
1032 csr_time = 0xc01, // Timer for RDTIME instruction (RO)
1033 csr_instret = 0xc02, // Insns-retired counter for RDINSTRET instruction (RO)
1034 csr_cycleh = 0xc80, // Upper 32 bits of cycle, RV32I only (RO)
1035 csr_timeh = 0xc81, // Upper 32 bits of time, RV32I only (RO)
1036 csr_instreth = 0xc82 // Upper 32 bits of instret, RV32I only (RO)
1037 };
1038
1039 enum FFlagsMask {
1040 kInvalidOperation = 0b10000, // NV: Invalid
1041 kDivideByZero = 0b1000, // DZ: Divide by Zero
1042 kOverflow = 0b100, // OF: Overflow
1043 kUnderflow = 0b10, // UF: Underflow
1044 kInexact = 0b1 // NX: Inexact
1045 };
1046
1047 enum RoundingMode {
1048 RNE = 0b000, // Round to Nearest, ties to Even
1049 RTZ = 0b001, // Round towards Zero
1050 RDN = 0b010, // Round Down (towards -infinity)
1051 RUP = 0b011, // Round Up (towards +infinity)
1052 RMM = 0b100, // Round to Nearest, tiest to Max Magnitude
1053 DYN = 0b111 // In instruction's rm field, selects dynamic rounding mode;
1054 // In Rounding Mode register, Invalid
1055 };
1056
1057 enum MemoryOdering {
1058 PSI = 0b1000, // PI or SI
1059 PSO = 0b0100, // PO or SO
1060 PSR = 0b0010, // PR or SR
1061 PSW = 0b0001, // PW or SW
1062 PSIORW = PSI | PSO | PSR | PSW
1063 };
1064
1065 const int kFloat32ExponentBias = 127;
1066 const int kFloat32MantissaBits = 23;
1067 const int kFloat32ExponentBits = 8;
1068 const int kFloat64ExponentBias = 1023;
1069 const int kFloat64MantissaBits = 52;
1070 const int kFloat64ExponentBits = 11;
1071
1072 enum FClassFlag {
1073 kNegativeInfinity = 1,
1074 kNegativeNormalNumber = 1 << 1,
1075 kNegativeSubnormalNumber = 1 << 2,
1076 kNegativeZero = 1 << 3,
1077 kPositiveZero = 1 << 4,
1078 kPositiveSubnormalNumber = 1 << 5,
1079 kPositiveNormalNumber = 1 << 6,
1080 kPositiveInfinity = 1 << 7,
1081 kSignalingNaN = 1 << 8,
1082 kQuietNaN = 1 << 9
1083 };
1084
1085 #define RVV_SEW(V) \
1086 V(E8) \
1087 V(E16) \
1088 V(E32) \
1089 V(E64) \
1090 V(E128) \
1091 V(E256) \
1092 V(E512) \
1093 V(E1024)
1094
1095 enum VSew {
1096 #define DEFINE_FLAG(name) name,
1097 RVV_SEW(DEFINE_FLAG)
1098 #undef DEFINE_FLAG
1099 };
1100
1101 #define RVV_LMUL(V) \
1102 V(m1) \
1103 V(m2) \
1104 V(m4) \
1105 V(m8) \
1106 V(RESERVERD) \
1107 V(mf8) \
1108 V(mf4) \
1109 V(mf2)
1110
1111 enum Vlmul {
1112 #define DEFINE_FLAG(name) name,
1113 RVV_LMUL(DEFINE_FLAG)
1114 #undef DEFINE_FLAG
1115 };
1116
1117 enum TailAgnosticType {
1118 ta = 0x1, // Tail agnostic
1119 tu = 0x0, // Tail undisturbed
1120 };
1121
1122 enum MaskAgnosticType {
1123 ma = 0x1, // Mask agnostic
1124 mu = 0x0, // Mask undisturbed
1125 };
1126 enum MaskType {
1127 Mask = 0x0, // use the mask
1128 NoMask = 0x1,
1129 };
1130
1131 // -----------------------------------------------------------------------------
1132 // Hints.
1133
1134 // Branch hints are not used on RISC-V. They are defined so that they can
1135 // appear in shared function signatures, but will be ignored in RISC-V
1136 // implementations.
1137 enum Hint { no_hint = 0 };
1138
NegateHint(Hint hint)1139 inline Hint NegateHint(Hint hint) { return no_hint; }
1140
1141 // -----------------------------------------------------------------------------
1142 // Specific instructions, constants, and masks.
1143 // These constants are declared in assembler-riscv64.cc, as they use named
1144 // registers and other constants.
1145
1146 // An Illegal instruction
1147 const Instr kIllegalInstr = 0; // All other bits are 0s (i.e., ecall)
1148 // An ECALL instruction, used for redirected real time call
1149 const Instr rtCallRedirInstr = SYSTEM; // All other bits are 0s (i.e., ecall)
1150 // An EBreak instruction, used for debugging and semi-hosting
1151 const Instr kBreakInstr = SYSTEM | 1 << kImm12Shift; // ebreak
1152
1153 constexpr uint8_t kInstrSize = 4;
1154 constexpr uint8_t kShortInstrSize = 2;
1155 constexpr uint8_t kInstrSizeLog2 = 2;
1156
1157 class InstructionBase {
1158 public:
1159 enum {
1160 // On RISC-V, PC cannot actually be directly accessed. We behave as if PC
1161 // was always the value of the current instruction being executed.
1162 kPCReadOffset = 0
1163 };
1164
1165 // Instruction type.
1166 enum Type {
1167 kRType,
1168 kR4Type, // Special R4 for Q extension
1169 kIType,
1170 kSType,
1171 kBType,
1172 kUType,
1173 kJType,
1174 // C extension
1175 kCRType,
1176 kCIType,
1177 kCSSType,
1178 kCIWType,
1179 kCLType,
1180 kCSType,
1181 kCAType,
1182 kCBType,
1183 kCJType,
1184 // V extension
1185 kVType,
1186 kVLType,
1187 kVSType,
1188 kVAMOType,
1189 kVIVVType,
1190 kVFVVType,
1191 kVMVVType,
1192 kVIVIType,
1193 kVIVXType,
1194 kVFVFType,
1195 kVMVXType,
1196 kVSETType,
1197 kUnsupported = -1
1198 };
1199
IsIllegalInstruction()1200 inline bool IsIllegalInstruction() const {
1201 uint16_t FirstHalfWord = *reinterpret_cast<const uint16_t*>(this);
1202 return FirstHalfWord == 0;
1203 }
1204
IsShortInstruction()1205 inline bool IsShortInstruction() const {
1206 uint8_t FirstByte = *reinterpret_cast<const uint8_t*>(this);
1207 return (FirstByte & 0x03) <= C2;
1208 }
1209
InstructionSize()1210 inline uint8_t InstructionSize() const {
1211 return (FLAG_riscv_c_extension && this->IsShortInstruction())
1212 ? kShortInstrSize
1213 : kInstrSize;
1214 }
1215
1216 // Get the raw instruction bits.
InstructionBits()1217 inline Instr InstructionBits() const {
1218 if (FLAG_riscv_c_extension && this->IsShortInstruction()) {
1219 return 0x0000FFFF & (*reinterpret_cast<const ShortInstr*>(this));
1220 }
1221 return *reinterpret_cast<const Instr*>(this);
1222 }
1223
1224 // Set the raw instruction bits to value.
SetInstructionBits(Instr value)1225 inline void SetInstructionBits(Instr value) {
1226 *reinterpret_cast<Instr*>(this) = value;
1227 }
1228
1229 // Read one particular bit out of the instruction bits.
Bit(int nr)1230 inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
1231
1232 // Read a bit field out of the instruction bits.
Bits(int hi,int lo)1233 inline int Bits(int hi, int lo) const {
1234 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
1235 }
1236
1237 // Accessors for the different named fields used in the RISC-V encoding.
BaseOpcodeValue()1238 inline Opcode BaseOpcodeValue() const {
1239 return static_cast<Opcode>(
1240 Bits(kBaseOpcodeShift + kBaseOpcodeBits - 1, kBaseOpcodeShift));
1241 }
1242
1243 // Return the fields at their original place in the instruction encoding.
BaseOpcodeFieldRaw()1244 inline Opcode BaseOpcodeFieldRaw() const {
1245 return static_cast<Opcode>(InstructionBits() & kBaseOpcodeMask);
1246 }
1247
1248 // Safe to call within R-type instructions
Funct7FieldRaw()1249 inline int Funct7FieldRaw() const { return InstructionBits() & kFunct7Mask; }
1250
1251 // Safe to call within R-, I-, S-, or B-type instructions
Funct3FieldRaw()1252 inline int Funct3FieldRaw() const { return InstructionBits() & kFunct3Mask; }
1253
1254 // Safe to call within R-, I-, S-, or B-type instructions
Rs1FieldRawNoAssert()1255 inline int Rs1FieldRawNoAssert() const {
1256 return InstructionBits() & kRs1FieldMask;
1257 }
1258
1259 // Safe to call within R-, S-, or B-type instructions
Rs2FieldRawNoAssert()1260 inline int Rs2FieldRawNoAssert() const {
1261 return InstructionBits() & kRs2FieldMask;
1262 }
1263
1264 // Safe to call within R4-type instructions
Rs3FieldRawNoAssert()1265 inline int Rs3FieldRawNoAssert() const {
1266 return InstructionBits() & kRs3FieldMask;
1267 }
1268
ITypeBits()1269 inline int32_t ITypeBits() const { return InstructionBits() & kITypeMask; }
1270
InstructionOpcodeType()1271 inline int32_t InstructionOpcodeType() const {
1272 if (IsShortInstruction()) {
1273 return InstructionBits() & kRvcOpcodeMask;
1274 } else {
1275 return InstructionBits() & kBaseOpcodeMask;
1276 }
1277 }
1278
1279 // Get the encoding type of the instruction.
1280 Type InstructionType() const;
1281
1282 protected:
InstructionBase()1283 InstructionBase() {}
1284 };
1285
1286 template <class T>
1287 class InstructionGetters : public T {
1288 public:
BaseOpcode()1289 inline int BaseOpcode() const {
1290 return this->InstructionBits() & kBaseOpcodeMask;
1291 }
1292
RvcOpcode()1293 inline int RvcOpcode() const {
1294 DCHECK(this->IsShortInstruction());
1295 return this->InstructionBits() & kRvcOpcodeMask;
1296 }
1297
Rs1Value()1298 inline int Rs1Value() const {
1299 DCHECK(this->InstructionType() == InstructionBase::kRType ||
1300 this->InstructionType() == InstructionBase::kR4Type ||
1301 this->InstructionType() == InstructionBase::kIType ||
1302 this->InstructionType() == InstructionBase::kSType ||
1303 this->InstructionType() == InstructionBase::kBType ||
1304 this->InstructionType() == InstructionBase::kIType ||
1305 this->InstructionType() == InstructionBase::kVType);
1306 return this->Bits(kRs1Shift + kRs1Bits - 1, kRs1Shift);
1307 }
1308
Rs2Value()1309 inline int Rs2Value() const {
1310 DCHECK(this->InstructionType() == InstructionBase::kRType ||
1311 this->InstructionType() == InstructionBase::kR4Type ||
1312 this->InstructionType() == InstructionBase::kSType ||
1313 this->InstructionType() == InstructionBase::kBType ||
1314 this->InstructionType() == InstructionBase::kIType ||
1315 this->InstructionType() == InstructionBase::kVType);
1316 return this->Bits(kRs2Shift + kRs2Bits - 1, kRs2Shift);
1317 }
1318
Rs3Value()1319 inline int Rs3Value() const {
1320 DCHECK(this->InstructionType() == InstructionBase::kR4Type);
1321 return this->Bits(kRs3Shift + kRs3Bits - 1, kRs3Shift);
1322 }
1323
Vs1Value()1324 inline int Vs1Value() const {
1325 DCHECK(this->InstructionType() == InstructionBase::kVType ||
1326 this->InstructionType() == InstructionBase::kIType ||
1327 this->InstructionType() == InstructionBase::kSType);
1328 return this->Bits(kVs1Shift + kVs1Bits - 1, kVs1Shift);
1329 }
1330
Vs2Value()1331 inline int Vs2Value() const {
1332 DCHECK(this->InstructionType() == InstructionBase::kVType ||
1333 this->InstructionType() == InstructionBase::kIType ||
1334 this->InstructionType() == InstructionBase::kSType);
1335 return this->Bits(kVs2Shift + kVs2Bits - 1, kVs2Shift);
1336 }
1337
VdValue()1338 inline int VdValue() const {
1339 DCHECK(this->InstructionType() == InstructionBase::kVType ||
1340 this->InstructionType() == InstructionBase::kIType ||
1341 this->InstructionType() == InstructionBase::kSType);
1342 return this->Bits(kVdShift + kVdBits - 1, kVdShift);
1343 }
1344
RdValue()1345 inline int RdValue() const {
1346 DCHECK(this->InstructionType() == InstructionBase::kRType ||
1347 this->InstructionType() == InstructionBase::kR4Type ||
1348 this->InstructionType() == InstructionBase::kIType ||
1349 this->InstructionType() == InstructionBase::kSType ||
1350 this->InstructionType() == InstructionBase::kUType ||
1351 this->InstructionType() == InstructionBase::kJType ||
1352 this->InstructionType() == InstructionBase::kVType);
1353 return this->Bits(kRdShift + kRdBits - 1, kRdShift);
1354 }
1355
RvcRdValue()1356 inline int RvcRdValue() const {
1357 DCHECK(this->IsShortInstruction());
1358 return this->Bits(kRvcRdShift + kRvcRdBits - 1, kRvcRdShift);
1359 }
1360
RvcRs1Value()1361 inline int RvcRs1Value() const { return this->RvcRdValue(); }
1362
RvcRs2Value()1363 inline int RvcRs2Value() const {
1364 DCHECK(this->IsShortInstruction());
1365 return this->Bits(kRvcRs2Shift + kRvcRs2Bits - 1, kRvcRs2Shift);
1366 }
1367
RvcRs1sValue()1368 inline int RvcRs1sValue() const {
1369 DCHECK(this->IsShortInstruction());
1370 return 0b1000 + this->Bits(kRvcRs1sShift + kRvcRs1sBits - 1, kRvcRs1sShift);
1371 }
1372
RvcRs2sValue()1373 inline int RvcRs2sValue() const {
1374 DCHECK(this->IsShortInstruction());
1375 return 0b1000 + this->Bits(kRvcRs2sShift + kRvcRs2sBits - 1, kRvcRs2sShift);
1376 }
1377
Funct7Value()1378 inline int Funct7Value() const {
1379 DCHECK(this->InstructionType() == InstructionBase::kRType);
1380 return this->Bits(kFunct7Shift + kFunct7Bits - 1, kFunct7Shift);
1381 }
1382
Funct3Value()1383 inline int Funct3Value() const {
1384 DCHECK(this->InstructionType() == InstructionBase::kRType ||
1385 this->InstructionType() == InstructionBase::kIType ||
1386 this->InstructionType() == InstructionBase::kSType ||
1387 this->InstructionType() == InstructionBase::kBType);
1388 return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
1389 }
1390
Funct5Value()1391 inline int Funct5Value() const {
1392 DCHECK(this->InstructionType() == InstructionBase::kRType &&
1393 this->BaseOpcode() == OP_FP);
1394 return this->Bits(kFunct5Shift + kFunct5Bits - 1, kFunct5Shift);
1395 }
1396
RvcFunct6Value()1397 inline int RvcFunct6Value() const {
1398 DCHECK(this->IsShortInstruction());
1399 return this->Bits(kRvcFunct6Shift + kRvcFunct6Bits - 1, kRvcFunct6Shift);
1400 }
1401
RvcFunct4Value()1402 inline int RvcFunct4Value() const {
1403 DCHECK(this->IsShortInstruction());
1404 return this->Bits(kRvcFunct4Shift + kRvcFunct4Bits - 1, kRvcFunct4Shift);
1405 }
1406
RvcFunct3Value()1407 inline int RvcFunct3Value() const {
1408 DCHECK(this->IsShortInstruction());
1409 return this->Bits(kRvcFunct3Shift + kRvcFunct3Bits - 1, kRvcFunct3Shift);
1410 }
1411
RvcFunct2Value()1412 inline int RvcFunct2Value() const {
1413 DCHECK(this->IsShortInstruction());
1414 return this->Bits(kRvcFunct2Shift + kRvcFunct2Bits - 1, kRvcFunct2Shift);
1415 }
1416
RvcFunct2BValue()1417 inline int RvcFunct2BValue() const {
1418 DCHECK(this->IsShortInstruction());
1419 return this->Bits(kRvcFunct2BShift + kRvcFunct2Bits - 1, kRvcFunct2BShift);
1420 }
1421
CsrValue()1422 inline int CsrValue() const {
1423 DCHECK(this->InstructionType() == InstructionBase::kIType &&
1424 this->BaseOpcode() == SYSTEM);
1425 return (this->Bits(kCsrShift + kCsrBits - 1, kCsrShift));
1426 }
1427
RoundMode()1428 inline int RoundMode() const {
1429 DCHECK((this->InstructionType() == InstructionBase::kRType ||
1430 this->InstructionType() == InstructionBase::kR4Type) &&
1431 this->BaseOpcode() == OP_FP);
1432 return this->Bits(kFunct3Shift + kFunct3Bits - 1, kFunct3Shift);
1433 }
1434
MemoryOrder(bool is_pred)1435 inline int MemoryOrder(bool is_pred) const {
1436 DCHECK((this->InstructionType() == InstructionBase::kIType &&
1437 this->BaseOpcode() == MISC_MEM));
1438 if (is_pred) {
1439 return this->Bits(kPredOrderShift + kMemOrderBits - 1, kPredOrderShift);
1440 } else {
1441 return this->Bits(kSuccOrderShift + kMemOrderBits - 1, kSuccOrderShift);
1442 }
1443 }
1444
Imm12Value()1445 inline int Imm12Value() const {
1446 DCHECK(this->InstructionType() == InstructionBase::kIType);
1447 int Value = this->Bits(kImm12Shift + kImm12Bits - 1, kImm12Shift);
1448 return Value << 20 >> 20;
1449 }
1450
Imm12SExtValue()1451 inline int32_t Imm12SExtValue() const {
1452 int32_t Value = this->Imm12Value() << 20 >> 20;
1453 return Value;
1454 }
1455
BranchOffset()1456 inline int BranchOffset() const {
1457 DCHECK(this->InstructionType() == InstructionBase::kBType);
1458 // | imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode |
1459 // 31 25 11 7
1460 uint32_t Bits = this->InstructionBits();
1461 int16_t imm13 = ((Bits & 0xf00) >> 7) | ((Bits & 0x7e000000) >> 20) |
1462 ((Bits & 0x80) << 4) | ((Bits & 0x80000000) >> 19);
1463 return imm13 << 19 >> 19;
1464 }
1465
StoreOffset()1466 inline int StoreOffset() const {
1467 DCHECK(this->InstructionType() == InstructionBase::kSType);
1468 // | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
1469 // 31 25 11 7
1470 uint32_t Bits = this->InstructionBits();
1471 int16_t imm12 = ((Bits & 0xf80) >> 7) | ((Bits & 0xfe000000) >> 20);
1472 return imm12 << 20 >> 20;
1473 }
1474
Imm20UValue()1475 inline int Imm20UValue() const {
1476 DCHECK(this->InstructionType() == InstructionBase::kUType);
1477 // | imm[31:12] | rd | opcode |
1478 // 31 12
1479 int32_t Bits = this->InstructionBits();
1480 return Bits >> 12;
1481 }
1482
Imm20JValue()1483 inline int Imm20JValue() const {
1484 DCHECK(this->InstructionType() == InstructionBase::kJType);
1485 // | imm[20|10:1|11|19:12] | rd | opcode |
1486 // 31 12
1487 uint32_t Bits = this->InstructionBits();
1488 int32_t imm20 = ((Bits & 0x7fe00000) >> 20) | ((Bits & 0x100000) >> 9) |
1489 (Bits & 0xff000) | ((Bits & 0x80000000) >> 11);
1490 return imm20 << 11 >> 11;
1491 }
1492
IsArithShift()1493 inline bool IsArithShift() const {
1494 // Valid only for right shift operations
1495 DCHECK((this->BaseOpcode() == OP || this->BaseOpcode() == OP_32 ||
1496 this->BaseOpcode() == OP_IMM || this->BaseOpcode() == OP_IMM_32) &&
1497 this->Funct3Value() == 0b101);
1498 return this->InstructionBits() & 0x40000000;
1499 }
1500
Shamt()1501 inline int Shamt() const {
1502 // Valid only for shift instructions (SLLI, SRLI, SRAI)
1503 DCHECK((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM &&
1504 (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
1505 // | 0A0000 | shamt | rs1 | funct3 | rd | opcode |
1506 // 31 25 20
1507 return this->Bits(kImm12Shift + 5, kImm12Shift);
1508 }
1509
Shamt32()1510 inline int Shamt32() const {
1511 // Valid only for shift instructions (SLLIW, SRLIW, SRAIW)
1512 DCHECK((this->InstructionBits() & kBaseOpcodeMask) == OP_IMM_32 &&
1513 (this->Funct3Value() == 0b001 || this->Funct3Value() == 0b101));
1514 // | 0A00000 | shamt | rs1 | funct3 | rd | opcode |
1515 // 31 24 20
1516 return this->Bits(kImm12Shift + 4, kImm12Shift);
1517 }
1518
RvcImm6Value()1519 inline int RvcImm6Value() const {
1520 DCHECK(this->IsShortInstruction());
1521 // | funct3 | imm[5] | rs1/rd | imm[4:0] | opcode |
1522 // 15 12 6 2
1523 uint32_t Bits = this->InstructionBits();
1524 int32_t imm6 = ((Bits & 0x1000) >> 7) | ((Bits & 0x7c) >> 2);
1525 return imm6 << 26 >> 26;
1526 }
1527
RvcImm6Addi16spValue()1528 inline int RvcImm6Addi16spValue() const {
1529 DCHECK(this->IsShortInstruction());
1530 // | funct3 | nzimm[9] | 2 | nzimm[4|6|8:7|5] | opcode |
1531 // 15 12 6 2
1532 uint32_t Bits = this->InstructionBits();
1533 int32_t imm10 = ((Bits & 0x1000) >> 3) | ((Bits & 0x40) >> 2) |
1534 ((Bits & 0x20) << 1) | ((Bits & 0x18) << 4) |
1535 ((Bits & 0x4) << 3);
1536 DCHECK_NE(imm10, 0);
1537 return imm10 << 22 >> 22;
1538 }
1539
RvcImm8Addi4spnValue()1540 inline int RvcImm8Addi4spnValue() const {
1541 DCHECK(this->IsShortInstruction());
1542 // | funct3 | nzimm[11] | rd' | opcode |
1543 // 15 13 5 2
1544 uint32_t Bits = this->InstructionBits();
1545 int32_t uimm10 = ((Bits & 0x20) >> 2) | ((Bits & 0x40) >> 4) |
1546 ((Bits & 0x780) >> 1) | ((Bits & 0x1800) >> 7);
1547 DCHECK_NE(uimm10, 0);
1548 return uimm10;
1549 }
1550
RvcShamt6()1551 inline int RvcShamt6() const {
1552 DCHECK(this->IsShortInstruction());
1553 // | funct3 | nzuimm[5] | rs1/rd | nzuimm[4:0] | opcode |
1554 // 15 12 6 2
1555 int32_t imm6 = this->RvcImm6Value();
1556 return imm6 & 0x3f;
1557 }
1558
RvcImm6LwspValue()1559 inline int RvcImm6LwspValue() const {
1560 DCHECK(this->IsShortInstruction());
1561 // | funct3 | uimm[5] | rs1 | uimm[4:2|7:6] | opcode |
1562 // 15 12 6 2
1563 uint32_t Bits = this->InstructionBits();
1564 int32_t imm8 =
1565 ((Bits & 0x1000) >> 7) | ((Bits & 0x70) >> 2) | ((Bits & 0xc) << 4);
1566 return imm8;
1567 }
1568
RvcImm6LdspValue()1569 inline int RvcImm6LdspValue() const {
1570 DCHECK(this->IsShortInstruction());
1571 // | funct3 | uimm[5] | rs1 | uimm[4:3|8:6] | opcode |
1572 // 15 12 6 2
1573 uint32_t Bits = this->InstructionBits();
1574 int32_t imm9 =
1575 ((Bits & 0x1000) >> 7) | ((Bits & 0x60) >> 2) | ((Bits & 0x1c) << 4);
1576 return imm9;
1577 }
1578
RvcImm6SwspValue()1579 inline int RvcImm6SwspValue() const {
1580 DCHECK(this->IsShortInstruction());
1581 // | funct3 | uimm[5:2|7:6] | rs2 | opcode |
1582 // 15 12 7
1583 uint32_t Bits = this->InstructionBits();
1584 int32_t imm8 = ((Bits & 0x1e00) >> 7) | ((Bits & 0x180) >> 1);
1585 return imm8;
1586 }
1587
RvcImm6SdspValue()1588 inline int RvcImm6SdspValue() const {
1589 DCHECK(this->IsShortInstruction());
1590 // | funct3 | uimm[5:3|8:6] | rs2 | opcode |
1591 // 15 12 7
1592 uint32_t Bits = this->InstructionBits();
1593 int32_t imm9 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x380) >> 1);
1594 return imm9;
1595 }
1596
RvcImm5WValue()1597 inline int RvcImm5WValue() const {
1598 DCHECK(this->IsShortInstruction());
1599 // | funct3 | imm[5:3] | rs1 | imm[2|6] | rd | opcode |
1600 // 15 12 10 6 4 2
1601 uint32_t Bits = this->InstructionBits();
1602 int32_t imm7 =
1603 ((Bits & 0x1c00) >> 7) | ((Bits & 0x40) >> 4) | ((Bits & 0x20) << 1);
1604 return imm7;
1605 }
1606
RvcImm5DValue()1607 inline int RvcImm5DValue() const {
1608 DCHECK(this->IsShortInstruction());
1609 // | funct3 | imm[5:3] | rs1 | imm[7:6] | rd | opcode |
1610 // 15 12 10 6 4 2
1611 uint32_t Bits = this->InstructionBits();
1612 int32_t imm8 = ((Bits & 0x1c00) >> 7) | ((Bits & 0x60) << 1);
1613 return imm8;
1614 }
1615
RvcImm11CJValue()1616 inline int RvcImm11CJValue() const {
1617 DCHECK(this->IsShortInstruction());
1618 // | funct3 | [11|4|9:8|10|6|7|3:1|5] | opcode |
1619 // 15 12 2
1620 uint32_t Bits = this->InstructionBits();
1621 int32_t imm12 = ((Bits & 0x4) << 3) | ((Bits & 0x38) >> 2) |
1622 ((Bits & 0x40) << 1) | ((Bits & 0x80) >> 1) |
1623 ((Bits & 0x100) << 2) | ((Bits & 0x600) >> 1) |
1624 ((Bits & 0x800) >> 7) | ((Bits & 0x1000) >> 1);
1625 return imm12 << 20 >> 20;
1626 }
1627
RvcImm8BValue()1628 inline int RvcImm8BValue() const {
1629 DCHECK(this->IsShortInstruction());
1630 // | funct3 | imm[8|4:3] | rs1` | imm[7:6|2:1|5] | opcode |
1631 // 15 12 10 7 2
1632 uint32_t Bits = this->InstructionBits();
1633 int32_t imm9 = ((Bits & 0x4) << 3) | ((Bits & 0x18) >> 2) |
1634 ((Bits & 0x60) << 1) | ((Bits & 0xc00) >> 7) |
1635 ((Bits & 0x1000) >> 4);
1636 return imm9 << 23 >> 23;
1637 }
1638
vl_vs_width()1639 inline int vl_vs_width() {
1640 int width = 0;
1641 if ((this->InstructionBits() & kBaseOpcodeMask) != LOAD_FP &&
1642 (this->InstructionBits() & kBaseOpcodeMask) != STORE_FP)
1643 return -1;
1644 switch (this->InstructionBits() & (kRvvWidthMask | kRvvMewMask)) {
1645 case 0x0:
1646 width = 8;
1647 break;
1648 case 0x00005000:
1649 width = 16;
1650 break;
1651 case 0x00006000:
1652 width = 32;
1653 break;
1654 case 0x00007000:
1655 width = 64;
1656 break;
1657 case 0x10000000:
1658 width = 128;
1659 break;
1660 case 0x10005000:
1661 width = 256;
1662 break;
1663 case 0x10006000:
1664 width = 512;
1665 break;
1666 case 0x10007000:
1667 width = 1024;
1668 break;
1669 default:
1670 width = -1;
1671 break;
1672 }
1673 return width;
1674 }
1675
Rvvzimm()1676 inline uint32_t Rvvzimm() const {
1677 if ((this->InstructionBits() &
1678 (kBaseOpcodeMask | kFunct3Mask | 0x80000000)) == RO_V_VSETVLI) {
1679 uint32_t Bits = this->InstructionBits();
1680 uint32_t zimm = Bits & kRvvZimmMask;
1681 return zimm >> kRvvZimmShift;
1682 } else {
1683 DCHECK_EQ(this->InstructionBits() &
1684 (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
1685 RO_V_VSETIVLI);
1686 uint32_t Bits = this->InstructionBits();
1687 uint32_t zimm = Bits & kRvvZimmMask;
1688 return (zimm >> kRvvZimmShift) & 0x3FF;
1689 }
1690 }
1691
Rvvuimm()1692 inline uint32_t Rvvuimm() const {
1693 DCHECK_EQ(
1694 this->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
1695 RO_V_VSETIVLI);
1696 uint32_t Bits = this->InstructionBits();
1697 uint32_t uimm = Bits & kRvvUimmMask;
1698 return uimm >> kRvvUimmShift;
1699 }
1700
RvvVsew()1701 inline uint32_t RvvVsew() const {
1702 uint32_t zimm = this->Rvvzimm();
1703 uint32_t vsew = (zimm >> 3) & 0x7;
1704 return vsew;
1705 }
1706
RvvVlmul()1707 inline uint32_t RvvVlmul() const {
1708 uint32_t zimm = this->Rvvzimm();
1709 uint32_t vlmul = zimm & 0x7;
1710 return vlmul;
1711 }
1712
RvvVM()1713 inline uint8_t RvvVM() const {
1714 DCHECK(this->InstructionType() == InstructionBase::kVType ||
1715 this->InstructionType() == InstructionBase::kIType ||
1716 this->InstructionType() == InstructionBase::kSType);
1717 return this->Bits(kRvvVmShift + kRvvVmBits - 1, kRvvVmShift);
1718 }
1719
RvvSEW()1720 inline const char* RvvSEW() const {
1721 uint32_t vsew = this->RvvVsew();
1722 switch (vsew) {
1723 #define CAST_VSEW(name) \
1724 case name: \
1725 return #name;
1726 RVV_SEW(CAST_VSEW)
1727 default:
1728 return "unknown";
1729 #undef CAST_VSEW
1730 }
1731 }
1732
RvvLMUL()1733 inline const char* RvvLMUL() const {
1734 uint32_t vlmul = this->RvvVlmul();
1735 switch (vlmul) {
1736 #define CAST_VLMUL(name) \
1737 case name: \
1738 return #name;
1739 RVV_LMUL(CAST_VLMUL)
1740 default:
1741 return "unknown";
1742 #undef CAST_VSEW
1743 }
1744 }
1745
1746 #define sext(x, len) (((int32_t)(x) << (32 - len)) >> (32 - len))
1747 #define zext(x, len) (((uint32_t)(x) << (32 - len)) >> (32 - len))
1748
RvvSimm5()1749 inline int32_t RvvSimm5() const {
1750 DCHECK(this->InstructionType() == InstructionBase::kVType);
1751 return sext(this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift),
1752 kRvvImm5Bits);
1753 }
1754
RvvUimm5()1755 inline uint32_t RvvUimm5() const {
1756 DCHECK(this->InstructionType() == InstructionBase::kVType);
1757 uint32_t imm = this->Bits(kRvvImm5Shift + kRvvImm5Bits - 1, kRvvImm5Shift);
1758 return zext(imm, kRvvImm5Bits);
1759 }
1760 #undef sext
1761 #undef zext
AqValue()1762 inline bool AqValue() const { return this->Bits(kAqShift, kAqShift); }
1763
RlValue()1764 inline bool RlValue() const { return this->Bits(kRlShift, kRlShift); }
1765
1766 // Say if the instruction is a break or a trap.
1767 bool IsTrap() const;
1768 };
1769
1770 class Instruction : public InstructionGetters<InstructionBase> {
1771 public:
1772 // Instructions are read of out a code stream. The only way to get a
1773 // reference to an instruction is to convert a pointer. There is no way
1774 // to allocate or create instances of class Instruction.
1775 // Use the At(pc) function to create references to Instruction.
At(byte * pc)1776 static Instruction* At(byte* pc) {
1777 return reinterpret_cast<Instruction*>(pc);
1778 }
1779
1780 private:
1781 // We need to prevent the creation of instances of class Instruction.
1782 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
1783 };
1784
1785 // -----------------------------------------------------------------------------
1786 // RISC-V assembly various constants.
1787
1788 // C/C++ argument slots size.
1789 const int kCArgSlotCount = 0;
1790
1791 // TODO(plind): below should be based on kSystemPointerSize
1792 // TODO(plind): find all usages and remove the needless instructions for n64.
1793 const int kCArgsSlotsSize = kCArgSlotCount * kInstrSize * 2;
1794
1795 const int kInvalidStackOffset = -1;
1796 const int kBranchReturnOffset = 2 * kInstrSize;
1797
1798 static const int kNegOffset = 0x00008000;
1799
1800 // -----------------------------------------------------------------------------
1801 // Instructions.
1802
1803 template <class P>
IsTrap()1804 bool InstructionGetters<P>::IsTrap() const {
1805 return (this->InstructionBits() == kBreakInstr);
1806 }
1807
1808 } // namespace internal
1809 } // namespace v8
1810
1811 #endif // V8_CODEGEN_RISCV64_CONSTANTS_RISCV64_H_
1812