xref: /openbsd-src/sys/arch/powerpc/ddb/db_disasm.c (revision 949c1c4ec8cc03255798b09f6078e1d0aed70a6a)
1*949c1c4eSmiod /*	$OpenBSD: db_disasm.c,v 1.22 2024/11/07 16:02:29 miod Exp $	*/
284c41355Smiod /*
392383dfeSdrahn  * Copyright (c) 1996, 2001, 2003 Dale Rahn. All rights reserved.
46a1aaa0fSderaadt  *
584c41355Smiod  * Redistribution and use in source and binary forms, with or without
684c41355Smiod  * modification, are permitted provided that the following conditions
784c41355Smiod  * are met:
884c41355Smiod  * 1. Redistributions of source code must retain the above copyright
984c41355Smiod  *    notice, this list of conditions and the following disclaimer.
1084c41355Smiod  * 2. Redistributions in binary form must reproduce the above copyright
1184c41355Smiod  *    notice, this list of conditions and the following disclaimer in the
1284c41355Smiod  *    documentation and/or other materials provided with the distribution.
1384c41355Smiod  *
1484c41355Smiod  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1584c41355Smiod  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1684c41355Smiod  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1784c41355Smiod  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1884c41355Smiod  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1984c41355Smiod  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2084c41355Smiod  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2184c41355Smiod  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2284c41355Smiod  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2384c41355Smiod  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2484c41355Smiod  */
2584c41355Smiod 
2684c41355Smiod #include <sys/param.h>
2784c41355Smiod #include <sys/proc.h>
2884c41355Smiod #include <sys/systm.h>
2984c41355Smiod 
3084c41355Smiod #include <machine/db_machdep.h>
3184c41355Smiod 
3284c41355Smiod #include <ddb/db_access.h>
3384c41355Smiod #include <ddb/db_sym.h>
3484c41355Smiod #include <ddb/db_variables.h>
3584c41355Smiod #include <ddb/db_interface.h>
3684c41355Smiod #include <ddb/db_output.h>
3784c41355Smiod 
3884c41355Smiod enum opf {
3984c41355Smiod 	Opf_INVALID,
4084c41355Smiod 	Opf_A,
4184c41355Smiod 	Opf_A0,
4284c41355Smiod 	Opf_B,
4384c41355Smiod 	Opf_BI,
4484c41355Smiod 	Opf_BI1,
4584c41355Smiod 	Opf_BO,
4684c41355Smiod 	Opf_CRM,
4784c41355Smiod 	Opf_D,
4884c41355Smiod 	Opf_S,
4984c41355Smiod 	Opf_FM,
5084c41355Smiod 	Opf_LK,
5184c41355Smiod 	Opf_RC,
5284c41355Smiod 	Opf_AA,
5384c41355Smiod 	Opf_LI,
5484c41355Smiod 	Opf_OE,
5584c41355Smiod 	Opf_SR,
5684c41355Smiod 	Opf_TO,
5784c41355Smiod 	Opf_SIMM,
5884c41355Smiod 	Opf_UIMM,
5984c41355Smiod 	Opf_crbA,
6084c41355Smiod 	Opf_crbB,
6184c41355Smiod 	Opf_crbD,
6284c41355Smiod 	Opf_crfD,
6384c41355Smiod 	Opf_crfS,
645f35ad5dSgkoehler 	Opf_d,
655f35ad5dSgkoehler 	Opf_ds,
6684c41355Smiod 	Opf_spr,
6784c41355Smiod 	Opf_tbr,
6884c41355Smiod 
6984c41355Smiod 	Opf_BD,
7084c41355Smiod 	Opf_C,
7184c41355Smiod 
7284c41355Smiod 	Opf_NB,
7384c41355Smiod 
7484c41355Smiod 	Opf_sh,
7584c41355Smiod 	Opf_SH,
7684c41355Smiod 	Opf_mb,
7784c41355Smiod 	Opf_MB,
7884c41355Smiod 	Opf_ME,
7984c41355Smiod };
8084c41355Smiod 
8184c41355Smiod 
8284c41355Smiod struct db_field {
8384c41355Smiod 	char *name;
8484c41355Smiod 	enum opf opf;
8584c41355Smiod } db_fields[] = {
8684c41355Smiod 	{ "A",		Opf_A },
8784c41355Smiod 	{ "A0",		Opf_A0 },
8884c41355Smiod 	{ "B",		Opf_B },
8984c41355Smiod 	{ "D",		Opf_D },
9084c41355Smiod 	{ "S",		Opf_S },
9184c41355Smiod 	{ "AA",		Opf_AA },
9284c41355Smiod 	{ "LI",		Opf_LI },
9384c41355Smiod 	{ "BD",		Opf_BD },
9484c41355Smiod 	{ "BI",		Opf_BI },
9584c41355Smiod 	{ "BI1",	Opf_BI1 },
9684c41355Smiod 	{ "BO",		Opf_BO },
9784c41355Smiod 	{ "CRM",	Opf_CRM },
9884c41355Smiod 	{ "FM",		Opf_FM },
9984c41355Smiod 	{ "LK",		Opf_LK },
10084c41355Smiod 	{ "MB",		Opf_MB },
10184c41355Smiod 	{ "ME",		Opf_ME },
10284c41355Smiod 	{ "NB",		Opf_NB },
10384c41355Smiod 	{ "OE",		Opf_OE },
10484c41355Smiod 	{ "RC",		Opf_RC },
10584c41355Smiod 	{ "SH",		Opf_SH },
10684c41355Smiod 	{ "SR",		Opf_SR },
10784c41355Smiod 	{ "TO",		Opf_TO },
10884c41355Smiod 	{ "SIMM",	Opf_SIMM },
10984c41355Smiod 	{ "UIMM",	Opf_UIMM },
11084c41355Smiod 	{ "crbA",	Opf_crbA },
11184c41355Smiod 	{ "crbB",	Opf_crbB },
11284c41355Smiod 	{ "crbD",	Opf_crbD },
11384c41355Smiod 	{ "crfD",	Opf_crfD },
11484c41355Smiod 	{ "crfS",	Opf_crfS },
11584c41355Smiod 	{ "d",		Opf_d },
1165f35ad5dSgkoehler 	{ "ds",		Opf_ds },
11784c41355Smiod 	{ "mb",		Opf_mb },
11884c41355Smiod 	{ "sh",		Opf_sh },
11984c41355Smiod 	{ "spr",	Opf_spr },
12084c41355Smiod 	{ "tbr",	Opf_tbr },
12184c41355Smiod 	{ NULL,		0 }
12284c41355Smiod };
12384c41355Smiod 
12484c41355Smiod struct opcode {
12584c41355Smiod 	char *name;
12684c41355Smiod 	u_int32_t mask;
12784c41355Smiod 	u_int32_t code;
12884c41355Smiod 	char *decode_str;
12984c41355Smiod };
13084c41355Smiod 
13184c41355Smiod typedef u_int32_t instr_t;
13284c41355Smiod typedef void (op_class_func) (u_int32_t addr, instr_t instr);
13384c41355Smiod 
13484c41355Smiod u_int32_t extract_field(u_int32_t value, u_int32_t base, u_int32_t width);
13584c41355Smiod void disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
13610691430Sdrahn     char *disasm_str, size_t bufsize);
13710691430Sdrahn void disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
13810691430Sdrahn     char *ppoutput, size_t bufsize);
13984c41355Smiod void dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr);
14084c41355Smiod 
14110691430Sdrahn 
14284c41355Smiod op_class_func op_ill, op_base;
14384c41355Smiod op_class_func op_cl_x13, op_cl_x1e, op_cl_x1f;
14484c41355Smiod op_class_func op_cl_x3a, op_cl_x3b;
14584c41355Smiod op_class_func op_cl_x3e, op_cl_x3f;
14684c41355Smiod 
14784c41355Smiod op_class_func *opcodes_base[] = {
14884c41355Smiod /*x00*/	op_ill,		op_ill,		op_base,	op_ill,
14984c41355Smiod /*x04*/	op_ill,		op_ill,		op_ill,		op_base,
15084c41355Smiod /*x08*/	op_base,	op_base,	op_base,	op_base,
15184c41355Smiod /*x0C*/	op_base,	op_base,	op_base/*XXX*/,	op_base/*XXX*/,
15284c41355Smiod /*x10*/	op_base,	op_base,	op_base,	op_cl_x13,
15384c41355Smiod /*x14*/	op_base,	op_base,	op_ill,		op_base,
15484c41355Smiod /*x18*/	op_base,	op_base,	op_base,	op_base,
15584c41355Smiod /*x1C*/	op_base,	op_base,	op_cl_x1e,	op_cl_x1f,
15684c41355Smiod /*x20*/	op_base,	op_base,	op_base,	op_base,
15784c41355Smiod /*x24*/	op_base,	op_base,	op_base,	op_base,
15884c41355Smiod /*x28*/	op_base,	op_base,	op_base,	op_base,
15984c41355Smiod /*x2C*/	op_base,	op_base,	op_base,	op_base,
16084c41355Smiod /*x30*/	op_base,	op_base,	op_base,	op_base,
16184c41355Smiod /*x34*/	op_base,	op_base,	op_base,	op_base,
16284c41355Smiod /*x38*/	op_ill,		op_ill,		op_cl_x3a,	op_cl_x3b,
16384c41355Smiod /*x3C*/	op_ill,		op_ill,		op_cl_x3e,	op_cl_x3f
16484c41355Smiod };
16584c41355Smiod 
16684c41355Smiod 
16784c41355Smiod /* This table could be modified to make significant the "reserved" fields
16884c41355Smiod  * of the opcodes, But I didn't feel like it when typing in the table,
16984c41355Smiod  * I would recommend that this table be looked over for errors,
17084c41355Smiod  * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD)
17184c41355Smiod  * PowerPC Microprocessor Family: The Programming Environments
17284c41355Smiod  */
17384c41355Smiod 
17484c41355Smiod const struct opcode opcodes[] = {
17584c41355Smiod 	{ "tdi",	0xfc000000, 0x08000000, " %{TO},%{A},%{SIMM}" },
17684c41355Smiod 	{ "twi",	0xfc000000, 0x0c000000, " %{TO},%{A},%{SIMM}" },
17784c41355Smiod 
17884c41355Smiod 	{ "mulli",	0xfc000000, 0x1c000000, " %{D},%{A},%{SIMM}" },
17984c41355Smiod 	{ "subfic",	0xfc000000, 0x20000000, " %{D},%{A},%{SIMM}" },
18084c41355Smiod 	{ "cmpli",	0xff800000, 0x28000000, " %{A},%{UIMM}" },
18184c41355Smiod 	{ "cmpli",	0xfc400000, 0x28000000, " %{crfD}%{A}, %{UIMM}" },
18284c41355Smiod 	{ "cmpi",	0xff800000, 0x2c000000, " %{A},%{SIMM}"},
18384c41355Smiod 	{ "cmpi",	0xfc400000, 0x2c000000, " %{crfD}%{A},%{SIMM}" },
18484c41355Smiod 	{ "addic",	0xfc000000, 0x30000000, " %{D},%{A},%{SIMM}" },
18584c41355Smiod 	{ "addic.",	0xfc000000, 0x34000000, " %{D},%{A},%{SIMM}" },
18684c41355Smiod 	{ "addi",	0xfc000000, 0x38000000, " %{D},%{A0}%{SIMM}" },
18784c41355Smiod 	{ "addis",	0xfc000000, 0x3c000000, " %{D},%{A0}%{SIMM}" },
18884c41355Smiod 	{ "sc",		0xffffffff, 0x44000002, "" },
189fb5cc47dSdrahn 	{ "b",		0xfc000000, 0x40000000, "%{BO}%{LK}%{AA} %{BI}%{BD}" },
190fb5cc47dSdrahn 	{ "b",		0xfc000000, 0x48000000, "%{LK}%{AA} %{LI}" },
19184c41355Smiod 
19284c41355Smiod 	{ "rlwimi",	0xfc000000, 0x50000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
19384c41355Smiod 	{ "rlwinm",	0xfc000000, 0x54000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
19484c41355Smiod 	{ "rlwnm",	0xfc000000, 0x5c000000, "%{RC} %{A},%{S},%{SH},%{MB},%{ME}" },
19584c41355Smiod 
19684c41355Smiod 	{ "ori",	0xfc000000, 0x60000000, " %{A},%{S},%{UIMM}" },
19784c41355Smiod 	{ "oris",	0xfc000000, 0x64000000, " %{A},%{S},%{UIMM}" },
19884c41355Smiod 	{ "xori",	0xfc000000, 0x68000000, " %{A},%{S},%{UIMM}" },
19984c41355Smiod 	{ "xoris",	0xfc000000, 0x6c000000, " %{A},%{S},%{UIMM}" },
20084c41355Smiod 
20184c41355Smiod 	{ "andi.",	0xfc000000, 0x70000000, " %{A},%{S},%{UIMM}" },
20284c41355Smiod 	{ "andis.",	0xfc000000, 0x74000000, " %{A},%{S},%{UIMM}" },
20384c41355Smiod 
20484c41355Smiod 	{ "lwz",	0xfc000000, 0x80000000, " %{D},%{d}(%{A})" },
20584c41355Smiod 	{ "lwzu",	0xfc000000, 0x84000000, " %{D},%{d}(%{A})" },
20684c41355Smiod 	{ "lbz",	0xfc000000, 0x88000000, " %{D},%{d}(%{A})" },
20784c41355Smiod 	{ "lbzu",	0xfc000000, 0x8c000000, " %{D},%{d}(%{A})" },
20884c41355Smiod 	{ "stw",	0xfc000000, 0x90000000, " %{S},%{d}(%{A})" },
20984c41355Smiod 	{ "stwu",	0xfc000000, 0x94000000, " %{S},%{d}(%{A})" },
21084c41355Smiod 	{ "stb",	0xfc000000, 0x98000000, " %{S},%{d}(%{A})" },
21184c41355Smiod 	{ "stbu",	0xfc000000, 0x9c000000, " %{S},%{d}(%{A})" },
21284c41355Smiod 
21384c41355Smiod 	{ "lhz",	0xfc000000, 0xa0000000, " %{D},%{d}(%{A})" },
21484c41355Smiod 	{ "lhzu",	0xfc000000, 0xa4000000, " %{D},%{d}(%{A})" },
21584c41355Smiod 	{ "lha",	0xfc000000, 0xa8000000, " %{D},%{d}(%{A})" },
21684c41355Smiod 	{ "lhau",	0xfc000000, 0xac000000, " %{D},%{d}(%{A})" },
21784c41355Smiod 	{ "sth",	0xfc000000, 0xb0000000, " %{S},%{d}(%{A})" },
21884c41355Smiod 	{ "sthu",	0xfc000000, 0xb4000000, " %{S},%{d}(%{A})" },
21984c41355Smiod 	{ "lmw",	0xfc000000, 0xb8000000, " %{D},%{d}(%{A})" },
22084c41355Smiod 	{ "stmw",	0xfc000000, 0xbc000000, " %{S},%{d}(%{A})" },
22184c41355Smiod 
22284c41355Smiod 	{ "lfs",	0xfc000000, 0xc0000000, " %{D},%{d}(%{A})" },
22384c41355Smiod 	{ "lfsu",	0xfc000000, 0xc4000000, " %{D},%{d}(%{A})" },
22484c41355Smiod 	{ "lfd",	0xfc000000, 0xc8000000, " %{D},%{d}(%{A})" },
22584c41355Smiod 	{ "lfdu",	0xfc000000, 0xcc000000, " %{D},%{d}(%{A})" },
22684c41355Smiod 
22784c41355Smiod 	{ "stfs",	0xfc000000, 0xd0000000, " %{S},%{d}(%{A})" },
22884c41355Smiod 	{ "stfsu",	0xfc000000, 0xd4000000, " %{S},%{d}(%{A})" },
22984c41355Smiod 	{ "stfd",	0xfc000000, 0xd8000000, " %{S},%{d}(%{A})" },
23084c41355Smiod 	{ "stfdu",	0xfc000000, 0xdc000000, " %{S},%{d}(%{A})" },
23184c41355Smiod 	{ "",		0x0,		0x0, "" }
23284c41355Smiod 
23384c41355Smiod };
234eaf55909Sdrahn 
23584c41355Smiod /* 13 * 4 = 4c */
23684c41355Smiod const struct opcode opcodes_13[] = {
23784c41355Smiod /* 0x13 << 2 */
23884c41355Smiod 	{ "mcrf",	0xfc0007fe, 0x4c000000, " %{crfD},%{crfS}" },
23984c41355Smiod 	{ "b",/*bclr*/	0xfc0007fe, 0x4c000020, "%{BO}lr%{LK} %{BI1}" },
24084c41355Smiod 	{ "crnor",	0xfc0007fe, 0x4c000042, " %{crbD},%{crbA},%{crbB}" },
24184c41355Smiod 	{ "rfi",	0xfc0007fe, 0x4c000064, "" },
24284c41355Smiod 	{ "crandc",	0xfc0007fe, 0x4c000102, " %{crbD},%{crbA},%{crbB}" },
24384c41355Smiod 	{ "isync",	0xfc0007fe, 0x4c00012c, "" },
24484c41355Smiod 	{ "crxor",	0xfc0007fe, 0x4c000182, " %{crbD},%{crbA},%{crbB}" },
24584c41355Smiod 	{ "crnand",	0xfc0007fe, 0x4c0001c2, " %{crbD},%{crbA},%{crbB}" },
24684c41355Smiod 	{ "crand",	0xfc0007fe, 0x4c000202, " %{crbD},%{crbA},%{crbB}" },
24784c41355Smiod 	{ "creqv",	0xfc0007fe, 0x4c000242, " %{crbD},%{crbA},%{crbB}" },
24884c41355Smiod 	{ "crorc",	0xfc0007fe, 0x4c000342, " %{crbD},%{crbA},%{crbB}" },
24984c41355Smiod 	{ "cror",	0xfc0007fe, 0x4c000382, " %{crbD},%{crbA},%{crbB}" },
25084c41355Smiod 	{ "b"/*bcctr*/,	0xfc0007fe, 0x4c000420, "%{BO}ctr%{LK} %{BI1}" },
25184c41355Smiod 	{ "",		0x0,		0x0, "" }
25284c41355Smiod };
25384c41355Smiod 
25484c41355Smiod /* 1e * 4 = 78 */
25584c41355Smiod const struct opcode opcodes_1e[] = {
25684c41355Smiod 	{ "rldicl",	0xfc00001c, 0x78000000, " %{A},%{S},%{sh},%{mb}" },
25784c41355Smiod 	{ "rldicr",	0xfc00001c, 0x78000004, " %{A},%{S},%{sh},%{mb}" },
25884c41355Smiod 	{ "rldic",	0xfc00001c, 0x78000008, " %{A},%{S},%{sh},%{mb}" },
25984c41355Smiod 	{ "rldimi",	0xfc00001c, 0x7800000c, " %{A},%{S},%{sh},%{mb}" },
26084c41355Smiod 	{ "rldcl",	0xfc00003e, 0x78000010, " %{A},%{S},%{B},%{mb}" },
26184c41355Smiod 	{ "rldcr",	0xfc00003e, 0x78000012, " %{A},%{S},%{B},%{mb}" },
26284c41355Smiod 	{ "",		0x0,		0x0, "" }
26384c41355Smiod };
26484c41355Smiod 
26584c41355Smiod /* 1f * 4 = 7c */
26684c41355Smiod const struct opcode opcodes_1f[] = {
26784c41355Smiod /* 1f << 2 */
26884c41355Smiod 	{ "cmpd",	0xfc2007fe, 0x7c200000, " %{crfD}%{A},%{B}" },
26984c41355Smiod 	{ "cmpw",	0xfc2007fe, 0x7c000000, " %{crfD}%{A},%{B}" },
27084c41355Smiod 	{ "tw",		0xfc0007fe, 0x7c000008, " %{TO},%{A},%{B}" },
27184c41355Smiod 	{ "subfc",	0xfc0003fe, 0x7c000010, "%{OE}%{RC} %{D},%{A},%{B}" },
27284c41355Smiod 	{ "mulhdu",	0xfc0007fe, 0x7c000012, "%{RC} %{D},%{A},%{B}" },
27384c41355Smiod 	{ "addc",	0xfc0003fe, 0x7c000014, "%{OE}%{RC} %{D},%{A},%{B}" },
27484c41355Smiod 	{ "mulhwu",	0xfc0007fe, 0x7c000016, "%{RC} %{D},%{A},%{B}" },
27584c41355Smiod 
27684c41355Smiod 	{ "mfcr",	0xfc0007fe, 0x7c000026, " %{D}" },
27784c41355Smiod 	{ "lwarx",	0xfc0007fe, 0x7c000028, " %{D},%{A0}%{B}" },
27884c41355Smiod 	{ "ldx",	0xfc0007fe, 0x7c00002a, " %{D},%{A0}%{B}" },
27984c41355Smiod 	{ "lwzx",	0xfc0007fe, 0x7c00002e, " %{D},%{A0}%{B}" },
28084c41355Smiod 	{ "slw",	0xfc0007fe, 0x7c000030, "%{RC} %{A},%{S},%{B}" },
28184c41355Smiod 	{ "cntlzw",	0xfc0007fe, 0x7c000034, "%{RC} %{A},%{S}" },
28284c41355Smiod 	{ "sld",	0xfc0007fe, 0x7c000036, "%{RC} %{A},%{S},%{B}" },
28384c41355Smiod 	{ "and",	0xfc0007fe, 0x7c000038, "%{RC} %{A},%{S},%{B}" },
28484c41355Smiod 	{ "cmpld",	0xfc2007fe, 0x7c200040, " %{crfD}%{A},%{B}" },
28584c41355Smiod 	{ "cmplw",	0xfc2007fe, 0x7c000040, " %{crfD}%{A},%{B}" },
28684c41355Smiod 	{ "subf",	0xfc0003fe, 0x7c000050, "%{OE}%{RC} %{D},%{A},%{B}" },
28784c41355Smiod 	{ "ldux",	0xfc0007fe, 0x7c00006a, " %{D},%{A},%{B}" },
28884c41355Smiod 	{ "dcbst",	0xfc0007fe, 0x7c00006c, " %{A0}%{B}" },
28984c41355Smiod 	{ "lwzux",	0xfc0007fe, 0x7c00006e, " %{D},%{A},%{B}" },
29084c41355Smiod 	{ "cntlzd",	0xfc0007fe, 0x7c000074, "%{RC} %{A},%{S}" },
29184c41355Smiod 	{ "andc",	0xfc0007fe, 0x7c000078, "%{RC} %{A},%{S},%{B}" },
29284c41355Smiod 	{ "td",		0xfc0007fe, 0x7c000088, " %{TO},%{A},%{B}" },
29384c41355Smiod 	{ "mulhd",	0xfc0007fe, 0x7c000092, "%{RC} %{D},%{A},%{B}" },
29484c41355Smiod 	{ "mulhw",	0xfc0007fe, 0x7c000096, "%{RC} %{D},%{A},%{B}" },
29584c41355Smiod 	{ "mfmsr",	0xfc0007fe, 0x7c0000a6, " %{D}" },
29684c41355Smiod 	{ "ldarx",	0xfc0007fe, 0x7c0000a8, " %{D},%{A0}%{B}" },
29784c41355Smiod 	{ "dcbf",	0xfc0007fe, 0x7c0000ac, " %{A0}%{B}" },
29884c41355Smiod 	{ "lbzx",	0xfc0007fe, 0x7c0000ae, " %{D},%{A0}%{B}" },
29984c41355Smiod 	{ "neg",	0xfc0003fe, 0x7c0000d0, "%{OE}%{RC} %{D},%{A}" },
30084c41355Smiod 	{ "lbzux",	0xfc0007fe, 0x7c0000ee, " %{D},%{A},%{B}" },
30184c41355Smiod 	{ "nor",	0xfc0007fe, 0x7c0000f8, "%{RC} %{A},%{S}" },
30284c41355Smiod 	{ "subfe",	0xfc0003fe, 0x7c000110, "%{OE}%{RC} %{D},%{A}" },
30384c41355Smiod 	{ "adde",	0xfc0003fe, 0x7c000114, "%{OE}%{RC} %{D},%{A}" },
30484c41355Smiod 	{ "mtcrf",	0xfc0007fe, 0x7c000120, " %{S},%{CRM}" },
30584c41355Smiod 	{ "mtmsr",	0xfc0007fe, 0x7c000124, " %{S}" },
30684c41355Smiod 	{ "stdx",	0xfc0007fe, 0x7c00012a, " %{S},%{A0}%{B}" },
30784c41355Smiod 	{ "stwcx.",	0xfc0007ff, 0x7c00012d, " %{S},%{A},%{B}" },
30884c41355Smiod 	{ "stwx",	0xfc0007fe, 0x7c00012e, " %{S},%{A},%{B}" },
30984c41355Smiod 	{ "stdux",	0xfc0007fe, 0x7c00016a, " %{S},%{A},%{B}" },
31084c41355Smiod 	{ "stwux",	0xfc0007fe, 0x7c00016e, " %{S},%{A},%{B}" },
31184c41355Smiod 	{ "subfze",	0xfc0003fe, 0x7c000190, "%{OE}%{RC} %{D},%{A}" },
31284c41355Smiod 	{ "addze",	0xfc0003fe, 0x7c000194, "%{OE}%{RC} %{D},%{A}" },
31384c41355Smiod 	{ "mtsr",	0xfc0007fe, 0x7c0001a4, " %{SR},%{S}" },
31484c41355Smiod 	{ "stdcx.",	0xfc0007ff, 0x7c0001ad, " %{S},%{A0}%{B}" },
31584c41355Smiod 	{ "stbx",	0xfc0007fe, 0x7c0001ae, " %{S},%{A0}%{B}" },
31684c41355Smiod 	{ "subfme",	0xfc0003fe, 0x7c0001d0, "%{OE}%{RC} %{D},%{A}" },
31784c41355Smiod 	{ "mulld",	0xfc0003fe, 0x7c0001d2, "%{OE}%{RC} %{D},%{A},%{B}" },
31884c41355Smiod 	{ "addme",	0xfc0003fe, 0x7c0001d4, "%{OE}%{RC} %{D},%{A}" },
31984c41355Smiod 	{ "mullw",	0xfc0003fe, 0x7c0001d6, "%{OE}%{RC} %{D},%{A},%{B}" },
32084c41355Smiod 	{ "mtsrin",	0xfc0007fe, 0x7c0001e4, " %{S},%{B}" },
32184c41355Smiod 	{ "dcbtst",	0xfc0007fe, 0x7c0001ec, " %{A0}%{B}" },
32284c41355Smiod 	{ "stbux",	0xfc0007fe, 0x7c0001ee, " %{S},%{A},%{B}" },
32384c41355Smiod 	{ "add",	0xfc0003fe, 0x7c000214, "" },
32484c41355Smiod 	{ "dcbt",	0xfc0007fe, 0x7c00022c, " %{A0}%{B}" },
32584c41355Smiod 	{ "lhzx",	0xfc0007ff, 0x7c00022e, " %{D},%{A0}%{B}" },
32684c41355Smiod 	{ "eqv",	0xfc0007fe, 0x7c000238, "%{RC} %{A},%{S},%{B}" },
32784c41355Smiod 	{ "tlbie",	0xfc0007fe, 0x7c000264, " %{B}" },
32884c41355Smiod 	{ "eciwx",	0xfc0007fe, 0x7c00026c, " %{D},%{A0}%{B}" },
32984c41355Smiod 	{ "lhzux",	0xfc0007fe, 0x7c00026e, " %{D},%{A},%{B}" },
33084c41355Smiod 	{ "xor",	0xfc0007fe, 0x7c000278, "%{RC} %{A},%{S},%{B}" },
33184c41355Smiod 	{ "mfspr",	0xfc0007fe, 0x7c0002a6, " %{D},%{spr}" },
33284c41355Smiod 	{ "lwax",	0xfc0007fe, 0x7c0002aa, " %{D},%{A0}%{B}" },
33384c41355Smiod 	{ "lhax",	0xfc0007fe, 0x7c0002ae, " %{D},%{A},%{B}" },
33484c41355Smiod 	{ "tlbia",	0xfc0007fe, 0x7c0002e4, "" },
33584c41355Smiod 	{ "mftb",	0xfc0007fe, 0x7c0002e6, " %{D},%{tbr}" },
33684c41355Smiod 	{ "lwaux",	0xfc0007fe, 0x7c0002ea, " %{D},%{A},%{B}" },
33784c41355Smiod 	{ "lhaux",	0xfc0007fe, 0x7c0002ee, " %{D},%{A},%{B}" },
33884c41355Smiod 	{ "sthx",	0xfc0007fe, 0x7c00032e, " %{S},%{A0}%{B}" },
33984c41355Smiod 	{ "orc",	0xfc0007fe, 0x7c000338, "%{RC} %{A},%{S},%{B}" },
34084c41355Smiod 	{ "ecowx",	0xfc0007fe, 0x7c00036c, "%{RC} %{S},%{A0}%{B}" },
34184c41355Smiod 	{ "slbie",	0xfc0007fc, 0x7c000364, " %{B}" },
34284c41355Smiod 	{ "sthux",	0xfc0007fe, 0x7c00036e, " %{S},%{A0}%{B}" },
34384c41355Smiod 	{ "or",		0xfc0007fe, 0x7c000378, "%{RC} %{A},%{S},%{B}" },
34484c41355Smiod 	{ "divdu",	0xfc0003fe, 0x7c000392, "%{OE}%{RC} %{S},%{A},%{B}" },
34584c41355Smiod 	{ "divwu",	0xfc0003fe, 0x7c000396, "%{OE}%{RC} %{S},%{A},%{B}" },
34684c41355Smiod 	{ "mtspr",	0xfc0007fe, 0x7c0003a6, " %{spr},%{S}" },
34784c41355Smiod 	{ "dcbi",	0xfc0007fe, 0x7c0003ac, " %{A0}%{B}" },
34884c41355Smiod 	{ "nand",	0xfc0007fe, 0x7c0003b8, "%{RC} %{A},%{S},%{B}" },
34984c41355Smiod 	{ "divd",	0xfc0003fe, 0x7c0003d2, "%{OE}%{RC} %{S},%{A},%{B}" },
35084c41355Smiod 	{ "divw",	0xfc0003fe, 0x7c0003d6, "%{OE}%{RC} %{S},%{A},%{B}" },
35184c41355Smiod 	{ "slbia",	0xfc0003fe, 0x7c0003e4, "%{OE}%{RC} %{S},%{A},%{B}" },
35284c41355Smiod 	{ "mcrxr",	0xfc0007fe, 0x7c000400, "crfD1" },
35384c41355Smiod 	{ "lswx",	0xfc0007fe, 0x7c00042a, " %{D},%{A0}%{B}" },
35484c41355Smiod 	{ "lwbrx",	0xfc0007fe, 0x7c00042c, " %{D},%{A0}%{B}" },
35584c41355Smiod 	{ "lfsx",	0xfc0007fe, 0x7c00042e, " %{D},%{A},%{B}" },
35684c41355Smiod 	{ "srw",	0xfc0007fe, 0x7c000430, "%{RC} %{A},%{S},%{B}" },
35784c41355Smiod 	{ "srd",	0xfc0007fe, 0x7c000436, "%{RC} %{A},%{S},%{B}" },
35884c41355Smiod 	{ "tlbsync",	0xffffffff, 0x7c00046c, "" },
35984c41355Smiod 	{ "lfsux",	0xfc0007fe, 0x7c00046e, " %{D},%{A},%{B}" },
36084c41355Smiod 	{ "mfsr",	0xfc0007fe, 0x7c0004a6, " %{D},%{SR}" },
36184c41355Smiod 	{ "lswi",	0xfc0007fe, 0x7c0004aa, " %{D},%{A},%{NB}" },
36284c41355Smiod 	{ "sync",	0xfc0007fe, 0x7c0004ac, "" },
36384c41355Smiod 	{ "lfdx",	0xfc0007fe, 0x7c0004ae, " %{D},%{A},%{B}" },
36484c41355Smiod 	{ "lfdux",	0xfc0007fe, 0x7c0004ee, " %{D},%{A},%{B}" },
36584c41355Smiod 	{ "mfsrin",	0xfc0007fe, 0x7c000526, "" },
36684c41355Smiod 	{ "stswx",	0xfc0007fe, 0x7c00052a, " %{S},%{A0}%{B}" },
36784c41355Smiod 	{ "stwbrx",	0xfc0007fe, 0x7c00052c, " %{S},%{A0}%{B}" },
36884c41355Smiod 	{ "stfsx",	0xfc0007fe, 0x7c00052e, " %{S},%{A0}%{B}" },
36984c41355Smiod 	{ "stfsux",	0xfc0007fe, 0x7c00056e, " %{S},%{A},%{B}" },
37084c41355Smiod 	{ "stswi",	0xfc0007fe, 0x7c0005aa, "%{S},%{A0}%{NB}" },
37184c41355Smiod 	{ "stfdx",	0xfc0007fe, 0x7c0005ae, " %{S},%{A0}%{B}" },
37284c41355Smiod 	{ "stfdux",	0xfc0007fe, 0x7c0005ee, " %{S},%{A},%{B}" },
37384c41355Smiod 	{ "lhbrx",	0xfc0007fe, 0x7c00062c, " %{D},%{A0}%{B}" },
37484c41355Smiod 	{ "sraw",	0xfc0007fe, 0x7c000630, " %{A},%{S},%{B}" },
37584c41355Smiod 	{ "srad",	0xfc0007fe, 0x7c000634, "%{RC} %{A},%{S},%{B}" },
37684c41355Smiod 	{ "srawi",	0xfc0007fe, 0x7c000670, "%{RC} %{A},%{SH}" },
37784c41355Smiod 	{ "sradi",	0xfc0007fc, 0x7c000674, " %{A},%{S},%{sh}" },
37884c41355Smiod 	{ "eieio",	0xfc0007fe, 0x7c0006ac, "" }, /* MASK? */
37984c41355Smiod 	{ "sthbrx",	0xfc0007fe, 0x7c00072c, " %{S},%{A0}%{B}" },
38084c41355Smiod 	{ "extsh",	0xfc0007fe, 0x7c000734, "%{RC} %{A},%{S}" },
38184c41355Smiod 	{ "extsb",	0xfc0007fe, 0x7c000774, "%{RC} %{A},%{S}" },
38284c41355Smiod 	{ "icbi",	0xfc0007fe, 0x7c0007ac, " %{A0}%{B}" },
38384c41355Smiod 
38484c41355Smiod 	{ "stfiwx",	0xfc0007fe, 0x7c0007ae, " %{S},%{A0}%{B}" },
38584c41355Smiod 	{ "extsw",	0xfc0007fe, 0x7c0007b4, "%{RC} %{A},%{S}" },
38684c41355Smiod 	{ "dcbz",	0xfc0007fe, 0x7c0007ec, " %{A0}%{B}" },
38784c41355Smiod 	{ "",		0x0,		0x0, 0, }
38884c41355Smiod };
38984c41355Smiod 
39084c41355Smiod /* 3a * 4 = e8 */
39184c41355Smiod const struct opcode opcodes_3a[] = {
3925f35ad5dSgkoehler 	{ "ld",		0xfc000003, 0xe8000000, " %{D},%{ds}(%{A})" },
3935f35ad5dSgkoehler 	{ "ldu",	0xfc000003, 0xe8000001, " %{D},%{ds}(%{A})" },
3945f35ad5dSgkoehler 	{ "lwa",	0xfc000003, 0xe8000002, " %{D},%{ds}(%{A})" },
39584c41355Smiod 	{ "",		0x0,		0x0, "" }
39684c41355Smiod };
397eaf55909Sdrahn 
39884c41355Smiod /* 3b * 4 = ec */
39984c41355Smiod const struct opcode opcodes_3b[] = {
40084c41355Smiod 	{ "fdivs",	0xfc00003e, 0xec000024, "%{RC} f%{D},f%{A},f%{B}" },
40184c41355Smiod 	{ "fsubs",	0xfc00003e, 0xec000028, "%{RC} f%{D},f%{A},f%{B}" },
40284c41355Smiod 
40384c41355Smiod 	{ "fadds",	0xfc00003e, 0xec00002a, "%{RC} f%{D},f%{A},f%{B}" },
40484c41355Smiod 	{ "fsqrts",	0xfc00003e, 0xec00002c, "" },
40584c41355Smiod 	{ "fres",	0xfc00003e, 0xec000030, "" },
40684c41355Smiod 	{ "fmuls",	0xfc00003e, 0xec000032, "%{RC} f%{D},f%{A},f%{C}" },
40784c41355Smiod 	{ "fmsubs",	0xfc00003e, 0xec000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
40884c41355Smiod 	{ "fmadds",	0xfc00003e, 0xec00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
40984c41355Smiod 	{ "fnmsubs",	0xfc00003e, 0xec00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
41084c41355Smiod 	{ "fnmadds",	0xfc00003e, 0xec00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
41184c41355Smiod 	{ "",		0x0,		0x0, "" }
41284c41355Smiod };
413eaf55909Sdrahn 
41484c41355Smiod /* 3e * 4 = f8 */
41584c41355Smiod const struct opcode opcodes_3e[] = {
4165f35ad5dSgkoehler 	{ "std",	0xfc000003, 0xf8000000, " %{D},%{ds}(%{A})" },
4175f35ad5dSgkoehler 	{ "stdu",	0xfc000003, 0xf8000001, " %{D},%{ds}(%{A})" },
41884c41355Smiod 	{ "",		0x0,		0x0, "" }
41984c41355Smiod };
42084c41355Smiod 
42184c41355Smiod /* 3f * 4 = fc */
42284c41355Smiod const struct opcode opcodes_3f[] = {
42384c41355Smiod 	{ "fcmpu",	0xfc0007fe, 0xfc000000, " %{crfD},f%{A},f%{B}" },
42484c41355Smiod 	{ "frsp",	0xfc0007fe, 0xfc000018, "%{RC} f%{D},f%{B}" },
42584c41355Smiod 	{ "fctiw",	0xfc0007fe, 0xfc00001c, "%{RC} f%{D},f%{B}" },
42684c41355Smiod 	{ "fctiwz",	0xfc0007fe, 0xfc00001e, "%{RC} f%{D},f%{B}" },
42784c41355Smiod 
42884c41355Smiod 	{ "fdiv",	0xfc00003e, 0xfc000024, "%{RC} f%{D},f%{A},f%{B}" },
42984c41355Smiod 	{ "fsub",	0xfc00003e, 0xfc000028, "%{RC} f%{D},f%{A},f%{B}" },
43084c41355Smiod 	{ "fadd",	0xfc00003e, 0xfc00002a, "%{RC} f%{D},f%{A},f%{B}" },
43184c41355Smiod 	{ "fsqrt",	0xfc00003e, 0xfc00002c, "%{RC} f%{D},f%{B}" },
43284c41355Smiod 	{ "fsel",	0xfc00003e, 0xfc00002e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
43384c41355Smiod 	{ "fmul",	0xfc00003e, 0xfc000032, "%{RC} f%{D},f%{A},f%{C}" },
43484c41355Smiod 	{ "frsqrte",	0xfc00003e, 0xfc000034, "%{RC} f%{D},f%{B}" },
43584c41355Smiod 	{ "fmsub",	0xfc00003e, 0xfc000038, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
43684c41355Smiod 	{ "fmadd",	0xfc00003e, 0xfc00003a, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
43784c41355Smiod 	{ "fnmsub",	0xfc00003e, 0xfc00003c, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
43884c41355Smiod 	{ "fnmadd",	0xfc00003e, 0xfc00003e, "%{RC} f%{D},f%{A},f%{C},f%{B}" },
43984c41355Smiod 
44084c41355Smiod 	{ "fcmpo",	0xfc0007fe, 0xfc000040, "%{RC} f%{D},f%{A},f%{C}" },
44184c41355Smiod 	{ "mtfsb1",	0xfc0007fe, 0xfc00004c, "%{RC} f%{D},f%{A},f%{C}" },
44284c41355Smiod 	{ "fneg",	0xfc0007fe, 0xfc000050, "%{RC} f%{D},f%{A},f%{C}" },
44384c41355Smiod 	{ "mcrfs",	0xfc0007fe, 0xfc000080, "%{RC} f%{D},f%{A},f%{C}" },
44484c41355Smiod 	{ "mtfsb0",	0xfc0007fe, 0xfc00008c, "%{RC} %{crfD},f%{C}" },
44584c41355Smiod 	{ "fmr",	0xfc0007fe, 0xfc000090, "%{RC} f%{D},f%{B}" },
44684c41355Smiod 	{ "mtfsfi",	0xfc0007fe, 0xfc00010c, "%{RC} %{crfD},f%{C},%{IMM}" },
44784c41355Smiod 
44884c41355Smiod 	{ "fnabs",	0xfc0007fe, 0xfc000110, "%{RC} f%{D},f%{B}" },
44984c41355Smiod 	{ "fabs",	0xfc0007fe, 0xfc000210, "%{RC} f%{D},f%{B}" },
45084c41355Smiod 	{ "mffs",	0xfc0007fe, 0xfc00048e, "%{RC} f%{D},f%{B}" },
45184c41355Smiod 	{ "mtfsf",	0xfc0007fe, 0xfc00058e, "%{RC} %{FM},f%{B}" },
45284c41355Smiod 	{ "fctid",	0xfc0007fe, 0xfc00065c, "%{RC} f%{D},f%{B}" },
45384c41355Smiod 	{ "fctidz",	0xfc0007fe, 0xfc00065e, "%{RC} f%{D},f%{B}" },
45484c41355Smiod 	{ "fcfid",	0xfc0007fe, 0xfc00069c, "%{RC} f%{D},f%{B}" },
45584c41355Smiod 	{ "",		0x0,		0x0, "" }
45684c41355Smiod };
45784c41355Smiod 
45884c41355Smiod void
45984c41355Smiod op_ill(u_int32_t addr, instr_t instr)
46084c41355Smiod {
46184c41355Smiod 	db_printf("illegal instruction %x\n", instr);
46284c41355Smiod }
46384c41355Smiod 
46492383dfeSdrahn /*
46592383dfeSdrahn  * Extracts bits out of an instruction opcode, base indicates the lsb
46692383dfeSdrahn  * to keep.
46792383dfeSdrahn  * Note that this uses the PowerPC bit number for base, MSb == 0
46892383dfeSdrahn  * because all of the documentation is written that way.
46992383dfeSdrahn  */
47084c41355Smiod u_int32_t
47184c41355Smiod extract_field(u_int32_t value, u_int32_t base, u_int32_t width)
47284c41355Smiod {
47384c41355Smiod 	u_int32_t mask = (1 << width) - 1;
47492383dfeSdrahn 	return ((value >> (31 - base)) & mask);
47584c41355Smiod }
47684c41355Smiod 
47784c41355Smiod char *db_BOBI_cond[] = {
47884c41355Smiod 	"ge",
47984c41355Smiod 	"le",
48084c41355Smiod 	"ne",
48184c41355Smiod 	"ns",
48284c41355Smiod 	"lt",
48384c41355Smiod 	"gt",
48484c41355Smiod 	"eq",
48584c41355Smiod 	"so"
48684c41355Smiod };
48784c41355Smiod /* what about prediction directions? */
48884c41355Smiod char *db_BO_op[] = {
489cf7a1709Sdrahn 	"dnzf",
490cf7a1709Sdrahn 	"dnzf-",
491cf7a1709Sdrahn 	"dzf",
492cf7a1709Sdrahn 	"dzf-",
49384c41355Smiod 	"",
49484c41355Smiod 	"",
49584c41355Smiod 	"",
49684c41355Smiod 	"",
497cf7a1709Sdrahn 	"dnzt",
498cf7a1709Sdrahn 	"dnzt-",
499cf7a1709Sdrahn 	"dzt",
500cf7a1709Sdrahn 	"dzt-",
50184c41355Smiod 	"",
50284c41355Smiod 	"",
50384c41355Smiod 	"",
50484c41355Smiod 	"",
50584c41355Smiod 	"dnz",
50684c41355Smiod 	"dnz",
50784c41355Smiod 	"dz",
50884c41355Smiod 	"dz",
50984c41355Smiod 	"",
51084c41355Smiod 	"",
51184c41355Smiod 	"",
51284c41355Smiod 	"",
51384c41355Smiod 	"dnz",
51484c41355Smiod 	"dnz",
51584c41355Smiod 	"dz",
51684c41355Smiod 	"dz",
51784c41355Smiod 	"",
51884c41355Smiod 	"",
51984c41355Smiod 	"",
52084c41355Smiod 	""
52184c41355Smiod };
52284c41355Smiod 
523cf7a1709Sdrahn char *BItbl[] = {
524cf7a1709Sdrahn 	"", "gt", "eq", "so"
525cf7a1709Sdrahn };
526cf7a1709Sdrahn 
527cf7a1709Sdrahn char BO_uses_tbl[32] = {
528cf7a1709Sdrahn 	/* 0 */ 1,
529cf7a1709Sdrahn 	/* 1 */ 1,
530cf7a1709Sdrahn 	/* 2 */ 1,
531cf7a1709Sdrahn 	/* 3 */ 1,
532cf7a1709Sdrahn 	/* 4 */ 0,
533cf7a1709Sdrahn 	/* 5 */ 0,
534cf7a1709Sdrahn 	/* 6 */ 0, /* invalid */
535cf7a1709Sdrahn 	/* 7 */ 0, /* invalid */
536cf7a1709Sdrahn 	/* 8 */ 1,
537cf7a1709Sdrahn 	/* 9 */ 1,
538cf7a1709Sdrahn 	/* a */ 1,
539cf7a1709Sdrahn 	/* b */ 1,
540cf7a1709Sdrahn 	/* c */ 0,
541cf7a1709Sdrahn 	/* d */ 0,
542cf7a1709Sdrahn 	/* e */ 0, /* invalid */
543cf7a1709Sdrahn 	/* f */ 1,
544cf7a1709Sdrahn 	/* 10 */        1,
545cf7a1709Sdrahn 	/* 11 */        1,
546cf7a1709Sdrahn 	/* 12 */        1,
547cf7a1709Sdrahn 	/* 13 */        1,
548cf7a1709Sdrahn 	/* 14 */        1,
549cf7a1709Sdrahn 	/* 15 */        0, /* invalid */
550cf7a1709Sdrahn 	/* 16 */        0, /* invalid */
551cf7a1709Sdrahn 	/* 17 */        0, /* invalid */
552cf7a1709Sdrahn 	/* 18 */        0, /* invalid */
553cf7a1709Sdrahn 	/* 19 */        0, /* invalid */
554cf7a1709Sdrahn 	/* 1a */        0, /* invalid */
555cf7a1709Sdrahn 	/* 1b */        0, /* invalid */
556cf7a1709Sdrahn 	/* 1c */        0, /* invalid */
557cf7a1709Sdrahn 	/* 1d */        0, /* invalid */
558cf7a1709Sdrahn 	/* 1e */        0, /* invalid */
559cf7a1709Sdrahn 	/* 1f */        0, /* invalid */
560cf7a1709Sdrahn };
561cf7a1709Sdrahn 
56284c41355Smiod void
56310691430Sdrahn disasm_process_field(u_int32_t addr, instr_t instr, char **ppfmt,
56410691430Sdrahn     char *disasm_buf, size_t bufsize)
56584c41355Smiod {
56684c41355Smiod 	char field [8];
56710691430Sdrahn 	char lbuf[50];
56884c41355Smiod 	int i;
56984c41355Smiod 	char *pfmt = *ppfmt;
57084c41355Smiod 	enum opf opf;
571*949c1c4eSmiod 	const char *name;
57284c41355Smiod 	db_expr_t offset;
57384c41355Smiod 
57484c41355Smiod 	/* find field */
57584c41355Smiod 	if (pfmt[0] != '%' || pfmt[1] != '{') {
57684c41355Smiod 		printf("error in disasm fmt [%s]\n", pfmt);
57784c41355Smiod 	}
57884c41355Smiod 	pfmt = &pfmt[2];
57910691430Sdrahn 	for (i = 0;
58010691430Sdrahn 	    pfmt[i] != '\0' && pfmt[i] != '}' && i < sizeof(field);
58110691430Sdrahn 	    i++) {
58284c41355Smiod 		field[i] = pfmt[i];
58384c41355Smiod 	}
58410691430Sdrahn 	if (i == sizeof(field)) {
58510691430Sdrahn 		printf("error in disasm fmt [%s]\n", pfmt);
58610691430Sdrahn 		return;
58710691430Sdrahn 	}
58884c41355Smiod 	field[i] = 0;
58984c41355Smiod 	if (pfmt[i] == '\0') {
59010691430Sdrahn 		/* match following close paren { */
59184c41355Smiod 		printf("disasm_process_field: missing } in [%s]\n", pfmt);
59284c41355Smiod 	}
59384c41355Smiod 	*ppfmt = &pfmt[i+1];
59484c41355Smiod 	opf = Opf_INVALID;
59584c41355Smiod 	for (i = 0; db_fields[i].name != NULL; i++) {
59684c41355Smiod 		if (strcmp(db_fields[i].name, field) == 0) {
59784c41355Smiod 			opf = db_fields[i].opf;
59884c41355Smiod 			break;
59984c41355Smiod 		}
60084c41355Smiod 	}
60184c41355Smiod 	switch (opf) {
60284c41355Smiod 	case Opf_INVALID:
60384c41355Smiod 		{
60484c41355Smiod 			printf("unable to find variable [%s]\n", field);
60584c41355Smiod 		}
60684c41355Smiod 	case Opf_A:
60784c41355Smiod 		{
60884c41355Smiod 			u_int A;
60992383dfeSdrahn 			A = extract_field(instr, 15, 5);
61010691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "r%d", A);
61110691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
61284c41355Smiod 		}
61384c41355Smiod 		break;
61484c41355Smiod 	case Opf_A0:
61584c41355Smiod 		{
61684c41355Smiod 			u_int A;
61792383dfeSdrahn 			A = extract_field(instr, 15, 5);
61884c41355Smiod 			if (A != 0) {
61910691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "r%d,", A);
62010691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
62184c41355Smiod 			}
62284c41355Smiod 		}
62384c41355Smiod 		break;
62484c41355Smiod 	case Opf_AA:
62584c41355Smiod 		if (instr & 0x2) {
62610691430Sdrahn 			strlcat (disasm_buf, "a", bufsize);
62784c41355Smiod 		}
62884c41355Smiod 		break;
62984c41355Smiod 	case Opf_LI:
63084c41355Smiod 		{
63184c41355Smiod 			u_int LI;
63292383dfeSdrahn 			LI = extract_field(instr, 29, 24);
63384c41355Smiod 			LI = LI << 2;
6348cc1443cSdrahn 			if (LI & 0x02000000) {
6358cc1443cSdrahn 				LI |= ~0x03ffffff;
63684c41355Smiod 			}
63784c41355Smiod 			if ((instr & (1 << 1)) == 0) {
63884c41355Smiod 				/* CHECK AA bit */
63984c41355Smiod 				LI = addr + LI;
64084c41355Smiod 			}
64184c41355Smiod 			db_find_sym_and_offset(LI, &name, &offset);
64284c41355Smiod 			if (name) {
64384c41355Smiod 				if (offset == 0) {
64410691430Sdrahn 					snprintf(lbuf, sizeof (lbuf),
64510691430Sdrahn 					    "0x%x (%s)", LI, name);
64610691430Sdrahn 					strlcat (disasm_buf, lbuf, bufsize);
64784c41355Smiod 				} else {
64810691430Sdrahn 					snprintf(lbuf, sizeof (lbuf),
649a9c4d1a2Smiod 					    "0x%x (%s+0x%lx)", LI, name,
65010691430Sdrahn 					    offset);
65110691430Sdrahn 					strlcat (disasm_buf, lbuf, bufsize);
65284c41355Smiod 				}
65384c41355Smiod 			} else {
65410691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "0x%x", LI);
65510691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
65684c41355Smiod 			}
65784c41355Smiod 		}
65884c41355Smiod 		break;
65984c41355Smiod 	case Opf_B:
66084c41355Smiod 		{
66184c41355Smiod 			u_int B;
66292383dfeSdrahn 			B = extract_field(instr, 20, 5);
66310691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "r%d", B);
66410691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
66584c41355Smiod 		}
66684c41355Smiod 		break;
66784c41355Smiod 	case Opf_BD:
66884c41355Smiod 		{
6693a859567Skettenis 			int BD;
67092383dfeSdrahn 			BD = extract_field(instr, 29, 14);
67184c41355Smiod 			BD = BD << 2;
67284c41355Smiod 			if (BD & 0x00008000) {
6733a859567Skettenis 				BD |= ~0x00007fff;
67484c41355Smiod 			}
67584c41355Smiod 			if ((instr & (1 << 1)) == 0) {
67684c41355Smiod 				/* CHECK AA bit */
67784c41355Smiod 				BD = addr + BD;
67884c41355Smiod 			}
67984c41355Smiod 			db_find_sym_and_offset(BD, &name, &offset);
68084c41355Smiod 			if (name) {
68184c41355Smiod 				if (offset == 0) {
68210691430Sdrahn 					snprintf(lbuf, sizeof (lbuf),
68310691430Sdrahn 					    "0x%x (%s)", BD, name);
68410691430Sdrahn 					strlcat (disasm_buf, lbuf, bufsize);
68584c41355Smiod 				} else {
68610691430Sdrahn 					snprintf(lbuf, sizeof (lbuf),
687a9c4d1a2Smiod 					    "0x%x (%s+0x%lx)", BD, name, offset);
68810691430Sdrahn 					strlcat (disasm_buf, lbuf, bufsize);
68984c41355Smiod 				}
69084c41355Smiod 			} else {
69110691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "0x%x", BD);
69210691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
69384c41355Smiod 			}
69484c41355Smiod 		}
69584c41355Smiod 		break;
696cf7a1709Sdrahn 	case Opf_BI1:
69784c41355Smiod 	case Opf_BI:
69884c41355Smiod 		{
699cf7a1709Sdrahn 			int BO, BI, cr, printcomma = 0;
70092383dfeSdrahn 			BO = extract_field(instr, 10, 5);
70192383dfeSdrahn 			BI = extract_field(instr, 15, 5);
702cf7a1709Sdrahn 			cr =  (BI >> 2) & 7;
703cf7a1709Sdrahn 			if (cr != 0) {
70410691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "cr%d", cr);
70510691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
706cf7a1709Sdrahn 				printcomma = 1;
70784c41355Smiod 			}
708cf7a1709Sdrahn 			if (BO_uses_tbl[BO]) {
70910691430Sdrahn 				if ((cr != 0) && ((BI & 3) != 0) &&
71010691430Sdrahn 				    BO_uses_tbl[BO] != 0)
71110691430Sdrahn 					strlcat (disasm_buf, "+", bufsize);
71210691430Sdrahn 
71310691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "%s",
71410691430Sdrahn 				    BItbl[BI & 3]);
71510691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
716cf7a1709Sdrahn 				printcomma = 1;
71784c41355Smiod 			}
718cf7a1709Sdrahn 			if ((opf == Opf_BI) && printcomma)
71910691430Sdrahn 				strlcat (disasm_buf, ",", bufsize);
72084c41355Smiod 		}
72184c41355Smiod 		break;
72284c41355Smiod 	case Opf_BO:
72384c41355Smiod 		{
72484c41355Smiod 			int BO, BI;
72592383dfeSdrahn 			BO = extract_field(instr, 10, 5);
72610691430Sdrahn 			strlcat (disasm_buf, db_BO_op[BO], bufsize);
727cf7a1709Sdrahn 			if ((BO & 4) != 0) {
72892383dfeSdrahn 				BI = extract_field(instr, 15, 5);
72910691430Sdrahn 				strlcat (disasm_buf,
73010691430Sdrahn 				    db_BOBI_cond[(BI & 0x3)| (((BO & 8) >> 1))],
73110691430Sdrahn 				    bufsize);
73284c41355Smiod 
733cf7a1709Sdrahn 				if (BO & 1)
73410691430Sdrahn 					strlcat (disasm_buf, "-", bufsize);
73584c41355Smiod 			}
73684c41355Smiod 		}
73784c41355Smiod 		break;
73884c41355Smiod 	case Opf_C:
73984c41355Smiod 		{
74084c41355Smiod 			u_int C;
74192383dfeSdrahn 			C = extract_field(instr, 25, 5);
74210691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "r%d, ", C);
74310691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
74484c41355Smiod 		}
74584c41355Smiod 		break;
74684c41355Smiod 	case Opf_CRM:
74784c41355Smiod 		{
74884c41355Smiod 			u_int CRM;
74992383dfeSdrahn 			CRM = extract_field(instr, 19, 8);
75010691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "0x%x", CRM);
75110691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
75284c41355Smiod 		}
75384c41355Smiod 		break;
75484c41355Smiod 	case Opf_FM:
75584c41355Smiod 		{
75684c41355Smiod 			u_int FM;
75792383dfeSdrahn 			FM = extract_field(instr, 10, 8);
75810691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", FM);
75910691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
76084c41355Smiod 		}
76184c41355Smiod 		break;
76284c41355Smiod 	case Opf_LK:
76384c41355Smiod 		if (instr & 0x1) {
76410691430Sdrahn 			strlcat (disasm_buf, "l", bufsize);
76584c41355Smiod 		}
76684c41355Smiod 		break;
76784c41355Smiod 	case Opf_MB:
76884c41355Smiod 		{
76984c41355Smiod 			u_int MB;
77092383dfeSdrahn 			MB = extract_field(instr, 20, 5);
77110691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", MB);
77210691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
77384c41355Smiod 		}
77484c41355Smiod 		break;
77584c41355Smiod 	case Opf_ME:
77684c41355Smiod 		{
77784c41355Smiod 			u_int ME;
77892383dfeSdrahn 			ME = extract_field(instr, 25, 5);
77910691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", ME);
78010691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
78184c41355Smiod 		}
78284c41355Smiod 		break;
78384c41355Smiod 	case Opf_NB:
78484c41355Smiod 		{
78584c41355Smiod 			u_int NB;
78692383dfeSdrahn 			NB = extract_field(instr, 20, 5);
78784c41355Smiod 			if (NB == 0 ) {
78884c41355Smiod 				NB=32;
78984c41355Smiod 			}
79010691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", NB);
79110691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
79284c41355Smiod 		}
79384c41355Smiod 		break;
79484c41355Smiod 	case Opf_OE:
79584c41355Smiod 		if (instr & (1 << (31-21))) {
79610691430Sdrahn 			strlcat (disasm_buf, "o", bufsize);
79784c41355Smiod 		}
79884c41355Smiod 		break;
79984c41355Smiod 	case Opf_RC:
80084c41355Smiod 		if (instr & 0x1) {
80110691430Sdrahn 			strlcat (disasm_buf, ".", bufsize);
80284c41355Smiod 		}
80384c41355Smiod 		break;
80484c41355Smiod 	case Opf_S:
80584c41355Smiod 	case Opf_D:
80684c41355Smiod 		{
80784c41355Smiod 			u_int D;
80884c41355Smiod 			/* S and D are the same */
80992383dfeSdrahn 			D = extract_field(instr, 10, 5);
81010691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "r%d", D);
81110691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
81284c41355Smiod 		}
81384c41355Smiod 		break;
81484c41355Smiod 	case Opf_SH:
81584c41355Smiod 		{
81684c41355Smiod 			u_int SH;
81792383dfeSdrahn 			SH = extract_field(instr, 20, 5);
81810691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", SH);
81910691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
82084c41355Smiod 		}
82184c41355Smiod 		break;
82284c41355Smiod 	case Opf_SIMM:
82384c41355Smiod 	case Opf_d:
82484c41355Smiod 		{
8253a859567Skettenis 			int IMM;
82692383dfeSdrahn 			IMM = extract_field(instr, 31, 16);
82710691430Sdrahn 			if (IMM & 0x8000)
82884c41355Smiod 				IMM |= ~0x7fff;
82910691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", IMM);
83010691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
83184c41355Smiod 		}
83284c41355Smiod 		break;
83384c41355Smiod 	case Opf_UIMM:
83484c41355Smiod 		{
8353a859567Skettenis 			u_int IMM;
83692383dfeSdrahn 			IMM = extract_field(instr, 31, 16);
83710691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "0x%x", IMM);
83810691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
83984c41355Smiod 		}
84084c41355Smiod 		break;
84184c41355Smiod 	case Opf_SR:
84284c41355Smiod 		{
84384c41355Smiod 			u_int SR;
84492383dfeSdrahn 			SR = extract_field(instr, 15, 3);
84510691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "sr%d", SR);
84610691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
84784c41355Smiod 		}
84884c41355Smiod 		break;
84984c41355Smiod 	case Opf_TO:
85084c41355Smiod 		{
85184c41355Smiod 			u_int TO;
85292383dfeSdrahn 			TO = extract_field(instr, 10, 1);
85310691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", TO);
85410691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
85584c41355Smiod 		}
85684c41355Smiod 		break;
85784c41355Smiod 	case Opf_crbA:
85884c41355Smiod 		{
85984c41355Smiod 			u_int crbA;
86092383dfeSdrahn 			crbA = extract_field(instr, 15, 5);
86110691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", crbA);
86210691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
86384c41355Smiod 		}
86484c41355Smiod 		break;
86584c41355Smiod 	case Opf_crbB:
86684c41355Smiod 		{
86784c41355Smiod 			u_int crbB;
86892383dfeSdrahn 			crbB = extract_field(instr, 20, 5);
86910691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", crbB);
87010691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
87184c41355Smiod 		}
87284c41355Smiod 		break;
87384c41355Smiod 	case Opf_crbD:
87484c41355Smiod 		{
87584c41355Smiod 			u_int crfD;
87692383dfeSdrahn 			crfD = extract_field(instr, 8, 3);
87710691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
87810691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
87984c41355Smiod 		}
88084c41355Smiod 		break;
88184c41355Smiod 	case Opf_crfD:
88284c41355Smiod 		{
88384c41355Smiod 			u_int crfD;
88492383dfeSdrahn 			crfD = extract_field(instr, 8, 3);
88510691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "crf%d", crfD);
88610691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
88784c41355Smiod 		}
88884c41355Smiod 		break;
88984c41355Smiod 	case Opf_crfS:
89084c41355Smiod 		{
89184c41355Smiod 			u_int crfS;
89292383dfeSdrahn 			crfS = extract_field(instr, 13, 3);
89310691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), "%d", crfS);
89410691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
89584c41355Smiod 		}
89684c41355Smiod 		break;
8975f35ad5dSgkoehler 	case Opf_ds:
8985f35ad5dSgkoehler 		{
8993a859567Skettenis 			int ds;
9005f35ad5dSgkoehler 			ds = extract_field(instr, 29, 14);
9015f35ad5dSgkoehler 			ds = ds << 2;
9025f35ad5dSgkoehler 			if (ds & 0x8000)
9035f35ad5dSgkoehler 				ds |= ~0x7fff;
9045f35ad5dSgkoehler 			snprintf(lbuf, sizeof (lbuf), "%d", ds);
9055f35ad5dSgkoehler 			strlcat (disasm_buf, lbuf, bufsize);
9065f35ad5dSgkoehler 		}
9075f35ad5dSgkoehler 		break;
90884c41355Smiod 	case Opf_mb:
90984c41355Smiod 		{
91084c41355Smiod 			u_int mb, mbl, mbh;
91192383dfeSdrahn 			mbl = extract_field(instr, 25, 4);
91292383dfeSdrahn 			mbh = extract_field(instr, 26, 1);
91384c41355Smiod 			mb = mbh << 4 | mbl;
91410691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), ", %d", mb);
91510691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
91684c41355Smiod 		}
91784c41355Smiod 		break;
91884c41355Smiod 	case Opf_sh:
91984c41355Smiod 		{
92084c41355Smiod 			u_int sh, shl, shh;
92192383dfeSdrahn 			shl = extract_field(instr, 19, 4);
92292383dfeSdrahn 			shh = extract_field(instr, 20, 1);
92384c41355Smiod 			sh = shh << 4 | shl;
92410691430Sdrahn 			snprintf(lbuf, sizeof (lbuf), ", %d", sh);
92510691430Sdrahn 			strlcat (disasm_buf, lbuf, bufsize);
92684c41355Smiod 		}
92784c41355Smiod 		break;
92884c41355Smiod 	case Opf_spr:
92984c41355Smiod 		{
93084c41355Smiod 			u_int spr;
93184c41355Smiod 			u_int sprl;
93284c41355Smiod 			u_int sprh;
93384c41355Smiod 			char *reg;
93492383dfeSdrahn 			sprl = extract_field(instr, 15, 5);
93592383dfeSdrahn 			sprh = extract_field(instr, 20, 5);
93684c41355Smiod 			spr = sprh << 5 | sprl;
93784c41355Smiod 
93884c41355Smiod 			/* this table could be written better */
93984c41355Smiod 			switch (spr) {
94084c41355Smiod 			case	1:
94184c41355Smiod 				reg = "xer";
94284c41355Smiod 				break;
94384c41355Smiod 			case	8:
94484c41355Smiod 				reg = "lr";
94584c41355Smiod 				break;
94684c41355Smiod 			case	9:
94784c41355Smiod 				reg = "ctr";
94884c41355Smiod 				break;
94984c41355Smiod 			case	18:
95084c41355Smiod 				reg = "dsisr";
95184c41355Smiod 				break;
95284c41355Smiod 			case	19:
95384c41355Smiod 				reg = "dar";
95484c41355Smiod 				break;
95584c41355Smiod 			case	22:
95684c41355Smiod 				reg = "dec";
95784c41355Smiod 				break;
95884c41355Smiod 			case	25:
95984c41355Smiod 				reg = "sdr1";
96084c41355Smiod 				break;
96184c41355Smiod 			case	26:
96284c41355Smiod 				reg = "srr0";
96384c41355Smiod 				break;
96484c41355Smiod 			case	27:
96584c41355Smiod 				reg = "srr1";
96684c41355Smiod 				break;
96784c41355Smiod 			case	272:
96884c41355Smiod 				reg = "SPRG0";
96984c41355Smiod 				break;
97084c41355Smiod 			case	273:
97184c41355Smiod 				reg = "SPRG1";
97284c41355Smiod 				break;
97384c41355Smiod 			case	274:
97484c41355Smiod 				reg = "SPRG3";
97584c41355Smiod 				break;
97684c41355Smiod 			case	275:
97784c41355Smiod 				reg = "SPRG3";
97884c41355Smiod 				break;
97984c41355Smiod 			case	280:
98084c41355Smiod 				reg = "asr";
98184c41355Smiod 				break;
98284c41355Smiod 			case	282:
98384c41355Smiod 				reg = "aer";
98484c41355Smiod 				break;
98584c41355Smiod 			case	287:
98684c41355Smiod 				reg = "pvr";
98784c41355Smiod 				break;
98884c41355Smiod 			case	528:
98984c41355Smiod 				reg = "ibat0u";
99084c41355Smiod 				break;
99184c41355Smiod 			case	529:
99284c41355Smiod 				reg = "ibat0l";
99384c41355Smiod 				break;
99484c41355Smiod 			case	530:
99584c41355Smiod 				reg = "ibat1u";
99684c41355Smiod 				break;
99784c41355Smiod 			case	531:
99884c41355Smiod 				reg = "ibat1l";
99984c41355Smiod 				break;
100084c41355Smiod 			case	532:
100184c41355Smiod 				reg = "ibat2u";
100284c41355Smiod 				break;
100384c41355Smiod 			case	533:
100484c41355Smiod 				reg = "ibat2l";
100584c41355Smiod 				break;
100684c41355Smiod 			case	534:
100784c41355Smiod 				reg = "ibat3u";
100884c41355Smiod 				break;
100984c41355Smiod 			case	535:
101084c41355Smiod 				reg = "ibat3l";
101184c41355Smiod 				break;
101284c41355Smiod 			case	536:
101384c41355Smiod 				reg = "dbat0u";
101484c41355Smiod 				break;
101584c41355Smiod 			case	537:
101684c41355Smiod 				reg = "dbat0l";
101784c41355Smiod 				break;
101884c41355Smiod 			case	538:
101984c41355Smiod 				reg = "dbat1u";
102084c41355Smiod 				break;
102184c41355Smiod 			case	539:
102284c41355Smiod 				reg = "dbat1l";
102384c41355Smiod 				break;
102484c41355Smiod 			case	540:
102584c41355Smiod 				reg = "dbat2u";
102684c41355Smiod 				break;
102784c41355Smiod 			case	541:
102884c41355Smiod 				reg = "dbat2l";
102984c41355Smiod 				break;
103084c41355Smiod 			case	542:
103184c41355Smiod 				reg = "dbat3u";
103284c41355Smiod 				break;
103384c41355Smiod 			case	543:
103484c41355Smiod 				reg = "dbat3l";
103584c41355Smiod 				break;
103684c41355Smiod 			case	1013:
103784c41355Smiod 				reg = "dabr";
103884c41355Smiod 				break;
103984c41355Smiod 			default:
104084c41355Smiod 				reg = 0;
104184c41355Smiod 			}
104284c41355Smiod 			if (reg == 0) {
104310691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "spr%d", spr);
104410691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
104584c41355Smiod 			} else {
104610691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "%s", reg);
104710691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
104884c41355Smiod 			}
104984c41355Smiod 		}
105084c41355Smiod 		break;
105184c41355Smiod 	case Opf_tbr:
105284c41355Smiod 		{
105384c41355Smiod 			u_int tbr;
105484c41355Smiod 			u_int tbrl;
105584c41355Smiod 			u_int tbrh;
105610691430Sdrahn 			char *reg = NULL;
105792383dfeSdrahn 			tbrl = extract_field(instr, 15, 5);
105892383dfeSdrahn 			tbrh = extract_field(instr, 20, 5);
105984c41355Smiod 			tbr = tbrh << 5 | tbrl;
106084c41355Smiod 
106184c41355Smiod 			switch (tbr) {
106284c41355Smiod 			case 268:
106384c41355Smiod 				reg = "tbl";
106484c41355Smiod 				break;
106584c41355Smiod 			case 269:
106684c41355Smiod 				reg = "tbu";
106784c41355Smiod 				break;
106884c41355Smiod 			default:
106984c41355Smiod 				reg = 0;
107084c41355Smiod 			}
107110691430Sdrahn 			if (reg == NULL) {
107210691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "tbr%d", tbr);
107310691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
107484c41355Smiod 			} else {
107510691430Sdrahn 				snprintf(lbuf, sizeof (lbuf), "%s", reg);
107610691430Sdrahn 				strlcat (disasm_buf, lbuf, bufsize);
107784c41355Smiod 			}
107884c41355Smiod 		}
107984c41355Smiod 		break;
108084c41355Smiod 	}
108184c41355Smiod }
108284c41355Smiod 
108384c41355Smiod void
108410691430Sdrahn disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr,
108510691430Sdrahn     char *disasm_str, size_t bufsize)
108684c41355Smiod {
108784c41355Smiod 	char *pfmt;
108810691430Sdrahn 	char cbuf[2];
108984c41355Smiod 	if (popcode->decode_str == NULL || popcode->decode_str[0] == '0') {
109084c41355Smiod 		return;
109184c41355Smiod 	}
109284c41355Smiod 	pfmt = popcode->decode_str;
10931d052456Sdrahn 	disasm_str[0] = '\0';
109484c41355Smiod 
109584c41355Smiod 	while (*pfmt != '\0')  {
109684c41355Smiod 		if (*pfmt == '%') {
109710691430Sdrahn 			disasm_process_field(addr, instr, &pfmt, disasm_str,
109810691430Sdrahn 			    bufsize);
109984c41355Smiod 		} else {
110010691430Sdrahn 			cbuf[0] = *pfmt;
110110691430Sdrahn 			cbuf[1] = '\0';
110210691430Sdrahn 			strlcat(disasm_str, cbuf, bufsize);
110384c41355Smiod 			pfmt++;
110484c41355Smiod 		}
110584c41355Smiod 	}
110684c41355Smiod }
110784c41355Smiod 
110884c41355Smiod void
110984c41355Smiod op_base(u_int32_t addr, instr_t instr)
111084c41355Smiod {
111184c41355Smiod 	dis_ppc(addr, opcodes, instr);
111284c41355Smiod }
111384c41355Smiod 
111484c41355Smiod void
111584c41355Smiod op_cl_x13(u_int32_t addr, instr_t instr)
111684c41355Smiod {
111784c41355Smiod 	dis_ppc(addr, opcodes_13, instr);
111884c41355Smiod }
111984c41355Smiod 
112084c41355Smiod void
112184c41355Smiod op_cl_x1e(u_int32_t addr, instr_t instr)
112284c41355Smiod {
112384c41355Smiod 	dis_ppc(addr, opcodes_1e, instr);
112484c41355Smiod }
112584c41355Smiod 
112684c41355Smiod void
112784c41355Smiod op_cl_x1f(u_int32_t addr, instr_t instr)
112884c41355Smiod {
112984c41355Smiod 	dis_ppc(addr, opcodes_1f, instr);
113084c41355Smiod }
113184c41355Smiod 
113284c41355Smiod void
113384c41355Smiod op_cl_x3a(u_int32_t addr, instr_t instr)
113484c41355Smiod {
113584c41355Smiod 	dis_ppc(addr, opcodes_3a, instr);
113684c41355Smiod }
113784c41355Smiod 
113884c41355Smiod void
113984c41355Smiod op_cl_x3b(u_int32_t addr, instr_t instr)
114084c41355Smiod {
114184c41355Smiod 	dis_ppc(addr, opcodes_3b, instr);
114284c41355Smiod }
114384c41355Smiod 
114484c41355Smiod void
114584c41355Smiod op_cl_x3e(u_int32_t addr, instr_t instr)
114684c41355Smiod {
114784c41355Smiod 	dis_ppc(addr, opcodes_3e, instr);
114884c41355Smiod }
114984c41355Smiod 
115084c41355Smiod void
115184c41355Smiod op_cl_x3f(u_int32_t addr, instr_t instr)
115284c41355Smiod {
115384c41355Smiod 	dis_ppc(addr, opcodes_3f, instr);
115484c41355Smiod }
115584c41355Smiod 
115684c41355Smiod void
115784c41355Smiod dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr)
115884c41355Smiod {
115984c41355Smiod 	const struct opcode *op;
116084c41355Smiod 	int i;
116110691430Sdrahn 	char disasm_str[80];
116284c41355Smiod 
11638016f8a7Sdrahn 	for (i=0; opcodeset[i].mask != 0; i++) {
11648016f8a7Sdrahn 		op = &opcodeset[i];
116584c41355Smiod 		if ((instr & op->mask) == op->code) {
116610691430Sdrahn 			disasm_fields(addr, op, instr, disasm_str,
116710691430Sdrahn 			    sizeof disasm_str);
1168b04037b0Sdrahn 			db_printf("%s%s\n", op->name, disasm_str);
116984c41355Smiod 			return;
117084c41355Smiod 		}
117184c41355Smiod 	}
117284c41355Smiod 	op_ill(addr, instr);
117384c41355Smiod }
117484c41355Smiod 
117552de38dfSmpi vaddr_t
117652de38dfSmpi db_disasm(vaddr_t loc, int extended)
117784c41355Smiod {
117884c41355Smiod 	int class;
117984c41355Smiod 	instr_t opcode;
118084c41355Smiod 	opcode = *(instr_t *)(loc);
118184c41355Smiod 	class = opcode >> 26;
118284c41355Smiod 	(opcodes_base[class])(loc, opcode);
118384c41355Smiod 
118484c41355Smiod 	return loc + 4;
118584c41355Smiod }
1186