xref: /freebsd/sys/riscv/riscv/db_disasm.c (revision 780fb4a2)
1 /*-
2  * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
3  * All rights reserved.
4  *
5  * Portions of this software were developed by SRI International and the
6  * University of Cambridge Computer Laboratory under DARPA/AFRL contract
7  * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Portions of this software were developed by the University of Cambridge
10  * Computer Laboratory as part of the CTSRD Project, with support from the
11  * UK Higher Education Innovation Fund (HEIF).
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <ddb/ddb.h>
41 #include <ddb/db_access.h>
42 #include <ddb/db_sym.h>
43 
44 #include <machine/riscvreg.h>
45 #include <machine/riscv_opcode.h>
46 
47 struct riscv_op {
48 	char *name;
49 	char *type;
50 	char *fmt;
51 	int opcode;
52 	int funct3;
53 	int funct7; /* Or imm, depending on type. */
54 };
55 
56 /*
57  * Keep sorted by opcode, funct3, funct7 so some instructions
58  * aliases will be supported (e.g. "mv" instruction alias)
59  * Use same print format as binutils do.
60  */
61 static struct riscv_op riscv_opcodes[] = {
62 	{ "lb",		"I",	"d,o(s)",	3,   0, -1 },
63 	{ "lh",		"I",	"d,o(s)",	3,   1, -1 },
64 	{ "lw",		"I",	"d,o(s)",	3,   2, -1 },
65 	{ "ld",		"I",	"d,o(s)",	3,   3, -1 },
66 	{ "lbu",	"I",	"d,o(s)",	3,   4, -1 },
67 	{ "lhu",	"I",	"d,o(s)",	3,   5, -1 },
68 	{ "lwu",	"I",	"d,o(s)",	3,   6, -1 },
69 	{ "ldu",	"I",	"d,o(s)",	3,   7, -1 },
70 	{ "fence",	"I",	"",		15,  0, -1 },
71 	{ "fence.i",	"I",	"",		15,  1, -1 },
72 	{ "mv",		"I",	"d,s",		19,  0,  0 },
73 	{ "addi",	"I",	"d,s,j",	19,  0, -1 },
74 	{ "slli",	"R2",	"d,s,>",	19,  1,  0 },
75 	{ "slti",	"I",	"d,s,j",	19,  2, -1 },
76 	{ "sltiu",	"I",	"d,s,j",	19,  3, -1 },
77 	{ "xori",	"I",	"d,s,j",	19,  4, -1 },
78 	{ "srli",	"R2",	"d,s,>",	19,  5,  0 },
79 	{ "srai",	"R2",	"d,s,>",	19,  5, 0b010000 },
80 	{ "ori",	"I",	"d,s,j",	19,  6, -1 },
81 	{ "andi",	"I",	"d,s,j",	19,  7, -1 },
82 	{ "auipc",	"U",	"d,u",		23, -1, -1 },
83 	{ "sext.w",	"I",	"d,s",		27,  0,  0 },
84 	{ "addiw",	"I",	"d,s,j",	27,  0, -1 },
85 	{ "slliw",	"R",	"d,s,<",	27,  1,  0 },
86 	{ "srliw",	"R",	"d,s,<",	27,  5,  0 },
87 	{ "sraiw",	"R",	"d,s,<",	27,  5, 0b0100000 },
88 	{ "sb",		"S",	"t,q(s)",	35,  0, -1 },
89 	{ "sh",		"S",	"t,q(s)",	35,  1, -1 },
90 	{ "sw",		"S",	"t,q(s)",	35,  2, -1 },
91 	{ "sd",		"S",	"t,q(s)",	35,  3, -1 },
92 	{ "sbu",	"S",	"t,q(s)",	35,  4, -1 },
93 	{ "shu",	"S",	"t,q(s)",	35,  5, -1 },
94 	{ "swu",	"S",	"t,q(s)",	35,  6, -1 },
95 	{ "sdu",	"S",	"t,q(s)",	35,  7, -1 },
96 	{ "lr.w",	"R",	"d,t,0(s)",	47,  2, 0b0001000 },
97 	{ "sc.w",	"R",	"d,t,0(s)",	47,  2, 0b0001100 },
98 	{ "amoswap.w",	"R",	"d,t,0(s)",	47,  2, 0b0000100 },
99 	{ "amoadd.w",	"R",	"d,t,0(s)",	47,  2, 0b0000000 },
100 	{ "amoxor.w",	"R",	"d,t,0(s)",	47,  2, 0b0010000 },
101 	{ "amoand.w",	"R",	"d,t,0(s)",	47,  2, 0b0110000 },
102 	{ "amoor.w",	"R",	"d,t,0(s)",	47,  2, 0b0100000 },
103 	{ "amomin.w",	"R",	"d,t,0(s)",	47,  2, 0b1000000 },
104 	{ "amomax.w",	"R",	"d,t,0(s)",	47,  2, 0b1010000 },
105 	{ "amominu.w",	"R",	"d,t,0(s)",	47,  2, 0b1100000 },
106 	{ "amomaxu.w",	"R",	"d,t,0(s)",	47,  2, 0b1110000 },
107 	{ "lr.w.aq",	"R",	"d,t,0(s)",	47,  2, 0b0001000 },
108 	{ "sc.w.aq",	"R",	"d,t,0(s)",	47,  2, 0b0001100 },
109 	{ "amoswap.w.aq","R",	"d,t,0(s)",	47,  2, 0b0000110 },
110 	{ "amoadd.w.aq","R",	"d,t,0(s)",	47,  2, 0b0000010 },
111 	{ "amoxor.w.aq","R",	"d,t,0(s)",	47,  2, 0b0010010 },
112 	{ "amoand.w.aq","R",	"d,t,0(s)",	47,  2, 0b0110010 },
113 	{ "amoor.w.aq",	"R",	"d,t,0(s)",	47,  2, 0b0100010 },
114 	{ "amomin.w.aq","R",	"d,t,0(s)",	47,  2, 0b1000010 },
115 	{ "amomax.w.aq","R",	"d,t,0(s)",	47,  2, 0b1010010 },
116 	{ "amominu.w.aq","R",	"d,t,0(s)",	47,  2, 0b1100010 },
117 	{ "amomaxu.w.aq","R",	"d,t,0(s)",	47,  2, 0b1110010 },
118 	{ "amoswap.w.rl","R",	"d,t,0(s)",	47,  2, 0b0000110 },
119 	{ "amoadd.w.rl","R",	"d,t,0(s)",	47,  2, 0b0000001 },
120 	{ "amoxor.w.rl","R",	"d,t,0(s)",	47,  2, 0b0010001 },
121 	{ "amoand.w.rl","R",	"d,t,0(s)",	47,  2, 0b0110001 },
122 	{ "amoor.w.rl",	"R",	"d,t,0(s)",	47,  2, 0b0100001 },
123 	{ "amomin.w.rl","R",	"d,t,0(s)",	47,  2, 0b1000001 },
124 	{ "amomax.w.rl","R",	"d,t,0(s)",	47,  2, 0b1010001 },
125 	{ "amominu.w.rl","R",	"d,t,0(s)",	47,  2, 0b1100001 },
126 	{ "amomaxu.w.rl","R",	"d,t,0(s)",	47,  2, 0b1110001 },
127 	{ "amoswap.d",	"R",	"d,t,0(s)",	47,  3, 0b0000100 },
128 	{ "amoadd.d",	"R",	"d,t,0(s)",	47,  3, 0b0000000 },
129 	{ "amoxor.d",	"R",	"d,t,0(s)",	47,  3, 0b0010000 },
130 	{ "amoand.d",	"R",	"d,t,0(s)",	47,  3, 0b0110000 },
131 	{ "amoor.d",	"R",	"d,t,0(s)",	47,  3, 0b0100000 },
132 	{ "amomin.d",	"R",	"d,t,0(s)",	47,  3, 0b1000000 },
133 	{ "amomax.d",	"R",	"d,t,0(s)",	47,  3, 0b1010000 },
134 	{ "amominu.d",	"R",	"d,t,0(s)",	47,  3, 0b1100000 },
135 	{ "amomaxu.d",	"R",	"d,t,0(s)",	47,  3, 0b1110000 },
136 	{ "lr.d.aq",	"R",	"d,t,0(s)",	47,  3, 0b0001000 },
137 	{ "sc.d.aq",	"R",	"d,t,0(s)",	47,  3, 0b0001100 },
138 	{ "amoswap.d.aq","R",	"d,t,0(s)",	47,  3, 0b0000110 },
139 	{ "amoadd.d.aq","R",	"d,t,0(s)",	47,  3, 0b0000010 },
140 	{ "amoxor.d.aq","R",	"d,t,0(s)",	47,  3, 0b0010010 },
141 	{ "amoand.d.aq","R",	"d,t,0(s)",	47,  3, 0b0110010 },
142 	{ "amoor.d.aq",	"R",	"d,t,0(s)",	47,  3, 0b0100010 },
143 	{ "amomin.d.aq","R",	"d,t,0(s)",	47,  3, 0b1000010 },
144 	{ "amomax.d.aq","R",	"d,t,0(s)",	47,  3, 0b1010010 },
145 	{ "amominu.d.aq","R",	"d,t,0(s)",	47,  3, 0b1100010 },
146 	{ "amomaxu.d.aq","R",	"d,t,0(s)",	47,  3, 0b1110010 },
147 	{ "amoswap.d.rl","R",	"d,t,0(s)",	47,  3, 0b0000110 },
148 	{ "amoadd.d.rl","R",	"d,t,0(s)",	47,  3, 0b0000001 },
149 	{ "amoxor.d.rl","R",	"d,t,0(s)",	47,  3, 0b0010001 },
150 	{ "amoand.d.rl","R",	"d,t,0(s)",	47,  3, 0b0110001 },
151 	{ "amoor.d.rl",	"R",	"d,t,0(s)",	47,  3, 0b0100001 },
152 	{ "amomin.d.rl","R",	"d,t,0(s)",	47,  3, 0b1000001 },
153 	{ "amomax.d.rl","R",	"d,t,0(s)",	47,  3, 0b1010001 },
154 	{ "amominu.d.rl","R",	"d,t,0(s)",	47,  3, 0b1100001 },
155 	{ "amomaxu.d.rl","R",	"d,t,0(s)",	47,  3, 0b1110001 },
156 	{ "add",	"R",	"d,s,t",	51,  0,  0 },
157 	{ "sub",	"R",	"d,s,t",	51,  0,  0b0100000 },
158 	{ "mul",	"R",	"d,s,t",	51,  0,  0b0000001 },
159 	{ "sll",	"R",	"d,s,t",	51,  1,  0 },
160 	{ "slt",	"R",	"d,s,t",	51,  2,  0 },
161 	{ "sltu",	"R",	"d,s,t",	51,  3,  0 },
162 	{ "xor",	"R",	"d,s,t",	51,  4,  0 },
163 	{ "srl",	"R",	"d,s,t",	51,  5,  0 },
164 	{ "sra",	"R",	"d,s,t",	51,  5,  0b0100000 },
165 	{ "or",		"R",	"d,s,t",	51,  6,  0 },
166 	{ "and",	"R",	"d,s,t",	51,  7,  0 },
167 	{ "lui",	"U",	"d,u",		55, -1, -1 },
168 	{ "addw",	"R",	"d,s,t",	59,  0,  0 },
169 	{ "subw",	"R",	"d,s,t",	59,  0,  0b0100000 },
170 	{ "mulw",	"R",	"d,s,t",	59,  0,  1 },
171 	{ "sllw",	"R",	"d,s,t",	59,  1,  0 },
172 	{ "srlw",	"R",	"d,s,t",	59,  5,  0 },
173 	{ "sraw",	"R",	"d,s,t",	59,  5,  0b0100000 },
174 	{ "beq",	"SB",	"s,t,p",	99,  0,  -1 },
175 	{ "bne",	"SB",	"s,t,p",	99,  1,  -1 },
176 	{ "blt",	"SB",	"s,t,p",	99,  4,  -1 },
177 	{ "bge",	"SB",	"s,t,p",	99,  5,  -1 },
178 	{ "bltu",	"SB",	"s,t,p",	99,  6,  -1 },
179 	{ "bgeu",	"SB",	"s,t,p",	99,  7,  -1 },
180 	{ "jalr",	"I",	"d,s,j",	103,  0, -1 },
181 	{ "jal",	"UJ",	"a",		111, -1, -1 },
182 	{ "eret",	"I",	"",		115,  0, 0b000100000000 },
183 	{ "sfence.vm",	"I",	"",		115,  0, 0b000100000001 },
184 	{ "wfi",	"I",	"",		115,  0, 0b000100000010 },
185 	{ "csrrw",	"I",	"d,E,s",	115,  1, -1},
186 	{ "csrrs",	"I",	"d,E,s",	115,  2, -1},
187 	{ "csrrc",	"I",	"d,E,s",	115,  3, -1},
188 	{ "csrrwi",	"I",	"d,E,Z",	115,  5, -1},
189 	{ "csrrsi",	"I",	"d,E,Z",	115,  6, -1},
190 	{ "csrrci",	"I",	"d,E,Z",	115,  7, -1},
191 	{ NULL, NULL, NULL, 0, 0, 0 }
192 };
193 
194 struct csr_op {
195 	char *name;
196 	int imm;
197 };
198 
199 static struct csr_op csr_name[] = {
200 	{ "fflags",		0x001 },
201 	{ "frm",		0x002 },
202 	{ "fcsr",		0x003 },
203 	{ "cycle",		0xc00 },
204 	{ "time",		0xc01 },
205 	{ "instret",		0xc02 },
206 	{ "stats",		0x0c0 },
207 	{ "uarch0",		0xcc0 },
208 	{ "uarch1",		0xcc1 },
209 	{ "uarch2",		0xcc2 },
210 	{ "uarch3",		0xcc3 },
211 	{ "uarch4",		0xcc4 },
212 	{ "uarch5",		0xcc5 },
213 	{ "uarch6",		0xcc6 },
214 	{ "uarch7",		0xcc7 },
215 	{ "uarch8",		0xcc8 },
216 	{ "uarch9",		0xcc9 },
217 	{ "uarch10",		0xcca },
218 	{ "uarch11",		0xccb },
219 	{ "uarch12",		0xccc },
220 	{ "uarch13",		0xccd },
221 	{ "uarch14",		0xcce },
222 	{ "uarch15",		0xccf },
223 	{ "sstatus",		0x100 },
224 	{ "stvec",		0x101 },
225 	{ "sie",		0x104 },
226 	{ "sscratch",		0x140 },
227 	{ "sepc",		0x141 },
228 	{ "sip",		0x144 },
229 	{ "sptbr",		0x180 },
230 	{ "sasid",		0x181 },
231 	{ "cyclew",		0x900 },
232 	{ "timew",		0x901 },
233 	{ "instretw",		0x902 },
234 	{ "stime",		0xd01 },
235 	{ "scause",		0xd42 },
236 	{ "sbadaddr",		0xd43 },
237 	{ "stimew",		0xa01 },
238 	{ "mstatus",		0x300 },
239 	{ "mtvec",		0x301 },
240 	{ "mtdeleg",		0x302 },
241 	{ "mie",		0x304 },
242 	{ "mtimecmp",		0x321 },
243 	{ "mscratch",		0x340 },
244 	{ "mepc",		0x341 },
245 	{ "mcause",		0x342 },
246 	{ "mbadaddr",		0x343 },
247 	{ "mip",		0x344 },
248 	{ "mtime",		0x701 },
249 	{ "mcpuid",		0xf00 },
250 	{ "mimpid",		0xf01 },
251 	{ "mhartid",		0xf10 },
252 	{ "mtohost",		0x780 },
253 	{ "mfromhost",		0x781 },
254 	{ "mreset",		0x782 },
255 	{ "send_ipi",		0x783 },
256 	{ "miobase",		0x784 },
257 	{ "cycleh",		0xc80 },
258 	{ "timeh",		0xc81 },
259 	{ "instreth",		0xc82 },
260 	{ "cyclehw",		0x980 },
261 	{ "timehw",		0x981 },
262 	{ "instrethw",		0x982 },
263 	{ "stimeh",		0xd81 },
264 	{ "stimehw",		0xa81 },
265 	{ "mtimecmph",		0x361 },
266 	{ "mtimeh",		0x741 },
267 	{ NULL,	0 }
268 };
269 
270 static char *reg_name[32] = {
271 	"zero",	"ra",	"sp",	"gp",	"tp",	"t0",	"t1",	"t2",
272 	"s0",	"s1",	"a0",	"a1",	"a2",	"a3",	"a4",	"a5",
273 	"a6",	"a7",	"s2",	"s3",	"s4",	"s5",	"s6",	"s7",
274 	"s8",	"s9",	"s10",	"s11",	"t3",	"t4",	"t5",	"t6"
275 };
276 
277 static int32_t
278 get_imm(InstFmt i, char *type, uint32_t *val)
279 {
280 	int imm;
281 
282 	imm = 0;
283 
284 	if (strcmp(type, "I") == 0) {
285 		imm = i.IType.imm;
286 		*val = imm;
287 		if (imm & (1 << 11))
288 			imm |= (0xfffff << 12);	/* sign extend */
289 
290 	} else if (strcmp(type, "S") == 0) {
291 		imm = i.SType.imm0_4;
292 		imm |= (i.SType.imm5_11 << 5);
293 		*val = imm;
294 		if (imm & (1 << 11))
295 			imm |= (0xfffff << 12);	/* sign extend */
296 
297 	} else if (strcmp(type, "U") == 0) {
298 		imm = i.UType.imm12_31;
299 		*val = imm;
300 
301 	} else if (strcmp(type, "UJ") == 0) {
302 		imm = i.UJType.imm12_19 << 12;
303 		imm |= i.UJType.imm11 << 11;
304 		imm |= i.UJType.imm1_10 << 1;
305 		imm |= i.UJType.imm20 << 20;
306 		*val = imm;
307 		if (imm & (1 << 20))
308 			imm |= (0xfff << 21);	/* sign extend */
309 
310 	} else if (strcmp(type, "SB") == 0) {
311 		imm = i.SBType.imm11 << 11;
312 		imm |= i.SBType.imm1_4 << 1;
313 		imm |= i.SBType.imm5_10 << 5;
314 		imm |= i.SBType.imm12 << 12;
315 		*val = imm;
316 		if (imm & (1 << 12))
317 			imm |= (0xfffff << 12);	/* sign extend */
318 	}
319 
320 	return (imm);
321 }
322 
323 static int
324 oprint(struct riscv_op *op, vm_offset_t loc, int rd,
325     int rs1, int rs2, uint32_t val, vm_offset_t imm)
326 {
327 	char *p;
328 	int i;
329 
330 	p = op->fmt;
331 
332 	db_printf("%s\t", op->name);
333 
334 	while (*p) {
335 		if (strncmp("d", p, 1) == 0)
336 			db_printf("%s", reg_name[rd]);
337 
338 		else if (strncmp("s", p, 1) == 0)
339 			db_printf("%s", reg_name[rs1]);
340 
341 		else if (strncmp("t", p, 1) == 0)
342 			db_printf("%s", reg_name[rs2]);
343 
344 		else if (strncmp(">", p, 1) == 0)
345 			db_printf("0x%x", rs2);
346 
347 		else if (strncmp("E", p, 1) == 0) {
348 			for (i = 0; csr_name[i].name != NULL; i++)
349 				if (csr_name[i].imm == val)
350 					db_printf("%s",
351 					    csr_name[i].name);
352 		} else if (strncmp("Z", p, 1) == 0)
353 			db_printf("%d", rs1);
354 
355 		else if (strncmp("<", p, 1) == 0)
356 			db_printf("0x%x", rs2);
357 
358 		else if (strncmp("j", p, 1) == 0)
359 			db_printf("%d", imm);
360 
361 		else if (strncmp("u", p, 1) == 0)
362 			db_printf("0x%x", imm);
363 
364 		else if (strncmp("a", p, 1) == 0)
365 			db_printf("0x%016lx", imm);
366 
367 		else if (strncmp("p", p, 1) == 0)
368 			db_printf("0x%016lx", (loc + imm));
369 
370 		else if (strlen(p) >= 4) {
371 			if (strncmp("o(s)", p, 4) == 0)
372 				db_printf("%d(%s)", imm, reg_name[rs1]);
373 			else if (strncmp("q(s)", p, 4) == 0)
374 				db_printf("%d(%s)", imm, reg_name[rs1]);
375 			else if (strncmp("0(s)", p, 4) == 0)
376 				db_printf("(%s)", reg_name[rs1]);
377 		}
378 
379 		while (*p && strncmp(p, ",", 1) != 0)
380 			p++;
381 
382 		if (*p) {
383 			db_printf(", ");
384 			p++;
385 		}
386 	}
387 
388 
389 	return (0);
390 }
391 
392 static int
393 match_type(InstFmt i, struct riscv_op *op, vm_offset_t loc)
394 {
395 	uint32_t val;
396 	int found;
397 	int imm;
398 
399 	val = 0;
400 	imm = get_imm(i, op->type, &val);
401 
402 	if (strcmp(op->type, "U") == 0) {
403 		oprint(op, loc, i.UType.rd, 0, 0, val, imm);
404 		return (1);
405 	}
406 	if (strcmp(op->type, "UJ") == 0) {
407 		oprint(op, loc, 0, 0, 0, val, (loc + imm));
408 		return (1);
409 	}
410 	if ((strcmp(op->type, "I") == 0) && \
411 	    (op->funct3 == i.IType.funct3)) {
412 		found = 0;
413 		if (op->funct7 != -1) {
414 			if (op->funct7 == i.IType.imm)
415 				found = 1;
416 		} else
417 			found = 1;
418 
419 		if (found) {
420 			oprint(op, loc, i.IType.rd,
421 			    i.IType.rs1, 0, val, imm);
422 			return (1);
423 		}
424 	}
425 	if ((strcmp(op->type, "S") == 0) && \
426 	    (op->funct3 == i.SType.funct3)) {
427 		oprint(op, loc, 0, i.SType.rs1, i.SType.rs2,
428 		    val, imm);
429 		return (1);
430 	}
431 	if ((strcmp(op->type, "SB") == 0) && \
432 	    (op->funct3 == i.SBType.funct3)) {
433 		oprint(op, loc, 0, i.SBType.rs1, i.SBType.rs2,
434 		    val, imm);
435 		return (1);
436 	}
437 	if ((strcmp(op->type, "R2") == 0) && \
438 	    (op->funct3 == i.R2Type.funct3) && \
439 	    (op->funct7 == i.R2Type.funct7)) {
440 		oprint(op, loc, i.R2Type.rd, i.R2Type.rs1,
441 		    i.R2Type.rs2, val, imm);
442 		return (1);
443 	}
444 	if ((strcmp(op->type, "R") == 0) && \
445 	    (op->funct3 == i.RType.funct3) && \
446 	    (op->funct7 == i.RType.funct7)) {
447 		oprint(op, loc, i.RType.rd, i.RType.rs1,
448 		    val, i.RType.rs2, imm);
449 		return (1);
450 	}
451 
452 	return (0);
453 }
454 
455 vm_offset_t
456 db_disasm(vm_offset_t loc, bool altfmt)
457 {
458 	struct riscv_op *op;
459 	InstFmt i;
460 	int j;
461 
462 	i.word = db_get_value(loc, INSN_SIZE, 0);
463 
464 	/* First match opcode */
465 	for (j = 0; riscv_opcodes[j].name != NULL; j++) {
466 		op = &riscv_opcodes[j];
467 		if (op->opcode == i.RType.opcode) {
468 			if (match_type(i, op, loc))
469 				break;
470 		}
471 	}
472 
473 	db_printf("\n");
474 	return(loc + INSN_SIZE);
475 }
476