Annotation of sys/arch/mips64/mips64/db_disasm.c, Revision 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