1 /* $OpenBSD: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo Exp $ */
3 * SPDX-License-Identifier: BSD-4-Clause
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * from: @(#)kadb.c 8.1 (Berkeley) 6/10/93
40 * Id: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo Exp
41 * JNPR: db_disasm.c,v 1.1 2006/08/07 05:38:57 katta
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
47 #include <sys/param.h>
48 #include <vm/vm_param.h>
51 #include <sys/systm.h>
53 #include <machine/mips_opcode.h>
54 #include <machine/db_machdep.h>
56 #include <ddb/db_output.h>
58 static char *op_name[64] = {
59 /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz",
60 /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
61 /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
62 /*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
63 /*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
64 /*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
65 /*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld",
66 /*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd"
69 static char *spec_name[64] = {
70 /* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
71 /* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync",
72 /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
73 /*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu",
74 /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
75 /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
76 /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
77 /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
80 static char *bcond_name[32] = {
81 /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
82 /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
83 /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
84 /*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
87 static char *cop1_name[64] = {
88 /* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
89 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
90 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
91 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
92 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
93 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
94 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
95 "fcmp.ole","fcmp.ule",
96 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
100 static char *fmt_name[16] = {
101 "s", "d", "e", "fmt3",
102 "w", "fmt5", "fmt6", "fmt7",
103 "fmt8", "fmt9", "fmta", "fmtb",
104 "fmtc", "fmtd", "fmte", "fmtf"
107 static char *reg_name[32] = {
108 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
109 #if defined(__mips_n32) || defined(__mips_n64)
110 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
112 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
114 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
115 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
118 static char *c0_opname[64] = {
119 "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
120 "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
121 "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
122 "eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
123 "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
124 "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
125 "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
126 "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
129 static char *c0_reg[32] = {
130 "index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
131 "badvaddr","count","tlbhi","c0r11","sr","cause","epc", "prid",
132 "config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
133 "c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
136 static int md_printins(int ins, int mdbdot);
139 db_disasm(db_addr_t loc, bool altfmt)
144 if (vtophys((vm_offset_t)loc)) {
145 db_read_bytes((vm_offset_t)loc, (size_t)sizeof(int),
147 md_printins(ins, loc);
150 return (loc + sizeof(int));
155 md_printins(int ins, int mdbdot)
162 switch (i.JType.op) {
168 if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
169 db_printf("move\t%s,%s",
170 reg_name[i.RType.rd], reg_name[i.RType.rs]);
173 db_printf("%s", spec_name[i.RType.func]);
174 switch (i.RType.func) {
184 db_printf("\t%s,%s,%d", reg_name[i.RType.rd],
185 reg_name[i.RType.rt], i.RType.shamt);
194 db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
195 reg_name[i.RType.rt], reg_name[i.RType.rs]);
200 db_printf("\t%s", reg_name[i.RType.rd]);
209 db_printf("\t%s", reg_name[i.RType.rs]);
221 reg_name[i.RType.rs], reg_name[i.RType.rt]);
229 db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
233 db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
234 reg_name[i.RType.rs], reg_name[i.RType.rt]);
239 db_printf("%s\t%s,", bcond_name[i.IType.rt],
240 reg_name[i.IType.rs]);
247 db_printf("%s\t%s,", op_name[i.IType.op],
248 reg_name[i.IType.rs]);
253 if (i.IType.rs == 0 && i.IType.rt == 0) {
260 db_printf("%s\t%s,%s,", op_name[i.IType.op],
261 reg_name[i.IType.rs], reg_name[i.IType.rt]);
264 db_printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
268 switch (i.RType.rs) {
272 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
276 db_printf("mtc0\t%s,%s",
277 reg_name[i.RType.rt], c0_reg[i.RType.rd]);
281 db_printf("dmtc0\t%s,%s",
282 reg_name[i.RType.rt], c0_reg[i.RType.rd]);
286 db_printf("mfc0\t%s,%s",
287 reg_name[i.RType.rt], c0_reg[i.RType.rd]);
291 db_printf("dmfc0\t%s,%s",
292 reg_name[i.RType.rt], c0_reg[i.RType.rd]);
296 db_printf("%s", c0_opname[i.FRType.func]);
301 switch (i.RType.rs) {
305 "ft"[i.RType.rt & COPz_BC_TF_MASK]);
309 db_printf("mtc1\t%s,f%d",
310 reg_name[i.RType.rt], i.RType.rd);
314 db_printf("mfc1\t%s,f%d",
315 reg_name[i.RType.rt], i.RType.rd);
319 db_printf("ctc1\t%s,f%d",
320 reg_name[i.RType.rt], i.RType.rd);
324 db_printf("cfc1\t%s,f%d",
325 reg_name[i.RType.rt], i.RType.rd);
329 db_printf("%s.%s\tf%d,f%d,f%d",
330 cop1_name[i.FRType.func], fmt_name[i.FRType.fmt],
331 i.FRType.fd, i.FRType.fs, i.FRType.ft);
337 db_printf("%s\t", op_name[i.JType.op]);
338 db_printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
344 db_printf("%s\tf%d,", op_name[i.IType.op], i.IType.rt);
358 db_printf("%s\t%s,", op_name[i.IType.op],
359 reg_name[i.IType.rt]);
361 db_printf("%d(%s)", (short)i.IType.imm, reg_name[i.IType.rs]);
366 if (i.IType.rs == 0) {
367 db_printf("li\t%s,0x%x",
368 reg_name[i.IType.rt], i.IType.imm);
373 db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
374 reg_name[i.IType.rt], reg_name[i.IType.rs], i.IType.imm);
378 db_printf("%s\t%s,0x%x", op_name[i.IType.op],
379 reg_name[i.IType.rt], i.IType.imm);
386 if (i.IType.rs == 0) {
387 db_printf("li\t%s,%d", reg_name[i.IType.rt],
393 db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
394 reg_name[i.IType.rt], reg_name[i.IType.rs],