Annotation of sys/arch/mips64/mips64/db_disasm.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: db_disasm.c,v 1.7 2007/07/05 04:37:30 miod 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.7 2007/07/05 04:37:30 miod Exp $
39: */
40:
41: #include <sys/param.h>
42: #include <sys/systm.h>
43:
44: #include <machine/mips_opcode.h>
45: #include <machine/db_machdep.h>
46: #include <ddb/db_interface.h>
47: #include <ddb/db_output.h>
48: #include <ddb/db_sym.h>
49:
50: static char *op_name[64] = {
51: /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz",
52: /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui",
53: /*16 */ "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "blezl","bgtzl",
54: /*24 */ "daddi","daddiu","ldl", "ldr", "op34", "op35", "op36", "op37",
55: /*32 */ "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu",
56: /*40 */ "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache",
57: /*48 */ "ll", "lwc1", "lwc2", "lwc3", "lld", "ldc1", "ldc2", "ld",
58: /*56 */ "sc", "swc1", "swc2", "swc3", "scd", "sdc1", "sdc2", "sd"
59: };
60:
61: static char *spec_name[64] = {
62: /* 0 */ "sll", "spec01","srl", "sra", "sllv", "spec05","srlv","srav",
63: /* 8 */ "jr", "jalr", "spec12","spec13","syscall","break","spec16","sync",
64: /*16 */ "mfhi", "mthi", "mflo", "mtlo", "dsllv","spec25","dsrlv","dsrav",
65: /*24 */ "mult", "multu","div", "divu", "dmult","dmultu","ddiv","ddivu",
66: /*32 */ "add", "addu", "sub", "subu", "and", "or", "xor", "nor",
67: /*40 */ "spec50","spec51","slt","sltu", "dadd","daddu","dsub","dsubu",
68: /*48 */ "tge","tgeu","tlt","tltu","teq","spec65","tne","spec67",
69: /*56 */ "dsll","spec71","dsrl","dsra","dsll32","spec75","dsrl32","dsra32"
70: };
71:
72: static char *bcond_name[32] = {
73: /* 0 */ "bltz", "bgez", "bltzl", "bgezl", "?", "?", "?", "?",
74: /* 8 */ "tgei", "tgeiu", "tlti", "tltiu", "teqi", "?", "tnei", "?",
75: /*16 */ "bltzal", "bgezal", "bltzall", "bgezall", "?", "?", "?", "?",
76: /*24 */ "?", "?", "?", "?", "?", "?", "?", "?",
77: };
78:
79: static char *cop1_name[64] = {
80: /* 0 */ "fadd", "fsub", "fmpy", "fdiv", "fsqrt","fabs", "fmov", "fneg",
81: /* 8 */ "fop08","fop09","fop0a","fop0b","fop0c","fop0d","fop0e","fop0f",
82: /*16 */ "fop10","fop11","fop12","fop13","fop14","fop15","fop16","fop17",
83: /*24 */ "fop18","fop19","fop1a","fop1b","fop1c","fop1d","fop1e","fop1f",
84: /*32 */ "fcvts","fcvtd","fcvte","fop23","fcvtw","fop25","fop26","fop27",
85: /*40 */ "fop28","fop29","fop2a","fop2b","fop2c","fop2d","fop2e","fop2f",
86: /*48 */ "fcmp.f","fcmp.un","fcmp.eq","fcmp.ueq","fcmp.olt","fcmp.ult",
87: "fcmp.ole","fcmp.ule",
88: /*56 */ "fcmp.sf","fcmp.ngle","fcmp.seq","fcmp.ngl","fcmp.lt","fcmp.nge",
89: "fcmp.le","fcmp.ngt"
90: };
91:
92: static char *fmt_name[16] = {
93: "s", "d", "e", "fmt3",
94: "w", "fmt5", "fmt6", "fmt7",
95: "fmt8", "fmt9", "fmta", "fmtb",
96: "fmtc", "fmtd", "fmte", "fmtf"
97: };
98:
99: static char *reg_name[32] = {
100: "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
101: "ta0", "ta1", "ta2", "ta3", "t0", "t1", "t2", "t3",
102: "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
103: "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
104: };
105:
106: static char *c0_opname[64] = {
107: "c0op00","tlbr", "tlbwi", "c0op03","c0op04","c0op05","tlbwr", "c0op07",
108: "tlbp", "c0op11","c0op12","c0op13","c0op14","c0op15","c0op16","c0op17",
109: "rfe", "c0op21","c0op22","c0op23","c0op24","c0op25","c0op26","c0op27",
110: "eret","c0op31","c0op32","c0op33","c0op34","c0op35","c0op36","c0op37",
111: "c0op40","c0op41","c0op42","c0op43","c0op44","c0op45","c0op46","c0op47",
112: "c0op50","c0op51","c0op52","c0op53","c0op54","c0op55","c0op56","c0op57",
113: "c0op60","c0op61","c0op62","c0op63","c0op64","c0op65","c0op66","c0op67",
114: "c0op70","c0op71","c0op72","c0op73","c0op74","c0op75","c0op77","c0op77",
115: };
116:
117: static char *c0_reg[32] = {
118: "index","random","tlblo0","tlblo1","context","tlbmask","wired","c0r7",
119: "badvaddr","count","tlbhi","c0r11","sr","cause","epc", "prid",
120: "config","lladr","watchlo","watchhi","xcontext","c0r21","c0r22","c0r23",
121: "c0r24","c0r25","ecc","cacheerr","taglo","taghi","errepc","c0r31"
122: };
123:
124: int kdbpeek(void *);
125:
126: static int md_printins(int ins, int mdbdot);
127:
128: db_addr_t
129: db_disasm(loc, altfmt)
130: db_addr_t loc;
131: boolean_t altfmt;
132: {
133: if (md_printins(kdbpeek((void *)loc), loc)) {
134: loc += 4;
135: db_printsym(loc, DB_STGY_ANY, db_printf);
136: db_printf(":\t ");
137: md_printins(kdbpeek((void *)loc), loc);
138: }
139: loc += 4;
140: return loc;
141: }
142:
143: /* ARGSUSED */
144: static int
145: md_printins(int ins, int mdbdot)
146: {
147: InstFmt i;
148: int delay = 0;
149:
150: i.word = ins;
151:
152: switch (i.JType.op) {
153: case OP_SPECIAL:
154: if (i.word == 0) {
155: db_printf("nop");
156: break;
157: }
158: if (i.RType.func == OP_ADDU && i.RType.rt == 0) {
159: db_printf("move\t%s,%s",
160: reg_name[i.RType.rd],
161: reg_name[i.RType.rs]);
162: break;
163: }
164: db_printf("%s", spec_name[i.RType.func]);
165: switch (i.RType.func) {
166: case OP_SLL:
167: case OP_SRL:
168: case OP_SRA:
169: case OP_DSLL:
170: case OP_DSRL:
171: case OP_DSRA:
172: case OP_DSLL32:
173: case OP_DSRL32:
174: case OP_DSRA32:
175: db_printf("\t%s,%s,%d",
176: reg_name[i.RType.rd],
177: reg_name[i.RType.rt],
178: i.RType.shamt);
179: break;
180:
181: case OP_SLLV:
182: case OP_SRLV:
183: case OP_SRAV:
184: case OP_DSLLV:
185: case OP_DSRLV:
186: case OP_DSRAV:
187: db_printf("\t%s,%s,%s",
188: reg_name[i.RType.rd],
189: reg_name[i.RType.rt],
190: reg_name[i.RType.rs]);
191: break;
192:
193: case OP_MFHI:
194: case OP_MFLO:
195: db_printf("\t%s", reg_name[i.RType.rd]);
196: break;
197:
198: case OP_JR:
199: case OP_JALR:
200: delay = 1;
201: /* FALLTHROUGH */
202: case OP_MTLO:
203: case OP_MTHI:
204: db_printf("\t%s", reg_name[i.RType.rs]);
205: break;
206:
207: case OP_MULT:
208: case OP_MULTU:
209: case OP_DMULT:
210: case OP_DMULTU:
211: case OP_DIV:
212: case OP_DIVU:
213: case OP_DDIV:
214: case OP_DDIVU:
215: db_printf("\t%s,%s",
216: reg_name[i.RType.rs],
217: reg_name[i.RType.rt]);
218: break;
219:
220: case OP_SYSCALL:
221: case OP_SYNC:
222: break;
223:
224: case OP_BREAK:
225: db_printf("\t%d", (i.RType.rs << 5) | i.RType.rt);
226: break;
227:
228: default:
229: db_printf("\t%s,%s,%s",
230: reg_name[i.RType.rd],
231: reg_name[i.RType.rs],
232: reg_name[i.RType.rt]);
233: };
234: break;
235:
236: case OP_BCOND:
237: db_printf("%s\t%s,", bcond_name[i.IType.rt],
238: reg_name[i.IType.rs]);
239: goto pr_displ;
240:
241: case OP_BLEZ:
242: case OP_BLEZL:
243: case OP_BGTZ:
244: case OP_BGTZL:
245: db_printf("%s\t%s,", op_name[i.IType.op],
246: reg_name[i.IType.rs]);
247: goto pr_displ;
248:
249: case OP_BEQ:
250: case OP_BEQL:
251: if (i.IType.rs == 0 && i.IType.rt == 0) {
252: db_printf("b\t");
253: goto pr_displ;
254: }
255: /* FALLTHROUGH */
256: case OP_BNE:
257: case OP_BNEL:
258: db_printf("%s\t%s,%s,", op_name[i.IType.op],
259: reg_name[i.IType.rs],
260: reg_name[i.IType.rt]);
261: pr_displ:
262: delay = 1;
263: db_printsym(mdbdot + 4 + ((short)i.IType.imm << 2),
264: DB_STGY_PROC, db_printf);
265: break;
266:
267: case OP_COP0:
268: switch (i.RType.rs) {
269: case OP_BCx:
270: case OP_BCy:
271: db_printf("bc0%c\t",
272: "ft"[i.RType.rt & COPz_BC_TF_MASK]);
273: goto pr_displ;
274:
275: case OP_MT:
276: db_printf("mtc0\t%s,%s",
277: reg_name[i.RType.rt],
278: c0_reg[i.RType.rd]);
279: break;
280:
281: case OP_DMT:
282: db_printf("dmtc0\t%s,%s",
283: reg_name[i.RType.rt],
284: c0_reg[i.RType.rd]);
285: break;
286:
287: case OP_MF:
288: db_printf("mfc0\t%s,%s",
289: reg_name[i.RType.rt],
290: c0_reg[i.RType.rd]);
291: break;
292:
293: case OP_DMF:
294: db_printf("dmfc0\t%s,%s",
295: reg_name[i.RType.rt],
296: c0_reg[i.RType.rd]);
297: break;
298:
299: default:
300: db_printf("%s", c0_opname[i.FRType.func]);
301: };
302: break;
303:
304: case OP_COP1:
305: switch (i.RType.rs) {
306: case OP_BCx:
307: case OP_BCy:
308: db_printf("bc1%c\t",
309: "ft"[i.RType.rt & COPz_BC_TF_MASK]);
310: goto pr_displ;
311:
312: case OP_MT:
313: db_printf("mtc1\t%s,f%d",
314: reg_name[i.RType.rt],
315: i.RType.rd);
316: break;
317:
318: case OP_MF:
319: db_printf("mfc1\t%s,f%d",
320: reg_name[i.RType.rt],
321: i.RType.rd);
322: break;
323:
324: case OP_CT:
325: db_printf("ctc1\t%s,f%d",
326: reg_name[i.RType.rt],
327: i.RType.rd);
328: break;
329:
330: case OP_CF:
331: db_printf("cfc1\t%s,f%d",
332: reg_name[i.RType.rt],
333: i.RType.rd);
334: break;
335:
336: default:
337: db_printf("%s.%s\tf%d,f%d,f%d",
338: cop1_name[i.FRType.func],
339: fmt_name[i.FRType.fmt],
340: i.FRType.fd, i.FRType.fs, i.FRType.ft);
341: };
342: break;
343:
344: case OP_J:
345: case OP_JAL:
346: db_printf("%s\t", op_name[i.JType.op]);
347: db_printsym((mdbdot & ~0x0fffffffL) | (i.JType.target << 2),
348: DB_STGY_PROC, db_printf);
349: delay = 1;
350: break;
351:
352: case OP_LWC1:
353: case OP_SWC1:
354: db_printf("%s\tf%d,", op_name[i.IType.op],
355: i.IType.rt);
356: goto loadstore;
357:
358: case OP_LB:
359: case OP_LH:
360: case OP_LW:
361: case OP_LD:
362: case OP_LBU:
363: case OP_LHU:
364: case OP_LWU:
365: case OP_SB:
366: case OP_SH:
367: case OP_SW:
368: case OP_SD:
369: db_printf("%s\t%s,", op_name[i.IType.op],
370: reg_name[i.IType.rt]);
371: loadstore:
372: db_printf("%d(%s)", (short)i.IType.imm,
373: reg_name[i.IType.rs]);
374: break;
375:
376: case OP_ORI:
377: case OP_XORI:
378: if (i.IType.rs == 0) {
379: db_printf("li\t%s,0x%x",
380: reg_name[i.IType.rt],
381: i.IType.imm);
382: break;
383: }
384: /* FALLTHROUGH */
385: case OP_ANDI:
386: db_printf("%s\t%s,%s,0x%x", op_name[i.IType.op],
387: reg_name[i.IType.rt],
388: reg_name[i.IType.rs],
389: i.IType.imm);
390: break;
391:
392: case OP_LUI:
393: db_printf("%s\t%s,0x%x", op_name[i.IType.op],
394: reg_name[i.IType.rt],
395: i.IType.imm);
396: break;
397:
398: case OP_CACHE:
399: db_printf("%s\t0x%x,%d(%s)", op_name[i.IType.op],
400: i.IType.rt,
401: (short)i.IType.imm,
402: reg_name[i.IType.rs]);
403: break;
404:
405: case OP_ADDI:
406: case OP_DADDI:
407: case OP_ADDIU:
408: case OP_DADDIU:
409: if (i.IType.rs == 0) {
410: db_printf("li\t%s,%d",
411: reg_name[i.IType.rt],
412: (short)i.IType.imm);
413: break;
414: }
415: /* FALLTHROUGH */
416: default:
417: db_printf("%s\t%s,%s,%d", op_name[i.IType.op],
418: reg_name[i.IType.rt],
419: reg_name[i.IType.rs],
420: (short)i.IType.imm);
421: }
422: db_printf("\n");
423: return(delay);
424: }
CVSweb