]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/mips/mips/db_disasm.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / mips / mips / db_disasm.c
1 /*      $OpenBSD: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo Exp $      */
2 /*-
3  * Copyright (c) 1991, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Ralph Campbell.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *      from: @(#)kadb.c        8.1 (Berkeley) 6/10/93
38  *      Id: db_disasm.c,v 1.1 1998/03/16 09:03:24 pefo Exp
39  *      JNPR: db_disasm.c,v 1.1 2006/08/07 05:38:57 katta
40  */
41
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
44
45 #include <sys/param.h>
46 #include <vm/vm_param.h>
47 #include <vm/vm.h>
48 #include <vm/pmap.h>
49 #include <sys/systm.h>
50
51 #include <machine/mips_opcode.h>
52 #include <machine/db_machdep.h>
53 #include <ddb/ddb.h>
54 #include <ddb/db_output.h>
55
56 static char *op_name[64] = {
57 /* 0 */ "spec", "bcond","j",    "jal",  "beq",  "bne",  "blez", "bgtz",
58 /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori",  "xori", "lui",
59 /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
60 /*24 */ "daddi","daddiu","ldl", "ldr",  "op34", "op35", "op36", "op37",
61 /*32 */ "lb",   "lh",   "lwl",  "lw",   "lbu",  "lhu",  "lwr",  "lwu",
62 /*40 */ "sb",   "sh",   "swl",  "sw",   "sdl",  "sdr",  "swr",  "cache",
63 /*48 */ "ll",   "lwc1", "lwc2", "lwc3", "lld",  "ldc1", "ldc2", "ld",
64 /*56 */ "sc",   "swc1", "swc2", "swc3", "scd",  "sdc1", "sdc2", "sd"
65 };
66
67 static char *spec_name[64] = {
68 /* 0 */ "sll",  "spec01","srl", "sra",  "sllv", "spec05","srlv","srav",
69 /* 8 */ "jr",   "jalr", "spec12","spec13","syscall","break","spec16","sync",
70 /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
71 /*24 */ "mult", "multu","div",  "divu", "dmult","dmultu","ddiv","ddivu",
72 /*32 */ "add",  "addu", "sub",  "subu", "and",  "or",   "xor",  "nor",
73 /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
74 /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
75 /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
76 };
77
78 static char *bcond_name[32] = {
79 /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
80 /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
81 /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
82 /*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
83 };
84
85 static char *cop1_name[64] = {
86 /* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
87 /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
88 /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
89 /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
90 /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
91 /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
92 /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
93         "fcmp.ole","fcmp.ule",
94 /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
95         "fcmp.le","fcmp.ngt"
96 };
97
98 static char *fmt_name[16] = {
99         "s",    "d",    "e",    "fmt3",
100         "w",    "fmt5", "fmt6", "fmt7",
101         "fmt8", "fmt9", "fmta", "fmtb",
102         "fmtc", "fmtd", "fmte", "fmtf"
103 };
104
105 static char *reg_name[32] = {
106         "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
107         "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
108         "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
109         "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
110 };
111
112 static char *c0_opname[64] = {
113         "c0op00","tlbr",  "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
114         "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
115         "rfe",  "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
116         "eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
117         "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
118         "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
119         "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
120         "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
121 };
122
123 static char *c0_reg[32] = {
124         "index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
125         "badvaddr","count","tlbhi","c0r11","sr","cause","epc",  "prid",
126         "config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
127         "c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
128 };
129
130 static int md_printins(int ins, int mdbdot);
131
132 db_addr_t
133 db_disasm(db_addr_t loc, boolean_t altfmt)
134
135 {
136         int ins;
137
138         if (vtophys((vm_offset_t)loc)) {
139                 db_read_bytes((vm_offset_t)loc, (size_t)sizeof(int),
140                     (char *)&ins);
141                 md_printins(ins, loc);
142         }
143
144         return (loc + sizeof(int));
145
146
147 /* ARGSUSED */
148 static int
149 md_printins(int ins, int mdbdot)
150 {
151         InstFmt i;
152         int delay = 0;
153
154         i.word = ins;
155
156         switch (i.JType.op) {
157         case OP_SPECIAL:
158                 if (i.word == 0) {
159                         db_printf("nop");
160                         break;
161                 }
162                 if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
163                         db_printf("move\t%s,%s",
164                             reg_name[i.RType.rd], reg_name[i.RType.rs]);
165                         break;
166                 }
167                 db_printf("%s", spec_name[i.RType.func]);
168                 switch (i.RType.func) {
169                 case OP_SLL:
170                 case OP_SRL:
171                 case OP_SRA:
172                 case OP_DSLL:
173                 case OP_DSRL:
174                 case OP_DSRA:
175                 case OP_DSLL32:
176                 case OP_DSRL32:
177                 case OP_DSRA32:
178                         db_printf("\t%s,%s,%d", reg_name[i.RType.rd],
179                             reg_name[i.RType.rt], i.RType.shamt);
180                         break;
181
182                 case OP_SLLV:
183                 case OP_SRLV:
184                 case OP_SRAV:
185                 case OP_DSLLV:
186                 case OP_DSRLV:
187                 case OP_DSRAV:
188                         db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
189                             reg_name[i.RType.rt], reg_name[i.RType.rs]);
190                         break;
191
192                 case OP_MFHI:
193                 case OP_MFLO:
194                         db_printf("\t%s", reg_name[i.RType.rd]);
195                         break;
196
197                 case OP_JR:
198                 case OP_JALR:
199                         delay = 1;
200                         /* FALLTHROUGH */
201                 case OP_MTLO:
202                 case OP_MTHI:
203                         db_printf("\t%s", reg_name[i.RType.rs]);
204                         break;
205
206                 case OP_MULT:
207                 case OP_MULTU:
208                 case OP_DMULT:
209                 case OP_DMULTU:
210                 case OP_DIV:
211                 case OP_DIVU:
212                 case OP_DDIV:
213                 case OP_DDIVU:
214                         db_printf("\t%s,%s",
215                             reg_name[i.RType.rs], reg_name[i.RType.rt]);
216                         break;
217
218                 case OP_SYSCALL:
219                 case OP_SYNC:
220                         break;
221
222                 case OP_BREAK:
223                         db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
224                         break;
225
226                 default:
227                         db_printf("\t%s,%s,%s", reg_name[i.RType.rd],
228                             reg_name[i.RType.rs], reg_name[i.RType.rt]);
229                 };
230                 break;
231
232         case OP_BCOND:
233                 db_printf("%s\t%s,", bcond_name[i.IType.rt],
234                     reg_name[i.IType.rs]);
235                 goto pr_displ;
236
237         case OP_BLEZ:
238         case OP_BLEZL:
239         case OP_BGTZ:
240         case OP_BGTZL:
241                 db_printf("%s\t%s,", op_name[i.IType.op],
242                     reg_name[i.IType.rs]);
243                 goto pr_displ;
244
245         case OP_BEQ:
246         case OP_BEQL:
247                 if (i.IType.rs == 0 && i.IType.rt == 0) {
248                         db_printf("b\t");
249                         goto pr_displ;
250                 }
251                 /* FALLTHROUGH */
252         case OP_BNE:
253         case OP_BNEL:
254                 db_printf("%s\t%s,%s,", op_name[i.IType.op],
255                     reg_name[i.IType.rs], reg_name[i.IType.rt]);
256         pr_displ:
257                 delay = 1;
258                 db_printf("0x%08x", mdbdot + 4 + ((short)i.IType.imm << 2));
259                 break;
260
261         case OP_COP0:
262                 switch (i.RType.rs) {
263                 case OP_BCx:
264                 case OP_BCy:
265                         db_printf("bc0%c\t",
266                             "ft"[i.RType.rt & COPz_BC_TF_MASK]);
267                         goto pr_displ;
268
269                 case OP_MT:
270                         db_printf("mtc0\t%s,%s",
271                             reg_name[i.RType.rt], c0_reg[i.RType.rd]);
272                         break;
273
274                 case OP_DMT:
275                         db_printf("dmtc0\t%s,%s",
276                             reg_name[i.RType.rt], c0_reg[i.RType.rd]);
277                         break;
278
279                 case OP_MF:
280                         db_printf("mfc0\t%s,%s",
281                             reg_name[i.RType.rt], c0_reg[i.RType.rd]);
282                         break;
283
284                 case OP_DMF:
285                         db_printf("dmfc0\t%s,%s",
286                             reg_name[i.RType.rt], c0_reg[i.RType.rd]);
287                         break;
288
289                 default:
290                         db_printf("%s", c0_opname[i.FRType.func]);
291                 };
292                 break;
293
294         case OP_COP1:
295                 switch (i.RType.rs) {
296                 case OP_BCx:
297                 case OP_BCy:
298                         db_printf("bc1%c\t",
299                             "ft"[i.RType.rt & COPz_BC_TF_MASK]);
300                         goto pr_displ;
301
302                 case OP_MT:
303                         db_printf("mtc1\t%s,f%d",
304                             reg_name[i.RType.rt], i.RType.rd);
305                         break;
306
307                 case OP_MF:
308                         db_printf("mfc1\t%s,f%d",
309                             reg_name[i.RType.rt], i.RType.rd);
310                         break;
311
312                 case OP_CT:
313                         db_printf("ctc1\t%s,f%d",
314                             reg_name[i.RType.rt], i.RType.rd);
315                         break;
316
317                 case OP_CF:
318                         db_printf("cfc1\t%s,f%d",
319                             reg_name[i.RType.rt], i.RType.rd);
320                         break;
321
322                 default:
323                         db_printf("%s.%s\tf%d,f%d,f%d",
324                             cop1_name[i.FRType.func], fmt_name[i.FRType.fmt],
325                             i.FRType.fd, i.FRType.fs, i.FRType.ft);
326                 };
327                 break;
328
329         case OP_J:
330         case OP_JAL:
331                 db_printf("%s\t", op_name[i.JType.op]);
332                 db_printf("0x%8x",(mdbdot & 0xF0000000) | (i.JType.target << 2));
333                 delay = 1;
334                 break;
335
336         case OP_LWC1:
337         case OP_SWC1:
338                 db_printf("%s\tf%d,", op_name[i.IType.op], i.IType.rt);
339                 goto loadstore;
340
341         case OP_LB:
342         case OP_LH:
343         case OP_LW:
344         case OP_LD:
345         case OP_LBU:
346         case OP_LHU:
347         case OP_LWU:
348         case OP_SB:
349         case OP_SH:
350         case OP_SW:
351         case OP_SD:
352                 db_printf("%s\t%s,", op_name[i.IType.op],
353                     reg_name[i.IType.rt]);
354         loadstore:
355                 db_printf("%d(%s)", (short)i.IType.imm, reg_name[i.IType.rs]);
356                 break;
357
358         case OP_ORI:
359         case OP_XORI:
360                 if (i.IType.rs == 0) {
361                         db_printf("li\t%s,0x%x",
362                             reg_name[i.IType.rt], i.IType.imm);
363                         break;
364                 }
365                 /* FALLTHROUGH */
366         case OP_ANDI:
367                 db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
368                     reg_name[i.IType.rt], reg_name[i.IType.rs], i.IType.imm);
369                 break;
370
371         case OP_LUI:
372                 db_printf("%s\t%s,0x%x", op_name[i.IType.op],
373                     reg_name[i.IType.rt], i.IType.imm);
374                 break;
375
376         case OP_ADDI:
377         case OP_DADDI:
378         case OP_ADDIU:
379         case OP_DADDIU:
380                 if (i.IType.rs == 0) {
381                         db_printf("li\t%s,%d", reg_name[i.IType.rt],
382                             (short)i.IType.imm);
383                         break;
384                 }
385                 /* FALLTHROUGH */
386         default:
387                 db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
388                     reg_name[i.IType.rt], reg_name[i.IType.rs],
389                     (short)i.IType.imm);
390         }
391         db_printf("\n");
392         return (delay);
393 }