1/* $NetBSD: insn.h,v 1.5 2024/02/02 22:00:33 andvar Exp $ */
2
3/*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#ifndef _RISCV_INSN_H_
33#define _RISCV_INSN_H_
34
35/*
36 * I have corrected and updated this, but it's the wrong way to do it.
37 * It's still used by ddb_machdep.c but that code should be fixed to
38 * use the newer stuff below. - dholland
39 */
40union riscv_insn {
41	uint32_t val;
42	/* register ops */
43	struct {
44		unsigned int r_opcode : 7;
45		unsigned int r_rd : 5;
46		unsigned int r_funct3 : 3;
47		unsigned int r_rs1 : 5;
48		unsigned int r_rs2 : 5;
49		unsigned int r_funct7 : 7;
50	} type_r;
51	/* 32-bit shifts */
52	struct {
53		unsigned int rs32_opcode : 7;
54		unsigned int rs32_rd : 5;
55		unsigned int rs32_funct3 : 3;
56		unsigned int rs32_rs1 : 5;
57		unsigned int rs32_shamt : 5;
58		unsigned int rs32_funct7 : 7;
59	} type_rs32;
60	/* 64-bit shifts */
61	struct {
62		unsigned int rs64_opcode : 7;
63		unsigned int rs64_rd : 5;
64		unsigned int rs64_funct3 : 3;
65		unsigned int rs64_rs1 : 5;
66		unsigned int rs64_shamt : 6;
67		unsigned int rs64_zero : 1;
68		unsigned int rs64_funct5 : 5;
69	} type_rs64;
70	/* atomics */
71	struct {
72		unsigned int ra_opcode : 7;
73		unsigned int ra_rd : 5;
74		unsigned int ra_funct3 : 3;
75		unsigned int ra_rs1 : 5;
76		unsigned int ra_rs2 : 5;
77		unsigned int ra_rl : 1;
78		unsigned int ra_aq : 1;
79		unsigned int ra_funct5 : 5;
80	} type_ra;
81	/* certain fpu ops */
82	struct {
83		unsigned int rf_opcode : 7;
84		unsigned int rf_rd : 5;
85		unsigned int rf_rm : 3;
86		unsigned int rf_rs1 : 5;
87		unsigned int rf_rs2 : 5;
88		unsigned int rf_size : 2;
89		unsigned int rf_funct5 : 5;
90	} type_rf;
91	/* other fpu ops */
92	struct {
93		unsigned int rf4_opcode : 7;
94		unsigned int rf4_rd : 5;
95		unsigned int rf4_rm : 3;
96		unsigned int rf4_rs1 : 5;
97		unsigned int rf4_rs2 : 5;
98		unsigned int rf4_size : 2;
99		unsigned int rf4_rs3 : 5;
100	} type_rf4;
101	/* immediates */
102	struct {
103		unsigned int i_opcode : 7;
104		unsigned int i_rd : 5;
105		unsigned int i_funct3 : 3;
106		unsigned int i_rs1 : 5;
107		signed int i_imm11to0 : 12;
108	} type_i;
109	/* stores */
110	struct {
111		unsigned int s_opcode : 7;
112		unsigned int s_imm4_to_0 : 5;
113		unsigned int s_funct3 : 3;
114		unsigned int s_rs1 : 5;
115		unsigned int s_rs2 : 5;
116		signed int s_imm11_to_5 : 7;
117	} type_s;
118	/* branches */
119	struct {
120		unsigned int b_opcode : 7;
121		unsigned int b_imm11 : 1;
122		unsigned int b_imm4to1 : 4;
123		unsigned int b_funct3 : 3;
124		unsigned int b_rs1 : 5;
125		unsigned int b_rs2 : 5;
126		unsigned int b_imm10to5 : 6;
127		signed int b_imm12 : 1;
128	} type_b;
129	/* large immediate constants */
130	struct {
131		unsigned int u_opcode : 7;
132		unsigned int u_rd : 5;
133		signed int u_imm31to12 : 20;
134	} type_u;
135	/* large immediate jumps */
136	struct {
137		unsigned int j_opcode : 7;
138		unsigned int j_rd : 5;
139		unsigned int j_imm19to12 : 9;
140		unsigned int j_imm11 : 1;
141		unsigned int j_imm10to1 : 9;
142		signed int j_imm20 : 1;
143	} type_j;
144};
145
146/*
147 * old macro still in use with the above
148 * (XXX, doesn't handle 16-bit instructions)
149 */
150
151#define OPCODE_P(i, x)		(((i) & 0b1111111) == ((OPCODE_##x<<2)|0b11))
152
153////////////////////////////////////////////////////////////
154
155/*
156 * Instruction size
157 */
158
159/* cumulative size tests */
160#define INSN_SIZE_IS_16(insn) (((insn) & 0b11) != 0b11)
161#define INSN_SIZE_IS_32(insn) (((insn) & 0b11100) != 0b11100)
162#define INSN_SIZE_IS_48(insn) (((insn) & 0b100000) != 0b100000)
163#define INSN_SIZE_IS_64(insn) (((insn) & 0b1000000) != 0b1000000)
164
165/* returns 1-5 for the number of uint16s */
166#define INSN_HALFWORDS(insn) \
167	(INSN_SIZE_IS_16(insn) ? 1 : \
168	 INSN_SIZE_IS_32(insn) ? 2 : \
169	 INSN_SIZE_IS_48(insn) ? 3 : \
170	 INSN_SIZE_IS_64(insn) ? 4 : \
171	 5)
172
173#define INSN_SIZE(insn) (INSN_HALFWORDS(insn) * sizeof(uint16_t))
174
175/*
176 * sign-extend x from the bottom k bits
177 */
178#define SIGNEXT32(x, k) ( \
179		( ((x) & (1U << ((k)-1))) ? (0xffffffffU << (k)) : 0U) | \
180		((x) & (0xffffffffU >> (32 - (k))))			 \
181	)
182
183/*
184 * Field extractors for 32-bit instructions
185 */
186
187#define INSN_OPCODE32(insn)	(((insn) & 0x0000007f) >> 2)
188#define INSN_RD(insn)		(((insn) & 0x00000f80) >> 7)
189#define INSN_FUNCT3(insn)	(((insn) & 0x00007000) >> 12)
190#define INSN_RS1(insn)		(((insn) & 0x000f8000) >> 15)
191#define INSN_RS2(insn)		(((insn) & 0x01f00000) >> 20)
192#define INSN_FUNCT7(insn)	(((insn) & 0xfe000000) >> 25)
193
194/* U-type immediate, just the top bits of the instruction */
195#define INSN_IMM_U(insn)	 ((insn) & 0xfffff000)
196
197/* I-type immediate, upper 12 bits sign-extended */
198#define INSN_IMM_I(insn)	SIGNEXT32(((insn) & 0xfff00000) >> 20, 12)
199
200/* S-type immediate (stores), pasted from funct7 field and rd field */
201#define INSN_IMM_S_raw(insn)	((INSN_FUNCT7(insn) << 5) | INSN_RD(insn))
202#define INSN_IMM_S(insn)	SIGNEXT32(INSN_IMM_S_raw(insn), 12)
203
204/* B-type immediate (branches), pasted messily from funct7 and rd fields */
205#define INSN_IMM_B_raw(insn)			\
206	(((insn & 0x80000000) >> (31-12)) |	\
207	 ((insn & 0x00000080) << (11-7))  |	\
208	 ((insn & 0x7e000000) >> (25-5))  |	\
209	 ((insn & 0x00000f00) >> (8-1)))
210#define INSN_IMM_B(insn)	SIGNEXT32(INSN_IMM_B_raw(insn), 13)
211
212/* J-type immediate (jumps), rehash of the U immediate field */
213#define INSN_IMM_J_raw(insn)			\
214	(((insn & 0x80000000) >> (31-20)) |	\
215	 ((insn & 0x000ff000) >> (12-12)) |	\
216	 ((insn & 0x00100000) >> (20-11)) |	\
217	 ((insn & 0x7fe00000) >> (21-1)))
218#define INSN_IMM_J(insn)	SIGNEXT32(INSN_IMM_J_raw(insn), 21)
219
220/*
221 * Field extractors for 16-bit instructions
222 */
223
224#define INSN16_QUADRANT(insn)	((insn) & 0b11)
225
226/*
227 * In the manual there's
228 *    FUNCT3 (bits 13-15)
229 *    FUNCT4 (bits 12-15)
230 *    FUNCT6 (bits 10-15)
231 *    FUNCT2 (bits 5-6)
232 *
233 * but this does not reflect the actual usage correctly. So I've got
234 *    FUNCT3 (bits 13-15)
235 *    FUNCT2a (bits 10-11)
236 *    FUNCT1b (bit 12)
237 *    FUNCT2b (bits 5-6)
238 *    FUNCT3b (FUNCT1b pasted to FUNCT3b)
239 *
240 * Quadrant 0 just uses FUNCT3;
241 * Quadrant 1 goes FUNCT3 -> FUNCT2a -> FUNCT3b,
242 * Quadrant 2 goes FUNCT3 -> FUNCT1b.
243 */
244#define INSN16_FUNCT3(insn)	(((insn) & 0xe000) >> 13)
245#define INSN16_FUNCT2a(insn)	(((insn) & 0x0c00) >> 10)
246#define INSN16_FUNCT1b(insn)	(((insn) & 0x1000) >> 12)
247#define INSN16_FUNCT2b(insn)	(((insn) & 0x0060) >> 5)
248#define INSN16_FUNCT3c(insn)	\
249	((INSN16_FUNCT1b(insn) << 2) | INSN16_FUNCT2b(insn))
250
251/* full-size register fields */
252#define INSN16_RS1(insn)	(((insn) & 0x0f80) >> 7)  /* bits 7-11 */
253#define INSN16_RS2(insn)	(((insn) & 0x007c) >> 2)  /* bits 2-6 */
254
255/* small register fields, for registers 8-15 */
256#define INSN16_RS1x(insn)	((((insn) & 0x0380) >> 7) + 8)	/* bits 7-9 */
257#define INSN16_RS2x(insn)	((((insn) & 0x001c) >> 2) + 8)	/* bits 2-4 */
258
259/* CI format immediates, for word/double/quad offsets, zero-extended */
260#define INSN16_IMM_CI_W(insn) \
261	((((insn) & 0b0001000000000000) >> (12-5)) |	\
262	 (((insn) & 0b0000000001110000) >> (4-2)) |	\
263	 (((insn) & 0b0000000000001100) << (6-2)))
264#define INSN16_IMM_CI_D(insn) \
265	((((insn) & 0b0001000000000000) >> (12-5)) |	\
266	 (((insn) & 0b0000000001100000) >> (4-2)) |	\
267	 (((insn) & 0b0000000000011100) << (6-2)))
268#define INSN16_IMM_CI_Q(insn) \
269	((((insn) & 0b0001000000000000) >> (12-5)) |	\
270	 (((insn) & 0b0000000001000000) >> (4-2)) |	\
271	 (((insn) & 0b0000000000111100) << (6-2)))
272
273/* additional CI format immediates for constants, sign-extended */
274#define INSN16_IMM_CI_K_raw(insn) \
275	((((insn) & 0b0001000000000000) >> (12-5)) |	\
276	 (((insn) & 0b0000000001111100) >> (2-0)))
277#define INSN16_IMM_CI_K(insn) SIGNEXT32(INSN16_IMM_CI_K_raw(insn), 6)
278#define INSN16_IMM_CI_K12(insn) SIGNEXT32(INSN16_IMM_CI_K_raw(insn) << 12, 18)
279
280/* and another one, sign-extended */
281#define INSN16_IMM_CI_K4_raw(insn) \
282	((((insn) & 0b0001000000000000) >> (12-9)) |	\
283	 (((insn) & 0b0000000001000000) >> (6-4)) |	\
284	 (((insn) & 0b0000000000100000) << (6-5)) |	\
285	 (((insn) & 0b0000000000011000) << (7-3)) |	\
286	 (((insn) & 0b0000000000000100) << (5-2)))
287#define INSN16_IMM_CI_K4(insn) SIGNEXT32(INSN16_IMM_CI_K4_raw(insn), 10)
288
289
290/* CSS format immediates, for word/double/quad offsets, zero-extended */
291#define INSN16_IMM_CSS_W(insn) \
292	((((insn) & 0b0001111000000000) >> (9-2)) |	\
293	 (((insn) & 0b0000000110000000) >> (7-6)))
294#define INSN16_IMM_CSS_D(insn) \
295	((((insn) & 0b0001110000000000) >> (9-2)) |	\
296	 (((insn) & 0b0000001110000000) >> (7-6)))
297#define INSN16_IMM_CSS_Q(insn) \
298	((((insn) & 0b0001100000000000) >> (9-2)) |	\
299	 (((insn) & 0b0000011110000000) >> (7-6)))
300
301/* CL format immediates, for word/double/quad offsets, zero-extended */
302#define INSN16_IMM_CL_W(insn) \
303	((((insn) & 0b0001110000000000) >> (10-3)) |	\
304	 (((insn) & 0b0000000001000000) >> (6-2)) |	\
305	 (((insn) & 0b0000000000100000) << (6-5)))
306#define INSN16_IMM_CL_D(insn) \
307	((((insn) & 0b0001110000000000) >> (10-3)) |	\
308	 (((insn) & 0b0000000001100000) << (6-5)))
309#define INSN16_IMM_CL_Q(insn) \
310	((((insn) & 0b0001100000000000) >> (11-4)) |	\
311	 (((insn) & 0b0000010000000000) >> (10-8)) |	\
312	 (((insn) & 0b0000000001100000) << (6-5)))
313
314/* CS format immediates are the same as the CL ones */
315#define INSN16_IMM_CS_W(insn) INSN16_IMM_CL_W(insn)
316#define INSN16_IMM_CS_D(insn) INSN16_IMM_CL_D(insn)
317#define INSN16_IMM_CS_Q(insn) INSN16_IMM_CL_Q(insn)
318
319/* CJ format immediate, sign extended */
320#define INSN16_IMM_CJ_raw(insn) \
321	((((insn) & 0b0001000000000000) >> (12-11)) |	\
322	 (((insn) & 0b0000100000000000) >> (11-4)) |	\
323	 (((insn) & 0b0000011000000000) >> (9-8)) |	\
324	 (((insn) & 0b0000000100000000) << (10-8)) |	\
325	 (((insn) & 0b0000000010000000) >> (7-6)) |	\
326	 (((insn) & 0b0000000001000000) << (7-6)) |	\
327	 (((insn) & 0b0000000000111000) >> (3-1)) |	\
328	 (((insn) & 0b0000000000000100) << (5-2)))
329#define INSN16_IMM_CJ(insn) SIGNEXT32(INSN16_IMM_CJ_raw(insn), 12)
330
331/* CB format immediate, sign extended */
332#define INSN16_IMM_CB_raw(insn) \
333	((((insn) & 0b0001000000000000) >> (12-8)) |	\
334	 (((insn) & 0b0000110000000000) >> (10-3)) |	\
335	 (((insn) & 0b0000000001100000) << (6-5)) |	\
336	 (((insn) & 0b0000000000011000) >> (3-1)) |	\
337	 (((insn) & 0b0000000000000100) << (5-2)))
338#define INSN16_IMM_CB(insn) SIGNEXT32(INSN16_IMM_CB_raw(insn), 9)
339
340/* also some CB instructions use the CI_K immediate */
341
342/* CIW format immediate, zero-extended */
343#define INSN16_IMM_CIW(insn) \
344	((((insn) & 0b0001100000000000) >> (11-4)) |	\
345	 (((insn) & 0b0000011110000000) >> (7-6)) |	\
346	 (((insn) & 0b0000000001000000) >> (6-2)) |	\
347	 (((insn) & 0b0000000000100000) >> (5-3)))
348
349/*
350 * Values for the primary opcode field (bits 2-6) in 32-bit instructions
351 */
352
353#define	OPCODE_LOAD		0b00000
354#define	OPCODE_LOADFP		0b00001
355#define	OPCODE_CUSTOM0		0b00010
356#define	OPCODE_MISCMEM		0b00011
357#define	OPCODE_OPIMM		0b00100
358#define	OPCODE_AUIPC		0b00101
359#define	OPCODE_OPIMM32		0b00110
360#define	OPCODE_X48a		0b00111
361
362#define	OPCODE_STORE		0b01000
363#define	OPCODE_STOREFP		0b01001
364#define	OPCODE_CUSTOM1		0b01010
365#define	OPCODE_AMO		0b01011
366#define	OPCODE_OP		0b01100
367#define	OPCODE_LUI		0b01101
368#define	OPCODE_OP32		0b01110
369#define	OPCODE_X64		0b01111
370
371#define	OPCODE_MADD		0b10000		// FMADD.[S,D]
372#define	OPCODE_MSUB		0b10001		// FMSUB.[S,D]
373#define	OPCODE_NMSUB		0b10010		// FNMSUB.[S,D]
374#define	OPCODE_NMADD		0b10011		// FNMADD.[S,D]
375#define	OPCODE_OPFP		0b10100
376#define	OPCODE_rsvd21		0b10101
377#define	OPCODE_CUSTOM2		0b10110
378#define	OPCODE_X48b		0b10111
379
380#define	OPCODE_BRANCH		0b11000
381#define	OPCODE_JALR		0b11001
382#define	OPCODE_rsvd26		0b11010
383#define	OPCODE_JAL		0b11011
384#define	OPCODE_SYSTEM		0b11100
385#define	OPCODE_rsvd29		0b11101
386#define	OPCODE_CUSTOM3		0b11110
387#define	OPCODE_X80		0b11111
388
389/*
390 * Values for the secondary/tertiary opcode field funct7 in 32-bit instructions
391 * for various primary and secondary opcodes.
392 *
393 * Note: for many of these the opcodes shown are the top 5 bits and the
394 * bottom two serve a separate purpose.
395 */
396
397// primary is OP (0b01100, 12)
398#define OP_ARITH		0b0000000
399#define OP_MULDIV		0b0000001
400#define OP_NARITH		0b0100000
401
402// primary is OPFP (0b10100, 20), top 5 bits
403// bottom 2 bits give the size
404#define OPFP_ADD		0b00000
405#define OPFP_SUB		0b00001
406#define OPFP_MUL		0b00010
407#define OPFP_DIV		0b00011
408#define OPFP_SGNJ		0b00100
409#define OPFP_MINMAX		0b00101
410#define OPFP_CVTFF		0b01000
411#define OPFP_SQRT		0b01011
412#define OPFP_CMP		0b10100
413#define OPFP_CVTIF		0b11000
414#define OPFP_CVTFI		0b11010
415#define OPFP_MVFI_CLASS		0b11100
416#define OPFP_MVIF		0b11110
417
418// primary is OPFP (0b10100, 20), bottom two bits (operand size)
419// these bits also give the size for FMADD/FMSUB/FNMSUB/FNMADD
420// and for FCVTFF they appear at the bottom of the rs2 field as well
421#define OPFP_S			0b00
422#define OPFP_D			0b01
423#define OPFP_Q			0b11
424
425// in some instructions they're an integer operand size instead
426#define OPFP_W			0b00
427#define OPFP_WU			0b01
428#define OPFP_L			0b10
429#define OPFP_LU			0b11
430
431// primary is AMO (0b01011, 11), top 5 bits
432// (bottom two bits are ACQUIRE and RELEASE flags respectively)
433// funct3 gives the operand size
434#define AMO_ADD			0b00000
435#define AMO_SWAP		0b00001
436#define AMO_LR			0b00010
437#define AMO_SC			0b00011
438#define AMO_XOR			0b00100
439#define AMO_OR			0b01000
440#define AMO_AND			0b01100
441#define AMO_MIN			0b10000
442#define AMO_MAX			0b10100
443#define AMO_MINU		0b11000
444#define AMO_MAXU		0b11100
445
446// primary is SYSTEM (0b11100, 28) and funct3 is PRIV (0)
447#define PRIV_USER		0b0000000
448#define PRIV_SYSTEM		0b0001000
449#define PRIV_SFENCE_VMA		0b0001001
450#define PRIV_HFENCE_BVMA	0b0010001
451#define PRIV_MACHINE		0b0011000
452#define PRIV_HFENCE_GVMA	0b1010001
453
454/*
455 * Values for the secondary/tertiary opcode field funct3 in 32-bit instructions
456 * for various primary and secondary opcodes.
457 */
458
459// primary is LOAD (0x00000)
460#define LOAD_LB			0b000
461#define LOAD_LH			0b001
462#define LOAD_LW			0b010
463#define LOAD_LD			0b011		// RV64I
464#define LOAD_LBU		0b100
465#define LOAD_LHU		0b101
466#define LOAD_LWU		0b110		// RV64I
467
468// primary is LOADFP (0x00001)
469#define LOADFP_FLW		0b010
470#define LOADFP_FLD		0b011
471#define LOADFP_FLQ		0b100
472
473// primary is MISCMEM (0x00011, 3)
474#define MISCMEM_FENCE		0b000
475#define MISCMEM_FENCEI		0b001
476
477// primary is STORE (0b01000, 8)
478#define STORE_SB		0b000
479#define STORE_SH		0b001
480#define STORE_SW		0b010
481#define STORE_SD		0b011		// RV64I
482
483// primary is STOREFP (0b01001, 9)
484#define STOREFP_FSW		0b010
485#define STOREFP_FSD		0b011
486#define STOREFP_FSQ		0b100
487
488// primary is AMO (0b01011, 11), funct7 gives the operation
489#define AMO_W			0b010
490#define AMO_D			0b011		// RV64I
491
492// primary is
493//    OPIMM   (0b00100, 4)
494//    OPIMM32 (0b00110, 6)
495//    OP      (0b01100, 12) when funct7 is ARITH or NARITH
496//    OP32    (0b01110, 14)
497//                                               OP	OP	OP32	OP32
498// given:			   OPIMM OPIMM32 ARITH	NARITH  ARITH	NARITH
499#define OP_ADDSUB	0b000	// addi  addiw   add	sub	addw	subw
500#define OP_SLL		0b001	// (1)   (2)     sll	-	sllw	-
501#define OP_SLT		0b010	// slti  -       slt	-	-	-
502#define OP_SLTU		0b011	// sltiu -       sltu	-	-	-
503#define OP_XOR		0b100	// xori  -       xor	-	-	-
504#define OP_SRX		0b101	// (3)   (4)     srl    sra	srlw	sraw
505#define OP_OR		0b110	// ori   -       or	-	-	-
506#define OP_AND		0b111	// andi  -       and	-	-	-
507//
508// (1) slli when funct7 is ARITH
509// (2) slliw when funct7 is ARITH
510// (3) srli when funct7 is ARITH, srai when funct7 is NARITH
511// (4) srliw when funct7 is ARITH, sraiw when funct7 is NARITH
512//
513// caution: on RV64, the immediate field of slli/srli/srai bleeds into
514// funct7, so you have to actually only test the upper 6 bits of funct7.
515// (and if RV128 ever actually happens, the upper 5 bits; conveniently
516// that aligns with other uses of those 5 bits)
517//
518
519// primary is
520//    OP      (0b01100, 12) when funct7 is MULDIV
521//    OP32    (0b01110, 14) when funct7 is MULDIV
522//
523// given:				   OP      OP32
524#define OP_MUL			0b000	// mul     mulw
525#define OP_MULH			0b001	// mulh    -
526#define OP_MULHSU		0b010	// mulhsu  -
527#define OP_MULHU		0b011   // mulhu   -
528#define OP_DIV			0b100	// div     divw
529#define OP_DIVU			0b101	// divu    divuw
530#define OP_REM			0b110	// rem     remw
531#define OP_REMU			0b111	// remu    remuw
532
533// primary is
534//    MADD    (0b10000, 16)
535//    MSUB    (0b10001, 17)
536//    NMADD   (0b10010, 18)
537//    NMSUB   (0b10011, 19)
538//    OPFP    (0b10100, 20) when funct7 is
539//                ADD SUB MULDIV SQRT CVTFF CVTIF CVTFI
540#define ROUND_RNE		0b000
541#define ROUND_RTZ		0b001
542#define ROUND_RDN		0b010
543#define ROUND_RUP		0b011
544#define ROUND_RMM		0b100
545#define ROUND_DYN		0b111
546
547// primary is OPFP (0b10100, 20) and funct7 is FSGNJ (0b00100)
548#define SGN_SGNJ		0b000
549#define SGN_SGNJN		0b001
550#define SGN_SGNJX		0b010
551
552// primary is OPFP (0b10100, 20) and funct7 is MINMAX (0b00101)
553#define MINMAX_MIN		0b000
554#define MINMAX_MAX		0b001
555
556// primary is OPFP (0b10100, 20) and funct7 is CMP (0b10100)
557#define CMP_LE			0b000
558#define CMP_LT			0b001
559#define CMP_EQ			0b010
560
561// primary is OPFP (0b10100, 20) and funct7 is MVFI_CLASS (0b11110)
562#define MVFI_CLASS_MVFI		0b000
563#define MVFI_CLASS_CLASS	0b001
564
565// primary is BRANCH (0b11000, 24)
566#define BRANCH_BEQ		0b000
567#define BRANCH_BNE		0b001
568#define BRANCH_BLT		0b100
569#define BRANCH_BGE		0b101
570#define BRANCH_BLTU		0b110
571#define BRANCH_BGEU		0b111
572
573// primary is SYSTEM (0b11100, 28)
574#define SYSTEM_PRIV		0b000
575#define SYSTEM_CSRRW		0b001
576#define SYSTEM_CSRRS		0b010
577#define SYSTEM_CSRRC		0b011
578#define SYSTEM_CSRRWI		0b101
579#define SYSTEM_CSRRSI		0b110
580#define SYSTEM_CSRRCI		0b111
581
582// the funct3 field is not used for
583//    AUIPC   (0b00101, 5)
584//    LUI     (0b01101, 13)
585//    JALR    (0b11001, 25) (or rather, it's always 0)
586//    JAL     (0b11011, 27)
587
588// and for these there are no standard instructions defined anyhow
589//    CUSTOM0 (0b00010, 2)
590//    CUSTOM1 (0b01010, 10)
591//    CUSTOM2 (0b10110, 22)
592//    CUSTOM3 (0b11110, 30)
593//    rsvd21  (0b10101, 21)
594//    rsvd29  (0b11101, 29)
595//    X48a    (0b00111, 7)
596//    X64     (0b01111, 15)
597//    X48b    (0b10111, 23)
598//    X80     (0b11111, 31)
599
600/*
601 * quaternary opcodes in rs2 field of 32-bit instructions
602 */
603
604// primary is SYSTEM (0b11100, 28)
605// funct3 is PRIV (0)
606// funct7 is USER (0)
607#define USER_ECALL		0b00000
608#define USER_EBREAK		0b00001
609#define USER_URET		0b00010
610
611// primary is SYSTEM (0b11100, 28)
612// funct3 is PRIV (0)
613// funct7 is SYSTEM (0b0001000, 16)
614#define SYSTEM_SRET		0b00010
615#define SYSTEM_WFI		0b00101
616
617// primary is SYSTEM (0b11100, 28)
618// funct3 is PRIV (0)
619// funct7 is MACHINE (0b0011000, 48)
620#define MACHINE_MRET		0b00010
621
622// primary is OPFP (0b10100, 20)
623// funct7 is CVTFI or CVTIF
624#define CVT_W			0b00000
625#define CVT_WU			0b00001
626#define CVT_L			0b00010
627#define CVT_LU			0b00011
628
629/*
630 * code bits for fence instruction
631 */
632
633#define FENCE_INPUT	0b1000
634#define FENCE_OUTPUT	0b0100
635#define FENCE_READ	0b0010
636#define FENCE_WRITE	0b0001
637
638#define FENCE_FM_NORMAL	0b0000
639#define FENCE_FM_TSO	0b1000
640
641/*
642 * AMO aq/rl bits in funct7
643 */
644#define AMO_AQ		0b0000010
645#define AMO_RL		0b0000001
646
647/*
648 * Opcode values for 16-bit instructions.
649 */
650
651#define OPCODE16_Q0	0b00	/* quadrant 0 */
652#define OPCODE16_Q1	0b01	/* quadrant 1 */
653#define OPCODE16_Q2	0b10	/* quadrant 2 */
654
655/* quadrant 0 */
656#define Q0_ADDI4SPN	0b000
657#define Q0_FLD_LQ	0b001	/* RV32/RV64 FLD, RV128 LQ */
658#define Q0_LW		0b010
659#define Q0_FLW_LD	0b011	/* RV32 FLW, RV64/RV128 LD */
660#define Q0_RESERVED	0b100
661#define Q0_FSD_SQ	0b101	/* RV32/RV64 FSD, RV128 SQ */
662#define Q0_SW		0b110
663#define Q0_FSW_SD	0b111	/* RV32 FSW, RV64/RV128 SD */
664
665/* quadrant 1 */
666#define Q1_NOP_ADDI	0b000	/* NOP when rs1/rd == 0, ADDI otherwise */
667#define Q1_JAL_ADDIW	0b001	/* RV32 JAL, RV64/RV128 ADDIW */
668#define Q1_LI		0b010
669#define Q1_ADDI16SP_LUI	0b011	/* ADDI16SP when rs1/rd == sp, else LUI */
670#define Q1_MISC		0b100
671#define Q1_J		0b101
672#define Q1_BEQZ		0b110
673#define Q1_BNEZ		0b111
674
675/* funct2a values for Q1_MISC */
676#define Q1MISC_SRLI	0b00
677#define Q1MISC_SRAI	0b01
678#define Q1MISC_ANDI	0b10
679#define Q1MISC_MORE	0b11
680
681/* funct3b values for Q1MISC_MORE */
682#define Q1MORE_SUB	0b000
683#define Q1MORE_XOR	0b001
684#define Q1MORE_OR	0b010
685#define Q1MORE_AND	0b011
686#define Q1MORE_SUBW	0b100	/* RV64/RV128 */
687#define Q1MORE_ADDW	0b101	/* RV64/RV128 */
688
689/* quadrant 2 */
690#define Q2_SLLI		0b000
691#define Q2_FLDSP_LQSP	0b001	/* RV32/RV64 FLDSP, RV128 LQSP */
692#define Q2_LWSP		0b010
693#define Q2_FLWSP_LDSP	0b011	/* RV32 FLWSP, RV64/RV128 LDSP */
694#define Q2_MISC		0b100
695#define Q2_FSDSP_SQSP	0b101	/* RV32/RV64 FSDSP, RV128 SQSP */
696#define Q2_SWSP		0b110
697#define Q2_FSWSP_SDSP	0b111	/* RV32/RV64 FSWSP, RV128 SDSP */
698
699/* funct1b values for Q2_MISC */
700#define Q2MISC_JR_MV	0b0	/* JR when rs2 == 0, MV otherwise */
701#define Q2MISC_EBREAK_JALR_ADD	0b1 /* EBREAK rs1==0; JALR rs2==0; else ADD */
702
703/*
704 * CSR numbers
705 */
706
707// fpu
708#define CSR_FFLAGS		0x001
709#define CSR_FRM			0x002
710#define CSR_FCSR		0x003
711
712// perfcounters
713#define CSR_CYCLE		0xc00
714#define CSR_TIME		0xc01
715#define CSR_INSTRET		0xc02
716#define CSR_HPMCOUNTER(n)	(0xc00+(n))	// n in 3..31
717#define CSR_CYCLEH		0xc80	// RV32I
718#define CSR_TIMEH		0xc81	// RV32I
719#define CSR_INSTRETH		0xc82	// RV32I
720#define CSR_HPMCOUNTERH(n)	(0xc80+(n))	// n in 3..31
721
722// system
723#define CSR_SSTATUS		0x100
724//	CSR_SEDELEG		0x102
725//	CSR_SIDELEG		0x103
726#define CSR_SIE			0x104
727#define CSR_STVEC		0x105
728#define CSR_SCOUNTEREN		0x106
729#define CSR_SSCRATCH		0x140
730#define CSR_SEPC		0x141
731#define CSR_SCAUSE		0x142
732#define CSR_STVAL		0x143
733#define CSR_SIP			0x144
734#define CSR_SATP		0x180
735
736// machine
737#define CSR_MVENDORID		0xf11
738#define CSR_MARCHID		0xf12
739#define CSR_MIMPID		0xf13
740#define CSR_MHARTID		0xf14
741#define CSR_MSTATUS		0x300
742#define CSR_MISA		0x301
743#define CSR_MEDELEG		0x302
744#define CSR_MIDELEG		0x303
745#define CSR_MIE			0x304
746#define CSR_MTVEC		0x305
747#define CSR_MCOUNTEREN		0x306
748#define CSR_MSCRATCH		0x340
749#define CSR_MEPC		0x341
750#define CSR_MCAUSE		0x342
751#define CSR_MTVAL		0x343
752#define CSR_MIP			0x344
753#define CSR_PMPCFG(n)		(0x3a0 + (n))	// n in 0..3
754#define CSR_PMPADDR(n)		(0x3b0 + (n))	// n in 0..15
755#define CSR_MCYCLE		0xb00
756#define CSR_MINSTRET		0xb02
757#define CSR_MHPMCOUNTER(n)	(0xb00+(n))	// n in 3..31
758#define CSR_MCYCLEH		0xb80	// RV32I
759#define CSR_MINSTRETH		0xb82	// RV32I
760#define CSR_MHPMCOUNTERH(n)	(0xb80+(n))	// n in 3..31
761#define CSR_MCOUNTINHIBIT	0x320
762#define CSR_MHPMEVENT(n)	(0x320+(n))	// n in 3..31
763
764// debug
765#define CSR_TSELECT		0x7a0
766#define CSR_TDATA1		0x7a1
767#define CSR_TDATA2		0x7a2
768#define CSR_TDATA3		0x7a3
769#define CSR_DCSR		0x7b0
770#define CSR_DPC			0x7b1
771#define CSR_DSCRATCH0		0x7b2
772#define CSR_DSCRATCH1		0x7b3
773
774
775#endif /* _RISCV_INSN_H_ */
776