[BACK]Return to db_disasm.c CVS log [TXT][DIR] Up to [local] / sys / arch / powerpc / ddb

Annotation of sys/arch/powerpc/ddb/db_disasm.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: db_disasm.c,v 1.14 2003/12/21 15:17:29 miod Exp $     */
        !             2: /*
        !             3:  * Copyright (c) 1996, 2001, 2003 Dale Rahn. All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  *
        !            14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            16:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            17:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            18:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            19:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            20:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            21:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            22:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            23:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            24:  */
        !            25:
        !            26: #include <sys/param.h>
        !            27: #include <sys/proc.h>
        !            28: #include <sys/systm.h>
        !            29:
        !            30: #include <machine/db_machdep.h>
        !            31:
        !            32: #include <ddb/db_access.h>
        !            33: #include <ddb/db_sym.h>
        !            34: #include <ddb/db_variables.h>
        !            35: #include <ddb/db_interface.h>
        !            36: #include <ddb/db_output.h>
        !            37:
        !            38: enum opf {
        !            39:        Opf_INVALID,
        !            40:        Opf_A,
        !            41:        Opf_A0,
        !            42:        Opf_B,
        !            43:        Opf_BI,
        !            44:        Opf_BI1,
        !            45:        Opf_BO,
        !            46:        Opf_CRM,
        !            47:        Opf_D,
        !            48:        Opf_S,
        !            49:        Opf_FM,
        !            50:        Opf_LK,
        !            51:        Opf_RC,
        !            52:        Opf_AA,
        !            53:        Opf_LI,
        !            54:        Opf_OE,
        !            55:        Opf_SR,
        !            56:        Opf_TO,
        !            57:        Opf_SIMM,
        !            58:        Opf_UIMM,
        !            59:        Opf_d,
        !            60:        Opf_crbA,
        !            61:        Opf_crbB,
        !            62:        Opf_crbD,
        !            63:        Opf_crfD,
        !            64:        Opf_crfS,
        !            65:        Opf_spr,
        !            66:        Opf_tbr,
        !            67:
        !            68:        Opf_BD,
        !            69:        Opf_C,
        !            70:
        !            71:        Opf_NB,
        !            72:
        !            73:        Opf_sh,
        !            74:        Opf_SH,
        !            75:        Opf_mb,
        !            76:        Opf_MB,
        !            77:        Opf_ME,
        !            78: };
        !            79:
        !            80:
        !            81: struct db_field {
        !            82:        char *name;
        !            83:        enum opf opf;
        !            84: } db_fields[] = {
        !            85:        { "A",          Opf_A },
        !            86:        { "A0",         Opf_A0 },
        !            87:        { "B",          Opf_B },
        !            88:        { "D",          Opf_D },
        !            89:        { "S",          Opf_S },
        !            90:        { "AA",         Opf_AA },
        !            91:        { "LI",         Opf_LI },
        !            92:        { "BD",         Opf_BD },
        !            93:        { "BI",         Opf_BI },
        !            94:        { "BI1",        Opf_BI1 },
        !            95:        { "BO",         Opf_BO },
        !            96:        { "CRM",        Opf_CRM },
        !            97:        { "FM",         Opf_FM },
        !            98:        { "LK",         Opf_LK },
        !            99:        { "MB",         Opf_MB },
        !           100:        { "ME",         Opf_ME },
        !           101:        { "NB",         Opf_NB },
        !           102:        { "OE",         Opf_OE },
        !           103:        { "RC",         Opf_RC },
        !           104:        { "SH",         Opf_SH },
        !           105:        { "SR",         Opf_SR },
        !           106:        { "TO",         Opf_TO },
        !           107:        { "SIMM",       Opf_SIMM },
        !           108:        { "UIMM",       Opf_UIMM },
        !           109:        { "crbA",       Opf_crbA },
        !           110:        { "crbB",       Opf_crbB },
        !           111:        { "crbD",       Opf_crbD },
        !           112:        { "crfD",       Opf_crfD },
        !           113:        { "crfS",       Opf_crfS },
        !           114:        { "d",          Opf_d },
        !           115:        { "mb",         Opf_mb },
        !           116:        { "sh",         Opf_sh },
        !           117:        { "spr",        Opf_spr },
        !           118:        { "tbr",        Opf_tbr },
        !           119:        { NULL,         0 }
        !           120: };
        !           121:
        !           122: struct opcode {
        !           123:        char *name;
        !           124:        u_int32_t mask;
        !           125:        u_int32_t code;
        !           126:        char *decode_str;
        !           127: };
        !           128:
        !           129: typedef u_int32_t instr_t;
        !           130: typedef void (op_class_func) (u_int32_t addr, instr_t instr);
        !           131:
        !           132: u_int32_t extract_field(u_int32_t value, u_int32_t base, u_int32_t width);
        !           133: void disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
        !           134:     char *disasm_str, size_t bufsize);
        !           135: void disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
        !           136:     char *ppoutput, size_t bufsize);
        !           137: void dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr);
        !           138:
        !           139:
        !           140: op_class_func op_ill, op_base;
        !           141: op_class_func op_cl_x13, op_cl_x1e, op_cl_x1f;
        !           142: op_class_func op_cl_x3a, op_cl_x3b;
        !           143: op_class_func op_cl_x3e, op_cl_x3f;
        !           144:
        !           145: op_class_func *opcodes_base[] = {
        !           146: /*x00*/        op_ill,         op_ill,         op_base,        op_ill,
        !           147: /*x04*/        op_ill,         op_ill,         op_ill,         op_base,
        !           148: /*x08*/        op_base,        op_base,        op_base,        op_base,
        !           149: /*x0C*/        op_base,        op_base,        op_base/*XXX*/, op_base/*XXX*/,
        !           150: /*x10*/        op_base,        op_base,        op_base,        op_cl_x13,
        !           151: /*x14*/        op_base,        op_base,        op_ill,         op_base,
        !           152: /*x18*/        op_base,        op_base,        op_base,        op_base,
        !           153: /*x1C*/        op_base,        op_base,        op_cl_x1e,      op_cl_x1f,
        !           154: /*x20*/        op_base,        op_base,        op_base,        op_base,
        !           155: /*x24*/        op_base,        op_base,        op_base,        op_base,
        !           156: /*x28*/        op_base,        op_base,        op_base,        op_base,
        !           157: /*x2C*/        op_base,        op_base,        op_base,        op_base,
        !           158: /*x30*/        op_base,        op_base,        op_base,        op_base,
        !           159: /*x34*/        op_base,        op_base,        op_base,        op_base,
        !           160: /*x38*/        op_ill,         op_ill,         op_cl_x3a,      op_cl_x3b,
        !           161: /*x3C*/        op_ill,         op_ill,         op_cl_x3e,      op_cl_x3f
        !           162: };
        !           163:
        !           164:
        !           165: /* This table could be modified to make significant the "reserved" fields
        !           166:  * of the opcodes, But I didn't feel like it when typing in the table,
        !           167:  * I would recommend that this table be looked over for errors,
        !           168:  * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD)
        !           169:  * PowerPC Microprocessor Family: The Programming Environments
        !           170:  */
        !           171:
        !           172: const struct opcode opcodes[] = {
        !           173:        { "tdi",        0xfc000000, 0x08000000, " %{TO},%{A},%{SIMM}" },
        !           174:        { "twi",        0xfc000000, 0x0c000000, " %{TO},%{A},%{SIMM}" },
        !           175:
        !           176:        { "mulli",      0xfc000000, 0x1c000000, " %{D},%{A},%{SIMM}" },
        !           177:        { "subfic",     0xfc000000, 0x20000000, " %{D},%{A},%{SIMM}" },
        !           178:        { "cmpli",      0xff800000, 0x28000000, " %{A},%{UIMM}" },
        !           179:        { "cmpli",      0xfc400000, 0x28000000, " %{crfD}%{A}, %{UIMM}" },
        !           180:        { "cmpi",       0xff800000, 0x2c000000, " %{A},%{SIMM}"},
        !           181:        { "cmpi",       0xfc400000, 0x2c000000, " %{crfD}%{A},%{SIMM}" },
        !           182:        { "addic",      0xfc000000, 0x30000000, " %{D},%{A},%{SIMM}" },
        !           183:        { "addic.",     0xfc000000, 0x34000000, " %{D},%{A},%{SIMM}" },
        !           184:        { "addi",       0xfc000000, 0x38000000, " %{D},%{A0}%{SIMM}" },
        !           185:        { "addis",      0xfc000000, 0x3c000000, " %{D},%{A0}%{SIMM}" },
        !           186:        { "sc",         0xffffffff, 0x44000002, "" },
        !           187:        { "b",          0xfc000000, 0x40000000, "%{BO}%{LK}%{AA} %{BI}%{BD}" },
        !           188:        { "b",          0xfc000000, 0x48000000, "%{LK}%{AA} %{LI}" },
        !           189:
        !           190:        { "rlwimi",     0xfc000000, 0x50000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
        !           191:        { "rlwinm",     0xfc000000, 0x54000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
        !           192:        { "rlwnm",      0xfc000000, 0x5c000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
        !           193:
        !           194:        { "ori",        0xfc000000, 0x60000000, " %{A},%{S},%{UIMM}" },
        !           195:        { "oris",       0xfc000000, 0x64000000, " %{A},%{S},%{UIMM}" },
        !           196:        { "xori",       0xfc000000, 0x68000000, " %{A},%{S},%{UIMM}" },
        !           197:        { "xoris",      0xfc000000, 0x6c000000, " %{A},%{S},%{UIMM}" },
        !           198:
        !           199:        { "andi.",      0xfc000000, 0x70000000, " %{A},%{S},%{UIMM}" },
        !           200:        { "andis.",     0xfc000000, 0x74000000, " %{A},%{S},%{UIMM}" },
        !           201:
        !           202:        { "lwz",        0xfc000000, 0x80000000, " %{D},%{d}(%{A})" },
        !           203:        { "lwzu",       0xfc000000, 0x84000000, " %{D},%{d}(%{A})" },
        !           204:        { "lbz",        0xfc000000, 0x88000000, " %{D},%{d}(%{A})" },
        !           205:        { "lbzu",       0xfc000000, 0x8c000000, " %{D},%{d}(%{A})" },
        !           206:        { "stw",        0xfc000000, 0x90000000, " %{S},%{d}(%{A})" },
        !           207:        { "stwu",       0xfc000000, 0x94000000, " %{S},%{d}(%{A})" },
        !           208:        { "stb",        0xfc000000, 0x98000000, " %{S},%{d}(%{A})" },
        !           209:        { "stbu",       0xfc000000, 0x9c000000, " %{S},%{d}(%{A})" },
        !           210:
        !           211:        { "lhz",        0xfc000000, 0xa0000000, " %{D},%{d}(%{A})" },
        !           212:        { "lhzu",       0xfc000000, 0xa4000000, " %{D},%{d}(%{A})" },
        !           213:        { "lha",        0xfc000000, 0xa8000000, " %{D},%{d}(%{A})" },
        !           214:        { "lhau",       0xfc000000, 0xac000000, " %{D},%{d}(%{A})" },
        !           215:        { "sth",        0xfc000000, 0xb0000000, " %{S},%{d}(%{A})" },
        !           216:        { "sthu",       0xfc000000, 0xb4000000, " %{S},%{d}(%{A})" },
        !           217:        { "lmw",        0xfc000000, 0xb8000000, " %{D},%{d}(%{A})" },
        !           218:        { "stmw",       0xfc000000, 0xbc000000, " %{S},%{d}(%{A})" },
        !           219:
        !           220:        { "lfs",        0xfc000000, 0xc0000000, " %{D},%{d}(%{A})" },
        !           221:        { "lfsu",       0xfc000000, 0xc4000000, " %{D},%{d}(%{A})" },
        !           222:        { "lfd",        0xfc000000, 0xc8000000, " %{D},%{d}(%{A})" },
        !           223:        { "lfdu",       0xfc000000, 0xcc000000, " %{D},%{d}(%{A})" },
        !           224:
        !           225:        { "stfs",       0xfc000000, 0xd0000000, " %{S},%{d}(%{A})" },
        !           226:        { "stfsu",      0xfc000000, 0xd4000000, " %{S},%{d}(%{A})" },
        !           227:        { "stfd",       0xfc000000, 0xd8000000, " %{S},%{d}(%{A})" },
        !           228:        { "stfdu",      0xfc000000, 0xdc000000, " %{S},%{d}(%{A})" },
        !           229:        { "",           0x0,            0x0, "" }
        !           230:
        !           231: };
        !           232:
        !           233: /* 13 * 4 = 4c */
        !           234: const struct opcode opcodes_13[] = {
        !           235: /* 0x13 << 2 */
        !           236:        { "mcrf",       0xfc0007fe, 0x4c000000, " %{crfD},%{crfS}" },
        !           237:        { "b",/*bclr*/  0xfc0007fe, 0x4c000020, "%{BO}lr%{LK} %{BI1}" },
        !           238:        { "crnor",      0xfc0007fe, 0x4c000042, " %{crbD},%{crbA},%{crbB}" },
        !           239:        { "rfi",        0xfc0007fe, 0x4c000064, "" },
        !           240:        { "crandc",     0xfc0007fe, 0x4c000102, " %{crbD},%{crbA},%{crbB}" },
        !           241:        { "isync",      0xfc0007fe, 0x4c00012c, "" },
        !           242:        { "crxor",      0xfc0007fe, 0x4c000182, " %{crbD},%{crbA},%{crbB}" },
        !           243:        { "crnand",     0xfc0007fe, 0x4c0001c2, " %{crbD},%{crbA},%{crbB}" },
        !           244:        { "crand",      0xfc0007fe, 0x4c000202, " %{crbD},%{crbA},%{crbB}" },
        !           245:        { "creqv",      0xfc0007fe, 0x4c000242, " %{crbD},%{crbA},%{crbB}" },
        !           246:        { "crorc",      0xfc0007fe, 0x4c000342, " %{crbD},%{crbA},%{crbB}" },
        !           247:        { "cror",       0xfc0007fe, 0x4c000382, " %{crbD},%{crbA},%{crbB}" },
        !           248:        { "b"/*bcctr*/, 0xfc0007fe, 0x4c000420, "%{BO}ctr%{LK} %{BI1}" },
        !           249:        { "",           0x0,            0x0, "" }
        !           250: };
        !           251:
        !           252: /* 1e * 4 = 78 */
        !           253: const struct opcode opcodes_1e[] = {
        !           254:        { "rldicl",     0xfc00001c, 0x78000000, " %{A},%{S},%{sh},%{mb}" },
        !           255:        { "rldicr",     0xfc00001c, 0x78000004, " %{A},%{S},%{sh},%{mb}" },
        !           256:        { "rldic",      0xfc00001c, 0x78000008, " %{A},%{S},%{sh},%{mb}" },
        !           257:        { "rldimi",     0xfc00001c, 0x7800000c, " %{A},%{S},%{sh},%{mb}" },
        !           258:        { "rldcl",      0xfc00003e, 0x78000010, " %{A},%{S},%{B},%{mb}" },
        !           259:        { "rldcr",      0xfc00003e, 0x78000012, " %{A},%{S},%{B},%{mb}" },
        !           260:        { "",           0x0,            0x0, "" }
        !           261: };
        !           262:
        !           263: /* 1f * 4 = 7c */
        !           264: const struct opcode opcodes_1f[] = {
        !           265: /* 1f << 2 */
        !           266:        { "cmpd",       0xfc2007fe, 0x7c200000, " %{crfD}%{A},%{B}" },
        !           267:        { "cmpw",       0xfc2007fe, 0x7c000000, " %{crfD}%{A},%{B}" },
        !           268:        { "tw",         0xfc0007fe, 0x7c000008, " %{TO},%{A},%{B}" },
        !           269:        { "subfc",      0xfc0003fe, 0x7c000010, "%{OE}%{RC} %{D},%{A},%{B}" },
        !           270:        { "mulhdu",     0xfc0007fe, 0x7c000012, "%{RC} %{D},%{A},%{B}" },
        !           271:        { "addc",       0xfc0003fe, 0x7c000014, "%{OE}%{RC} %{D},%{A},%{B}" },
        !           272:        { "mulhwu",     0xfc0007fe, 0x7c000016, "%{RC} %{D},%{A},%{B}" },
        !           273:
        !           274:        { "mfcr",       0xfc0007fe, 0x7c000026, " %{D}" },
        !           275:        { "lwarx",      0xfc0007fe, 0x7c000028, " %{D},%{A0}%{B}" },
        !           276:        { "ldx",        0xfc0007fe, 0x7c00002a, " %{D},%{A0}%{B}" },
        !           277:        { "lwzx",       0xfc0007fe, 0x7c00002e, " %{D},%{A0}%{B}" },
        !           278:        { "slw",        0xfc0007fe, 0x7c000030, "%{RC} %{A},%{S},%{B}" },
        !           279:        { "cntlzw",     0xfc0007fe, 0x7c000034, "%{RC} %{A},%{S}" },
        !           280:        { "sld",        0xfc0007fe, 0x7c000036, "%{RC} %{A},%{S},%{B}" },
        !           281:        { "and",        0xfc0007fe, 0x7c000038, "%{RC} %{A},%{S},%{B}" },
        !           282:        { "cmpld",      0xfc2007fe, 0x7c200040, " %{crfD}%{A},%{B}" },
        !           283:        { "cmplw",      0xfc2007fe, 0x7c000040, " %{crfD}%{A},%{B}" },
        !           284:        { "subf",       0xfc0003fe, 0x7c000050, "%{OE}%{RC} %{D},%{A},%{B}" },
        !           285:        { "ldux",       0xfc0007fe, 0x7c00006a, " %{D},%{A},%{B}" },
        !           286:        { "dcbst",      0xfc0007fe, 0x7c00006c, " %{A0}%{B}" },
        !           287:        { "lwzux",      0xfc0007fe, 0x7c00006e, " %{D},%{A},%{B}" },
        !           288:        { "cntlzd",     0xfc0007fe, 0x7c000074, "%{RC} %{A},%{S}" },
        !           289:        { "andc",       0xfc0007fe, 0x7c000078, "%{RC} %{A},%{S},%{B}" },
        !           290:        { "td",         0xfc0007fe, 0x7c000088, " %{TO},%{A},%{B}" },
        !           291:        { "mulhd",      0xfc0007fe, 0x7c000092, "%{RC} %{D},%{A},%{B}" },
        !           292:        { "mulhw",      0xfc0007fe, 0x7c000096, "%{RC} %{D},%{A},%{B}" },
        !           293:        { "mfmsr",      0xfc0007fe, 0x7c0000a6, " %{D}" },
        !           294:        { "ldarx",      0xfc0007fe, 0x7c0000a8, " %{D},%{A0}%{B}" },
        !           295:        { "dcbf",       0xfc0007fe, 0x7c0000ac, " %{A0}%{B}" },
        !           296:        { "lbzx",       0xfc0007fe, 0x7c0000ae, " %{D},%{A0}%{B}" },
        !           297:        { "neg",        0xfc0003fe, 0x7c0000d0, "%{OE}%{RC} %{D},%{A}" },
        !           298:        { "lbzux",      0xfc0007fe, 0x7c0000ee, " %{D},%{A},%{B}" },
        !           299:        { "nor",        0xfc0007fe, 0x7c0000f8, "%{RC} %{A},%{S}" },
        !           300:        { "subfe",      0xfc0003fe, 0x7c000110, "%{OE}%{RC} %{D},%{A}" },
        !           301:        { "adde",       0xfc0003fe, 0x7c000114, "%{OE}%{RC} %{D},%{A}" },
        !           302:        { "mtcrf",      0xfc0007fe, 0x7c000120, " %{S},%{CRM}" },
        !           303:        { "mtmsr",      0xfc0007fe, 0x7c000124, " %{S}" },
        !           304:        { "stdx",       0xfc0007fe, 0x7c00012a, " %{S},%{A0}%{B}" },
        !           305:        { "stwcx.",     0xfc0007ff, 0x7c00012d, " %{S},%{A},%{B}" },
        !           306:        { "stwx",       0xfc0007fe, 0x7c00012e, " %{S},%{A},%{B}" },
        !           307:        { "stdux",      0xfc0007fe, 0x7c00016a, " %{S},%{A},%{B}" },
        !           308:        { "stwux",      0xfc0007fe, 0x7c00016e, " %{S},%{A},%{B}" },
        !           309:        { "subfze",     0xfc0003fe, 0x7c000190, "%{OE}%{RC} %{D},%{A}" },
        !           310:        { "addze",      0xfc0003fe, 0x7c000194, "%{OE}%{RC} %{D},%{A}" },
        !           311:        { "mtsr",       0xfc0007fe, 0x7c0001a4, " %{SR},%{S}" },
        !           312:        { "stdcx.",     0xfc0007ff, 0x7c0001ad, " %{S},%{A0}%{B}" },
        !           313:        { "stbx",       0xfc0007fe, 0x7c0001ae, " %{S},%{A0}%{B}" },
        !           314:        { "subfme",     0xfc0003fe, 0x7c0001d0, "%{OE}%{RC} %{D},%{A}" },
        !           315:        { "mulld",      0xfc0003fe, 0x7c0001d2, "%{OE}%{RC} %{D},%{A},%{B}" },
        !           316:        { "addme",      0xfc0003fe, 0x7c0001d4, "%{OE}%{RC} %{D},%{A}" },
        !           317:        { "mullw",      0xfc0003fe, 0x7c0001d6, "%{OE}%{RC} %{D},%{A},%{B}" },
        !           318:        { "mtsrin",     0xfc0007fe, 0x7c0001e4, " %{S},%{B}" },
        !           319:        { "dcbtst",     0xfc0007fe, 0x7c0001ec, " %{A0}%{B}" },
        !           320:        { "stbux",      0xfc0007fe, 0x7c0001ee, " %{S},%{A},%{B}" },
        !           321:        { "add",        0xfc0003fe, 0x7c000214, "" },
        !           322:        { "dcbt",       0xfc0007fe, 0x7c00022c, " %{A0}%{B}" },
        !           323:        { "lhzx",       0xfc0007ff, 0x7c00022e, " %{D},%{A0}%{B}" },
        !           324:        { "eqv",        0xfc0007fe, 0x7c000238, "%{RC} %{A},%{S},%{B}" },
        !           325:        { "tlbie",      0xfc0007fe, 0x7c000264, " %{B}" },
        !           326:        { "eciwx",      0xfc0007fe, 0x7c00026c, " %{D},%{A0}%{B}" },
        !           327:        { "lhzux",      0xfc0007fe, 0x7c00026e, " %{D},%{A},%{B}" },
        !           328:        { "xor",        0xfc0007fe, 0x7c000278, "%{RC} %{A},%{S},%{B}" },
        !           329:        { "mfspr",      0xfc0007fe, 0x7c0002a6, " %{D},%{spr}" },
        !           330:        { "lwax",       0xfc0007fe, 0x7c0002aa, " %{D},%{A0}%{B}" },
        !           331:        { "lhax",       0xfc0007fe, 0x7c0002ae, " %{D},%{A},%{B}" },
        !           332:        { "tlbia",      0xfc0007fe, 0x7c0002e4, "" },
        !           333:        { "mftb",       0xfc0007fe, 0x7c0002e6, " %{D},%{tbr}" },
        !           334:        { "lwaux",      0xfc0007fe, 0x7c0002ea, " %{D},%{A},%{B}" },
        !           335:        { "lhaux",      0xfc0007fe, 0x7c0002ee, " %{D},%{A},%{B}" },
        !           336:        { "sthx",       0xfc0007fe, 0x7c00032e, " %{S},%{A0}%{B}" },
        !           337:        { "orc",        0xfc0007fe, 0x7c000338, "%{RC} %{A},%{S},%{B}" },
        !           338:        { "ecowx",      0xfc0007fe, 0x7c00036c, "%{RC} %{S},%{A0}%{B}" },
        !           339:        { "slbie",      0xfc0007fc, 0x7c000364, " %{B}" },
        !           340:        { "sthux",      0xfc0007fe, 0x7c00036e, " %{S},%{A0}%{B}" },
        !           341:        { "or",         0xfc0007fe, 0x7c000378, "%{RC} %{A},%{S},%{B}" },
        !           342:        { "divdu",      0xfc0003fe, 0x7c000392, "%{OE}%{RC} %{S},%{A},%{B}" },
        !           343:        { "divwu",      0xfc0003fe, 0x7c000396, "%{OE}%{RC} %{S},%{A},%{B}" },
        !           344:        { "mtspr",      0xfc0007fe, 0x7c0003a6, " %{spr},%{S}" },
        !           345:        { "dcbi",       0xfc0007fe, 0x7c0003ac, " %{A0}%{B}" },
        !           346:        { "nand",       0xfc0007fe, 0x7c0003b8, "%{RC} %{A},%{S},%{B}" },
        !           347:        { "divd",       0xfc0003fe, 0x7c0003d2, "%{OE}%{RC} %{S},%{A},%{B}" },
        !           348:        { "divw",       0xfc0003fe, 0x7c0003d6, "%{OE}%{RC} %{S},%{A},%{B}" },
        !           349:        { "slbia",      0xfc0003fe, 0x7c0003e4, "%{OE}%{RC} %{S},%{A},%{B}" },
        !           350:        { "mcrxr",      0xfc0007fe, 0x7c000400, "crfD1" },
        !           351:        { "lswx",       0xfc0007fe, 0x7c00042a, " %{D},%{A0}%{B}" },
        !           352:        { "lwbrx",      0xfc0007fe, 0x7c00042c, " %{D},%{A0}%{B}" },
        !           353:        { "lfsx",       0xfc0007fe, 0x7c00042e, " %{D},%{A},%{B}" },
        !           354:        { "srw",        0xfc0007fe, 0x7c000430, "%{RC} %{A},%{S},%{B}" },
        !           355:        { "srd",        0xfc0007fe, 0x7c000436, "%{RC} %{A},%{S},%{B}" },
        !           356:        { "tlbsync",    0xffffffff, 0x7c00046c, "" },
        !           357:        { "lfsux",      0xfc0007fe, 0x7c00046e, " %{D},%{A},%{B}" },
        !           358:        { "mfsr",       0xfc0007fe, 0x7c0004a6, " %{D},%{SR}" },
        !           359:        { "lswi",       0xfc0007fe, 0x7c0004aa, " %{D},%{A},%{NB}" },
        !           360:        { "sync",       0xfc0007fe, 0x7c0004ac, "" },
        !           361:        { "lfdx",       0xfc0007fe, 0x7c0004ae, " %{D},%{A},%{B}" },
        !           362:        { "lfdux",      0xfc0007fe, 0x7c0004ee, " %{D},%{A},%{B}" },
        !           363:        { "mfsrin",     0xfc0007fe, 0x7c000526, "" },
        !           364:        { "stswx",      0xfc0007fe, 0x7c00052a, " %{S},%{A0}%{B}" },
        !           365:        { "stwbrx",     0xfc0007fe, 0x7c00052c, " %{S},%{A0}%{B}" },
        !           366:        { "stfsx",      0xfc0007fe, 0x7c00052e, " %{S},%{A0}%{B}" },
        !           367:        { "stfsux",     0xfc0007fe, 0x7c00056e, " %{S},%{A},%{B}" },
        !           368:        { "stswi",      0xfc0007fe, 0x7c0005aa, "%{S},%{A0}%{NB}" },
        !           369:        { "stfdx",      0xfc0007fe, 0x7c0005ae, " %{S},%{A0}%{B}" },
        !           370:        { "stfdux",     0xfc0007fe, 0x7c0005ee, " %{S},%{A},%{B}" },
        !           371:        { "lhbrx",      0xfc0007fe, 0x7c00062c, " %{D},%{A0}%{B}" },
        !           372:        { "sraw",       0xfc0007fe, 0x7c000630, " %{A},%{S},%{B}" },
        !           373:        { "srad",       0xfc0007fe, 0x7c000634, "%{RC} %{A},%{S},%{B}" },
        !           374:        { "srawi",      0xfc0007fe, 0x7c000670, "%{RC} %{A},%{SH}" },
        !           375:        { "sradi",      0xfc0007fc, 0x7c000674, " %{A},%{S},%{sh}" },
        !           376:        { "eieio",      0xfc0007fe, 0x7c0006ac, "" }, /* MASK? */
        !           377:        { "sthbrx",     0xfc0007fe, 0x7c00072c, " %{S},%{A0}%{B}" },
        !           378:        { "extsh",      0xfc0007fe, 0x7c000734, "%{RC} %{A},%{S}" },
        !           379:        { "extsb",      0xfc0007fe, 0x7c000774, "%{RC} %{A},%{S}" },
        !           380:        { "icbi",       0xfc0007fe, 0x7c0007ac, " %{A0}%{B}" },
        !           381:
        !           382:        { "stfiwx",     0xfc0007fe, 0x7c0007ae, " %{S},%{A0}%{B}" },
        !           383:        { "extsw",      0xfc0007fe, 0x7c0007b4, "%{RC} %{A},%{S}" },
        !           384:        { "dcbz",       0xfc0007fe, 0x7c0007ec, " %{A0}%{B}" },
        !           385:        { "",           0x0,            0x0, 0, }
        !           386: };
        !           387:
        !           388: /* 3a * 4 = e8 */
        !           389: const struct opcode opcodes_3a[] = {
        !           390:        { "ld",         0xfc000003, 0xe8000000, " %{D},${ds}${A}" },
        !           391:        { "ldu",        0xfc000003, 0xe8000001, " %{D},${ds}${A}" },
        !           392:        { "lwa",        0xfc000003, 0xe8000002, " %{D},${ds}${A}" },
        !           393:        { "",           0x0,            0x0, "" }
        !           394: };
        !           395:
        !           396: /* 3b * 4 = ec */
        !           397: const struct opcode opcodes_3b[] = {
        !           398:        { "fdivs",      0xfc00003e, 0xec000024, "%{RC} f%{D},f%{A},f%{B}" },
        !           399:        { "fsubs",      0xfc00003e, 0xec000028, "%{RC} f%{D},f%{A},f%{B}" },
        !           400:
        !           401:        { "fadds",      0xfc00003e, 0xec00002a, "%{RC} f%{D},f%{A},f%{B}" },
        !           402:        { "fsqrts",     0xfc00003e, 0xec00002c, "" },
        !           403:        { "fres",       0xfc00003e, 0xec000030, "" },
        !           404:        { "fmuls",      0xfc00003e, 0xec000032, "%{RC} f%{D},f%{A},f%{C}" },
        !           405:        { "fmsubs",     0xfc00003e, 0xec000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           406:        { "fmadds",     0xfc00003e, 0xec00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           407:        { "fnmsubs",    0xfc00003e, 0xec00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           408:        { "fnmadds",    0xfc00003e, 0xec00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           409:        { "",           0x0,            0x0, "" }
        !           410: };
        !           411:
        !           412: /* 3e * 4 = f8 */
        !           413: const struct opcode opcodes_3e[] = {
        !           414:        { "std",        0xfc000003, 0xf8000000, " %{D},${ds}${A}" },
        !           415:        { "stdu",       0xfc000003, 0xf8000001, " %{D},${ds}${A}" },
        !           416:        { "",           0x0,            0x0, "" }
        !           417: };
        !           418:
        !           419: /* 3f * 4 = fc */
        !           420: const struct opcode opcodes_3f[] = {
        !           421:        { "fcmpu",      0xfc0007fe, 0xfc000000, " %{crfD},f%{A},f%{B}" },
        !           422:        { "frsp",       0xfc0007fe, 0xfc000018, "%{RC} f%{D},f%{B}" },
        !           423:        { "fctiw",      0xfc0007fe, 0xfc00001c, "%{RC} f%{D},f%{B}" },
        !           424:        { "fctiwz",     0xfc0007fe, 0xfc00001e, "%{RC} f%{D},f%{B}" },
        !           425:
        !           426:        { "fdiv",       0xfc00003e, 0xfc000024, "%{RC} f%{D},f%{A},f%{B}" },
        !           427:        { "fsub",       0xfc00003e, 0xfc000028, "%{RC} f%{D},f%{A},f%{B}" },
        !           428:        { "fadd",       0xfc00003e, 0xfc00002a, "%{RC} f%{D},f%{A},f%{B}" },
        !           429:        { "fsqrt",      0xfc00003e, 0xfc00002c, "%{RC} f%{D},f%{B}" },
        !           430:        { "fsel",       0xfc00003e, 0xfc00002e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           431:        { "fmul",       0xfc00003e, 0xfc000032, "%{RC} f%{D},f%{A},f%{C}" },
        !           432:        { "frsqrte",    0xfc00003e, 0xfc000034, "%{RC} f%{D},f%{B}" },
        !           433:        { "fmsub",      0xfc00003e, 0xfc000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           434:        { "fmadd",      0xfc00003e, 0xfc00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           435:        { "fnmsub",     0xfc00003e, 0xfc00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           436:        { "fnmadd",     0xfc00003e, 0xfc00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
        !           437:
        !           438:        { "fcmpo",      0xfc0007fe, 0xfc000040, "%{RC} f%{D},f%{A},f%{C}" },
        !           439:        { "mtfsb1",     0xfc0007fe, 0xfc00004c, "%{RC} f%{D},f%{A},f%{C}" },
        !           440:        { "fneg",       0xfc0007fe, 0xfc000050, "%{RC} f%{D},f%{A},f%{C}" },
        !           441:        { "mcrfs",      0xfc0007fe, 0xfc000080, "%{RC} f%{D},f%{A},f%{C}" },
        !           442:        { "mtfsb0",     0xfc0007fe, 0xfc00008c, "%{RC} %{crfD},f%{C}" },
        !           443:        { "fmr",        0xfc0007fe, 0xfc000090, "%{RC} f%{D},f%{B}" },
        !           444:        { "mtfsfi",     0xfc0007fe, 0xfc00010c, "%{RC} %{crfD},f%{C},%{IMM}" },
        !           445:
        !           446:        { "fnabs",      0xfc0007fe, 0xfc000110, "%{RC} f%{D},f%{B}" },
        !           447:        { "fabs",       0xfc0007fe, 0xfc000210, "%{RC} f%{D},f%{B}" },
        !           448:        { "mffs",       0xfc0007fe, 0xfc00048e, "%{RC} f%{D},f%{B}" },
        !           449:        { "mtfsf",      0xfc0007fe, 0xfc00058e, "%{RC} %{FM},f%{B}" },
        !           450:        { "fctid",      0xfc0007fe, 0xfc00065c, "%{RC} f%{D},f%{B}" },
        !           451:        { "fctidz",     0xfc0007fe, 0xfc00065e, "%{RC} f%{D},f%{B}" },
        !           452:        { "fcfid",      0xfc0007fe, 0xfc00069c, "%{RC} f%{D},f%{B}" },
        !           453:        { "",           0x0,            0x0, "" }
        !           454: };
        !           455:
        !           456: void
        !           457: op_ill(u_int32_t addr, instr_t instr)
        !           458: {
        !           459:        db_printf("illegal instruction %x\n", instr);
        !           460: }
        !           461:
        !           462: /*
        !           463:  * Extracts bits out of an instruction opcode, base indicates the lsb
        !           464:  * to keep.
        !           465:  * Note that this uses the PowerPC bit number for base, MSb == 0
        !           466:  * because all of the documentation is written that way.
        !           467:  */
        !           468: u_int32_t
        !           469: extract_field(u_int32_t value, u_int32_t base, u_int32_t width)
        !           470: {
        !           471:        u_int32_t mask = (1 << width) - 1;
        !           472:        return ((value >> (31 - base)) & mask);
        !           473: }
        !           474:
        !           475: const struct opcode * search_op(const struct opcode *);
        !           476:
        !           477: char *db_BOBI_cond[] = {
        !           478:        "ge",
        !           479:        "le",
        !           480:        "ne",
        !           481:        "ns",
        !           482:        "lt",
        !           483:        "gt",
        !           484:        "eq",
        !           485:        "so"
        !           486: };
        !           487: /* what about prediction directions? */
        !           488: char *db_BO_op[] = {
        !           489:        "dnzf",
        !           490:        "dnzf-",
        !           491:        "dzf",
        !           492:        "dzf-",
        !           493:        "",
        !           494:        "",
        !           495:        "",
        !           496:        "",
        !           497:        "dnzt",
        !           498:        "dnzt-",
        !           499:        "dzt",
        !           500:        "dzt-",
        !           501:        "",
        !           502:        "",
        !           503:        "",
        !           504:        "",
        !           505:        "dnz",
        !           506:        "dnz",
        !           507:        "dz",
        !           508:        "dz",
        !           509:        "",
        !           510:        "",
        !           511:        "",
        !           512:        "",
        !           513:        "dnz",
        !           514:        "dnz",
        !           515:        "dz",
        !           516:        "dz",
        !           517:        "",
        !           518:        "",
        !           519:        "",
        !           520:        ""
        !           521: };
        !           522:
        !           523: char *BItbl[] = {
        !           524:        "", "gt", "eq", "so"
        !           525: };
        !           526:
        !           527: char BO_uses_tbl[32] = {
        !           528:        /* 0 */ 1,
        !           529:        /* 1 */ 1,
        !           530:        /* 2 */ 1,
        !           531:        /* 3 */ 1,
        !           532:        /* 4 */ 0,
        !           533:        /* 5 */ 0,
        !           534:        /* 6 */ 0, /* invalid */
        !           535:        /* 7 */ 0, /* invalid */
        !           536:        /* 8 */ 1,
        !           537:        /* 9 */ 1,
        !           538:        /* a */ 1,
        !           539:        /* b */ 1,
        !           540:        /* c */ 0,
        !           541:        /* d */ 0,
        !           542:        /* e */ 0, /* invalid */
        !           543:        /* f */ 1,
        !           544:        /* 10 */        1,
        !           545:        /* 11 */        1,
        !           546:        /* 12 */        1,
        !           547:        /* 13 */        1,
        !           548:        /* 14 */        1,
        !           549:        /* 15 */        0, /* invalid */
        !           550:        /* 16 */        0, /* invalid */
        !           551:        /* 17 */        0, /* invalid */
        !           552:        /* 18 */        0, /* invalid */
        !           553:        /* 19 */        0, /* invalid */
        !           554:        /* 1a */        0, /* invalid */
        !           555:        /* 1b */        0, /* invalid */
        !           556:        /* 1c */        0, /* invalid */
        !           557:        /* 1d */        0, /* invalid */
        !           558:        /* 1e */        0, /* invalid */
        !           559:        /* 1f */        0, /* invalid */
        !           560: };
        !           561:
        !           562: void
        !           563: disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
        !           564:     char *disasm_buf, size_t bufsize)
        !           565: {
        !           566:        char field [8];
        !           567:        char lbuf[50];
        !           568:        int i;
        !           569:        char *pfmt = *ppfmt;
        !           570:        enum opf opf;
        !           571:        char *name;
        !           572:        db_expr_t offset;
        !           573:
        !           574:        /* find field */
        !           575:        if (pfmt[0] != '%' || pfmt[1] != '{') {
        !           576:                printf("error in disasm fmt [%s]\n", pfmt);
        !           577:        }
        !           578:        pfmt = &pfmt[2];
        !           579:        for (i = 0;
        !           580:            pfmt[i] != '\0' && pfmt[i] != '}' && i < sizeof(field);
        !           581:            i++) {
        !           582:                field[i] = pfmt[i];
        !           583:        }
        !           584:        if (i == sizeof(field)) {
        !           585:                printf("error in disasm fmt [%s]\n", pfmt);
        !           586:                return;
        !           587:        }
        !           588:        field[i] = 0;
        !           589:        if (pfmt[i] == '\0') {
        !           590:                /* match following close paren { */
        !           591:                printf("disasm_process_field: missing } in [%s]\n", pfmt);
        !           592:        }
        !           593:        *ppfmt = &pfmt[i+1];
        !           594:        opf = Opf_INVALID;
        !           595:        for (i = 0; db_fields[i].name != NULL; i++) {
        !           596:                if (strcmp(db_fields[i].name, field) == 0) {
        !           597:                        opf = db_fields[i].opf;
        !           598:                        break;
        !           599:                }
        !           600:        }
        !           601:        switch (opf) {
        !           602:        case Opf_INVALID:
        !           603:                {
        !           604:                        printf("unable to find variable [%s]\n", field);
        !           605:                }
        !           606:        case Opf_A:
        !           607:                {
        !           608:                        u_int A;
        !           609:                        A = extract_field(instr, 15, 5);
        !           610:                        snprintf(lbuf, sizeof (lbuf), "r%d", A);
        !           611:                        strlcat (disasm_buf, lbuf, bufsize);
        !           612:                }
        !           613:                break;
        !           614:        case Opf_A0:
        !           615:                {
        !           616:                        u_int A;
        !           617:                        A = extract_field(instr, 15, 5);
        !           618:                        if (A != 0) {
        !           619:                                snprintf(lbuf, sizeof (lbuf), "r%d,", A);
        !           620:                                strlcat (disasm_buf, lbuf, bufsize);
        !           621:                        }
        !           622:                }
        !           623:                break;
        !           624:        case Opf_AA:
        !           625:                if (instr & 0x2) {
        !           626:                        strlcat (disasm_buf, "a", bufsize);
        !           627:                }
        !           628:                break;
        !           629:        case Opf_LI:
        !           630:                {
        !           631:                        u_int LI;
        !           632:                        LI = extract_field(instr, 29, 24);
        !           633:                        LI = LI << 2;
        !           634:                        if (LI & 0x02000000) {
        !           635:                                LI |= ~0x03ffffff;
        !           636:                        }
        !           637:                        if ((instr & (1 << 1)) == 0) {
        !           638:                                /* CHECK AA bit */
        !           639:                                LI = addr + LI;
        !           640:                        }
        !           641:                        db_find_sym_and_offset(LI, &name, &offset);
        !           642:                        if (name) {
        !           643:                                if (offset == 0) {
        !           644:                                        snprintf(lbuf, sizeof (lbuf),
        !           645:                                            "0x%x (%s)", LI, name);
        !           646:                                        strlcat (disasm_buf, lbuf, bufsize);
        !           647:                                } else {
        !           648:                                        snprintf(lbuf, sizeof (lbuf),
        !           649:                                            "0x%x (%s+0x%lx)", LI, name,
        !           650:                                            offset);
        !           651:                                        strlcat (disasm_buf, lbuf, bufsize);
        !           652:                                }
        !           653:                        } else {
        !           654:                                snprintf(lbuf, sizeof (lbuf), "0x%x", LI);
        !           655:                                strlcat (disasm_buf, lbuf, bufsize);
        !           656:                        }
        !           657:                }
        !           658:                break;
        !           659:        case Opf_B:
        !           660:                {
        !           661:                        u_int B;
        !           662:                        B = extract_field(instr, 20, 5);
        !           663:                        snprintf(lbuf, sizeof (lbuf), "r%d", B);
        !           664:                        strlcat (disasm_buf, lbuf, bufsize);
        !           665:                }
        !           666:                break;
        !           667:        case Opf_BD:
        !           668:                {
        !           669:                        u_int BD;
        !           670:                        BD = extract_field(instr, 29, 14);
        !           671:                        BD = BD << 2;
        !           672:                        if (BD & 0x00008000) {
        !           673:                                BD &= ~0x00007fff;
        !           674:                        }
        !           675:                        if ((instr & (1 << 1)) == 0) {
        !           676:                                /* CHECK AA bit */
        !           677:                                BD = addr + BD;
        !           678:                        }
        !           679:                        db_find_sym_and_offset(BD, &name, &offset);
        !           680:                        if (name) {
        !           681:                                if (offset == 0) {
        !           682:                                        snprintf(lbuf, sizeof (lbuf),
        !           683:                                            "0x%x (%s)", BD, name);
        !           684:                                        strlcat (disasm_buf, lbuf, bufsize);
        !           685:                                } else {
        !           686:                                        snprintf(lbuf, sizeof (lbuf),
        !           687:                                            "0x%x (%s+0x%lx)", BD, name, offset);
        !           688:                                        strlcat (disasm_buf, lbuf, bufsize);
        !           689:                                }
        !           690:                        } else {
        !           691:                                snprintf(lbuf, sizeof (lbuf), "0x%x", BD);
        !           692:                                strlcat (disasm_buf, lbuf, bufsize);
        !           693:                        }
        !           694:                }
        !           695:                break;
        !           696:        case Opf_BI1:
        !           697:        case Opf_BI:
        !           698:                {
        !           699:                        int BO, BI, cr, printcomma = 0;
        !           700:                        BO = extract_field(instr, 10, 5);
        !           701:                        BI = extract_field(instr, 15, 5);
        !           702:                        cr =  (BI >> 2) & 7;
        !           703:                        if (cr != 0) {
        !           704:                                snprintf(lbuf, sizeof (lbuf), "cr%d", cr);
        !           705:                                strlcat (disasm_buf, lbuf, bufsize);
        !           706:                                printcomma = 1;
        !           707:                        }
        !           708:                        if (BO_uses_tbl[BO]) {
        !           709:                                if ((cr != 0) && ((BI & 3) != 0) &&
        !           710:                                    BO_uses_tbl[BO] != 0)
        !           711:                                        strlcat (disasm_buf, "+", bufsize);
        !           712:
        !           713:                                snprintf(lbuf, sizeof (lbuf), "%s",
        !           714:                                    BItbl[BI & 3]);
        !           715:                                strlcat (disasm_buf, lbuf, bufsize);
        !           716:                                printcomma = 1;
        !           717:                        }
        !           718:                        if ((opf == Opf_BI) && printcomma)
        !           719:                                strlcat (disasm_buf, ",", bufsize);
        !           720:                }
        !           721:                break;
        !           722:        case Opf_BO:
        !           723:                {
        !           724:                        int BO, BI;
        !           725:                        BO = extract_field(instr, 10, 5);
        !           726:                        strlcat (disasm_buf, db_BO_op[BO], bufsize);
        !           727:                        if ((BO & 4) != 0) {
        !           728:                                BI = extract_field(instr, 15, 5);
        !           729:                                strlcat (disasm_buf,
        !           730:                                    db_BOBI_cond[(BI & 0x3)| (((BO & 8) >> 1))],
        !           731:                                    bufsize);
        !           732:
        !           733:                                if (BO & 1)
        !           734:                                        strlcat (disasm_buf, "-", bufsize);
        !           735:                        }
        !           736:                }
        !           737:                break;
        !           738:        case Opf_C:
        !           739:                {
        !           740:                        u_int C;
        !           741:                        C = extract_field(instr, 25, 5);
        !           742:                        snprintf(lbuf, sizeof (lbuf), "r%d, ", C);
        !           743:                        strlcat (disasm_buf, lbuf, bufsize);
        !           744:                }
        !           745:                break;
        !           746:        case Opf_CRM:
        !           747:                {
        !           748:                        u_int CRM;
        !           749:                        CRM = extract_field(instr, 19, 8);
        !           750:                        snprintf(lbuf, sizeof (lbuf), "0x%x", CRM);
        !           751:                        strlcat (disasm_buf, lbuf, bufsize);
        !           752:                }
        !           753:                break;
        !           754:        case Opf_FM:
        !           755:                {
        !           756:                        u_int FM;
        !           757:                        FM = extract_field(instr, 10, 8);
        !           758:                        snprintf(lbuf, sizeof (lbuf), "%d", FM);
        !           759:                        strlcat (disasm_buf, lbuf, bufsize);
        !           760:                }
        !           761:                break;
        !           762:        case Opf_LK:
        !           763:                if (instr & 0x1) {
        !           764:                        strlcat (disasm_buf, "l", bufsize);
        !           765:                }
        !           766:                break;
        !           767:        case Opf_MB:
        !           768:                {
        !           769:                        u_int MB;
        !           770:                        MB = extract_field(instr, 20, 5);
        !           771:                        snprintf(lbuf, sizeof (lbuf), "%d", MB);
        !           772:                        strlcat (disasm_buf, lbuf, bufsize);
        !           773:                }
        !           774:                break;
        !           775:        case Opf_ME:
        !           776:                {
        !           777:                        u_int ME;
        !           778:                        ME = extract_field(instr, 25, 5);
        !           779:                        snprintf(lbuf, sizeof (lbuf), "%d", ME);
        !           780:                        strlcat (disasm_buf, lbuf, bufsize);
        !           781:                }
        !           782:                break;
        !           783:        case Opf_NB:
        !           784:                {
        !           785:                        u_int NB;
        !           786:                        NB = extract_field(instr, 20, 5);
        !           787:                        if (NB == 0 ) {
        !           788:                                NB=32;
        !           789:                        }
        !           790:                        snprintf(lbuf, sizeof (lbuf), "%d", NB);
        !           791:                        strlcat (disasm_buf, lbuf, bufsize);
        !           792:                }
        !           793:                break;
        !           794:        case Opf_OE:
        !           795:                if (instr & (1 << (31-21))) {
        !           796:                        strlcat (disasm_buf, "o", bufsize);
        !           797:                }
        !           798:                break;
        !           799:        case Opf_RC:
        !           800:                if (instr & 0x1) {
        !           801:                        strlcat (disasm_buf, ".", bufsize);
        !           802:                }
        !           803:                break;
        !           804:        case Opf_S:
        !           805:        case Opf_D:
        !           806:                {
        !           807:                        u_int D;
        !           808:                        /* S and D are the same */
        !           809:                        D = extract_field(instr, 10, 5);
        !           810:                        snprintf(lbuf, sizeof (lbuf), "r%d", D);
        !           811:                        strlcat (disasm_buf, lbuf, bufsize);
        !           812:                }
        !           813:                break;
        !           814:        case Opf_SH:
        !           815:                {
        !           816:                        u_int SH;
        !           817:                        SH = extract_field(instr, 20, 5);
        !           818:                        snprintf(lbuf, sizeof (lbuf), "%d", SH);
        !           819:                        strlcat (disasm_buf, lbuf, bufsize);
        !           820:                }
        !           821:                break;
        !           822:        case Opf_SIMM:
        !           823:        case Opf_d:
        !           824:                {
        !           825:                        int32_t IMM;
        !           826:                        IMM = extract_field(instr, 31, 16);
        !           827:                        if (IMM & 0x8000)
        !           828:                                IMM |= ~0x7fff;
        !           829:                        snprintf(lbuf, sizeof (lbuf), "%d", IMM);
        !           830:                        strlcat (disasm_buf, lbuf, bufsize);
        !           831:                }
        !           832:                break;
        !           833:        case Opf_UIMM:
        !           834:                {
        !           835:                        u_int32_t IMM;
        !           836:                        IMM = extract_field(instr, 31, 16);
        !           837:                        snprintf(lbuf, sizeof (lbuf), "0x%x", IMM);
        !           838:                        strlcat (disasm_buf, lbuf, bufsize);
        !           839:                }
        !           840:                break;
        !           841:        case Opf_SR:
        !           842:                {
        !           843:                        u_int SR;
        !           844:                        SR = extract_field(instr, 15, 3);
        !           845:                        snprintf(lbuf, sizeof (lbuf), "sr%d", SR);
        !           846:                        strlcat (disasm_buf, lbuf, bufsize);
        !           847:                }
        !           848:                break;
        !           849:        case Opf_TO:
        !           850:                {
        !           851:                        u_int TO;
        !           852:                        TO = extract_field(instr, 10, 1);
        !           853:                        snprintf(lbuf, sizeof (lbuf), "%d", TO);
        !           854:                        strlcat (disasm_buf, lbuf, bufsize);
        !           855:                }
        !           856:                break;
        !           857:        case Opf_crbA:
        !           858:                {
        !           859:                        u_int crbA;
        !           860:                        crbA = extract_field(instr, 15, 5);
        !           861:                        snprintf(lbuf, sizeof (lbuf), "%d", crbA);
        !           862:                        strlcat (disasm_buf, lbuf, bufsize);
        !           863:                }
        !           864:                break;
        !           865:        case Opf_crbB:
        !           866:                {
        !           867:                        u_int crbB;
        !           868:                        crbB = extract_field(instr, 20, 5);
        !           869:                        snprintf(lbuf, sizeof (lbuf), "%d", crbB);
        !           870:                        strlcat (disasm_buf, lbuf, bufsize);
        !           871:                }
        !           872:                break;
        !           873:        case Opf_crbD:
        !           874:                {
        !           875:                        u_int crfD;
        !           876:                        crfD = extract_field(instr, 8, 3);
        !           877:                        snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
        !           878:                        strlcat (disasm_buf, lbuf, bufsize);
        !           879:                }
        !           880:                break;
        !           881:        case Opf_crfD:
        !           882:                {
        !           883:                        u_int crfD;
        !           884:                        crfD = extract_field(instr, 8, 3);
        !           885:                        snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
        !           886:                        strlcat (disasm_buf, lbuf, bufsize);
        !           887:                }
        !           888:                break;
        !           889:        case Opf_crfS:
        !           890:                {
        !           891:                        u_int crfS;
        !           892:                        crfS = extract_field(instr, 13, 3);
        !           893:                        snprintf(lbuf, sizeof (lbuf), "%d", crfS);
        !           894:                        strlcat (disasm_buf, lbuf, bufsize);
        !           895:                }
        !           896:                break;
        !           897:                break;
        !           898:        case Opf_mb:
        !           899:                {
        !           900:                        u_int mb, mbl, mbh;
        !           901:                        mbl = extract_field(instr, 25, 4);
        !           902:                        mbh = extract_field(instr, 26, 1);
        !           903:                        mb = mbh << 4 | mbl;
        !           904:                        snprintf(lbuf, sizeof (lbuf), ", %d", mb);
        !           905:                        strlcat (disasm_buf, lbuf, bufsize);
        !           906:                }
        !           907:                break;
        !           908:        case Opf_sh:
        !           909:                {
        !           910:                        u_int sh, shl, shh;
        !           911:                        shl = extract_field(instr, 19, 4);
        !           912:                        shh = extract_field(instr, 20, 1);
        !           913:                        sh = shh << 4 | shl;
        !           914:                        snprintf(lbuf, sizeof (lbuf), ", %d", sh);
        !           915:                        strlcat (disasm_buf, lbuf, bufsize);
        !           916:                }
        !           917:                break;
        !           918:        case Opf_spr:
        !           919:                {
        !           920:                        u_int spr;
        !           921:                        u_int sprl;
        !           922:                        u_int sprh;
        !           923:                        char *reg;
        !           924:                        sprl = extract_field(instr, 15, 5);
        !           925:                        sprh = extract_field(instr, 20, 5);
        !           926:                        spr = sprh << 5 | sprl;
        !           927:
        !           928:                        /* this table could be written better */
        !           929:                        switch (spr) {
        !           930:                        case    1:
        !           931:                                reg = "xer";
        !           932:                                break;
        !           933:                        case    8:
        !           934:                                reg = "lr";
        !           935:                                break;
        !           936:                        case    9:
        !           937:                                reg = "ctr";
        !           938:                                break;
        !           939:                        case    18:
        !           940:                                reg = "dsisr";
        !           941:                                break;
        !           942:                        case    19:
        !           943:                                reg = "dar";
        !           944:                                break;
        !           945:                        case    22:
        !           946:                                reg = "dec";
        !           947:                                break;
        !           948:                        case    25:
        !           949:                                reg = "sdr1";
        !           950:                                break;
        !           951:                        case    26:
        !           952:                                reg = "srr0";
        !           953:                                break;
        !           954:                        case    27:
        !           955:                                reg = "srr1";
        !           956:                                break;
        !           957:                        case    272:
        !           958:                                reg = "SPRG0";
        !           959:                                break;
        !           960:                        case    273:
        !           961:                                reg = "SPRG1";
        !           962:                                break;
        !           963:                        case    274:
        !           964:                                reg = "SPRG3";
        !           965:                                break;
        !           966:                        case    275:
        !           967:                                reg = "SPRG3";
        !           968:                                break;
        !           969:                        case    280:
        !           970:                                reg = "asr";
        !           971:                                break;
        !           972:                        case    282:
        !           973:                                reg = "aer";
        !           974:                                break;
        !           975:                        case    287:
        !           976:                                reg = "pvr";
        !           977:                                break;
        !           978:                        case    528:
        !           979:                                reg = "ibat0u";
        !           980:                                break;
        !           981:                        case    529:
        !           982:                                reg = "ibat0l";
        !           983:                                break;
        !           984:                        case    530:
        !           985:                                reg = "ibat1u";
        !           986:                                break;
        !           987:                        case    531:
        !           988:                                reg = "ibat1l";
        !           989:                                break;
        !           990:                        case    532:
        !           991:                                reg = "ibat2u";
        !           992:                                break;
        !           993:                        case    533:
        !           994:                                reg = "ibat2l";
        !           995:                                break;
        !           996:                        case    534:
        !           997:                                reg = "ibat3u";
        !           998:                                break;
        !           999:                        case    535:
        !          1000:                                reg = "ibat3l";
        !          1001:                                break;
        !          1002:                        case    536:
        !          1003:                                reg = "dbat0u";
        !          1004:                                break;
        !          1005:                        case    537:
        !          1006:                                reg = "dbat0l";
        !          1007:                                break;
        !          1008:                        case    538:
        !          1009:                                reg = "dbat1u";
        !          1010:                                break;
        !          1011:                        case    539:
        !          1012:                                reg = "dbat1l";
        !          1013:                                break;
        !          1014:                        case    540:
        !          1015:                                reg = "dbat2u";
        !          1016:                                break;
        !          1017:                        case    541:
        !          1018:                                reg = "dbat2l";
        !          1019:                                break;
        !          1020:                        case    542:
        !          1021:                                reg = "dbat3u";
        !          1022:                                break;
        !          1023:                        case    543:
        !          1024:                                reg = "dbat3l";
        !          1025:                                break;
        !          1026:                        case    1013:
        !          1027:                                reg = "dabr";
        !          1028:                                break;
        !          1029:                        default:
        !          1030:                                reg = 0;
        !          1031:                        }
        !          1032:                        if (reg == 0) {
        !          1033:                                snprintf(lbuf, sizeof (lbuf), "spr%d", spr);
        !          1034:                                strlcat (disasm_buf, lbuf, bufsize);
        !          1035:                        } else {
        !          1036:                                snprintf(lbuf, sizeof (lbuf), "%s", reg);
        !          1037:                                strlcat (disasm_buf, lbuf, bufsize);
        !          1038:                        }
        !          1039:                }
        !          1040:                break;
        !          1041:        case Opf_tbr:
        !          1042:                {
        !          1043:                        u_int tbr;
        !          1044:                        u_int tbrl;
        !          1045:                        u_int tbrh;
        !          1046:                        char *reg = NULL;
        !          1047:                        tbrl = extract_field(instr, 15, 5);
        !          1048:                        tbrh = extract_field(instr, 20, 5);
        !          1049:                        tbr = tbrh << 5 | tbrl;
        !          1050:
        !          1051:                        switch (tbr) {
        !          1052:                        case 268:
        !          1053:                                reg = "tbl";
        !          1054:                                break;
        !          1055:                        case 269:
        !          1056:                                reg = "tbu";
        !          1057:                                break;
        !          1058:                        default:
        !          1059:                                reg = 0;
        !          1060:                        }
        !          1061:                        if (reg == NULL) {
        !          1062:                                snprintf(lbuf, sizeof (lbuf), "tbr%d", tbr);
        !          1063:                                strlcat (disasm_buf, lbuf, bufsize);
        !          1064:                        } else {
        !          1065:                                snprintf(lbuf, sizeof (lbuf), "%s", reg);
        !          1066:                                strlcat (disasm_buf, lbuf, bufsize);
        !          1067:                        }
        !          1068:                }
        !          1069:                break;
        !          1070:        }
        !          1071: }
        !          1072:
        !          1073: void
        !          1074: disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
        !          1075:     char *disasm_str, size_t bufsize)
        !          1076: {
        !          1077:        char *pfmt;
        !          1078:        char cbuf[2];
        !          1079:        if (popcode->decode_str == NULL || popcode->decode_str[0] == '0') {
        !          1080:                return;
        !          1081:        }
        !          1082:        pfmt = popcode->decode_str;
        !          1083:
        !          1084:        while (*pfmt != '\0')  {
        !          1085:                if (*pfmt == '%') {
        !          1086:                        disasm_process_field(addr, instr, &pfmt, disasm_str,
        !          1087:                            bufsize);
        !          1088:                } else {
        !          1089:                        cbuf[0] = *pfmt;
        !          1090:                        cbuf[1] = '\0';
        !          1091:                        strlcat(disasm_str, cbuf, bufsize);
        !          1092:                        pfmt++;
        !          1093:                }
        !          1094:        }
        !          1095: }
        !          1096:
        !          1097: void
        !          1098: op_base(u_int32_t addr, instr_t instr)
        !          1099: {
        !          1100:        dis_ppc(addr, opcodes, instr);
        !          1101: }
        !          1102:
        !          1103: void
        !          1104: op_cl_x13(u_int32_t addr, instr_t instr)
        !          1105: {
        !          1106:        dis_ppc(addr, opcodes_13, instr);
        !          1107: }
        !          1108:
        !          1109: void
        !          1110: op_cl_x1e(u_int32_t addr, instr_t instr)
        !          1111: {
        !          1112:        dis_ppc(addr, opcodes_1e, instr);
        !          1113: }
        !          1114:
        !          1115: void
        !          1116: op_cl_x1f(u_int32_t addr, instr_t instr)
        !          1117: {
        !          1118:        dis_ppc(addr, opcodes_1f, instr);
        !          1119: }
        !          1120:
        !          1121: void
        !          1122: op_cl_x3a(u_int32_t addr, instr_t instr)
        !          1123: {
        !          1124:        dis_ppc(addr, opcodes_3a, instr);
        !          1125: }
        !          1126:
        !          1127: void
        !          1128: op_cl_x3b(u_int32_t addr, instr_t instr)
        !          1129: {
        !          1130:        dis_ppc(addr, opcodes_3b, instr);
        !          1131: }
        !          1132:
        !          1133: void
        !          1134: op_cl_x3e(u_int32_t addr, instr_t instr)
        !          1135: {
        !          1136:        dis_ppc(addr, opcodes_3e, instr);
        !          1137: }
        !          1138:
        !          1139: void
        !          1140: op_cl_x3f(u_int32_t addr, instr_t instr)
        !          1141: {
        !          1142:        dis_ppc(addr, opcodes_3f, instr);
        !          1143: }
        !          1144:
        !          1145: void
        !          1146: dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr)
        !          1147: {
        !          1148:        const struct opcode *op;
        !          1149:        int i;
        !          1150:        char disasm_str[80];
        !          1151:
        !          1152:        for (i=0; opcodeset[i].mask != 0; i++) {
        !          1153:                op = &opcodeset[i];
        !          1154:                if ((instr & op->mask) == op->code) {
        !          1155:                        disasm_fields(addr, op, instr, disasm_str,
        !          1156:                            sizeof disasm_str);
        !          1157:                        db_printf("%s%s\n", op->name, disasm_str);
        !          1158:                        return;
        !          1159:                }
        !          1160:        }
        !          1161:        op_ill(addr, instr);
        !          1162: }
        !          1163:
        !          1164: db_addr_t
        !          1165: db_disasm(db_addr_t loc, boolean_t extended)
        !          1166: {
        !          1167:        int class;
        !          1168:        instr_t opcode;
        !          1169:        opcode = *(instr_t *)(loc);
        !          1170:        class = opcode >> 26;
        !          1171:        (opcodes_base[class])(loc, opcode);
        !          1172:
        !          1173:        return loc + 4;
        !          1174: }

CVSweb