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