199730Sbenno/* $FreeBSD$ */ 299730Sbenno/* $NetBSD: db_disasm.c,v 1.12 2002/01/05 22:07:26 jhawk Exp $ */ 399730Sbenno/* $OpenBSD: db_disasm.c,v 1.2 1996/12/28 06:21:48 rahnds Exp $ */ 499730Sbenno 599730Sbenno#include <sys/param.h> 699730Sbenno#include <sys/proc.h> 799730Sbenno#include <sys/systm.h> 899730Sbenno 999730Sbenno#include <machine/db_machdep.h> 1099730Sbenno#include <machine/trap.h> 1199730Sbenno 1299730Sbenno#include <ddb/ddb.h> 1399730Sbenno#include <ddb/db_access.h> 1499730Sbenno#include <ddb/db_sym.h> 1599730Sbenno#include <ddb/db_variables.h> 1699730Sbenno#include <ddb/db_output.h> 1799730Sbenno 1899730Sbennoenum function_mask { 1999730Sbenno Op_A = 0x00000001, 2099730Sbenno Op_B = 0x00000002, 2199730Sbenno Op_BI = 0x00000004, 2299730Sbenno Op_BO = 0x00000008, 2399730Sbenno Op_CRM = 0x00000010, 2499730Sbenno Op_D = 0x00000020, /* yes, Op_S and Op_D are the same */ 2599730Sbenno Op_S = 0x00000020, 2699730Sbenno Op_FM = 0x00000040, 2799730Sbenno Op_IMM = 0x00000080, 2899730Sbenno Op_LK = 0x00000100, 2999730Sbenno Op_Rc = 0x00000200, 3099730Sbenno Op_AA = Op_LK | Op_Rc, /* kludge (reduce Op_s) */ 3199730Sbenno Op_LKM = Op_AA, 3299730Sbenno Op_RcM = Op_AA, 3399730Sbenno Op_OE = 0x00000400, 3499730Sbenno Op_SR = 0x00000800, 3599730Sbenno Op_TO = 0x00001000, 3699730Sbenno Op_sign = 0x00002000, 3799730Sbenno Op_const = 0x00004000, 3899730Sbenno Op_SIMM = Op_const | Op_sign, 3999730Sbenno Op_UIMM = Op_const, 4099730Sbenno Op_d = Op_const | Op_sign, 4199730Sbenno Op_crbA = 0x00008000, 4299730Sbenno Op_crbB = 0x00010000, 4399730Sbenno Op_WS = Op_crbB, /* kludge, same field as crbB */ 4499730Sbenno Op_crbD = 0x00020000, 4599730Sbenno Op_crfD = 0x00040000, 4699730Sbenno Op_crfS = 0x00080000, 4799730Sbenno Op_ds = 0x00100000, 4899730Sbenno Op_me = 0x00200000, 4999730Sbenno Op_spr = 0x00400000, 5099730Sbenno Op_dcr = Op_spr, /* out of bits - cheat with Op_spr */ 5199730Sbenno Op_tbr = 0x00800000, 5299730Sbenno 5399730Sbenno Op_L = 0x01000000, 5499730Sbenno Op_BD = 0x02000000, 5599730Sbenno Op_LI = 0x04000000, 5699730Sbenno Op_C = 0x08000000, 5799730Sbenno 5899730Sbenno Op_NB = 0x10000000, 5999730Sbenno 6099730Sbenno Op_sh_mb_sh = 0x20000000, 6199730Sbenno Op_sh = 0x40000000, 6299730Sbenno Op_SH = Op_sh | Op_sh_mb_sh, 6399730Sbenno Op_mb = 0x80000000, 6499730Sbenno Op_MB = Op_mb | Op_sh_mb_sh, 6599730Sbenno Op_ME = Op_MB, 6699730Sbenno 6799730Sbenno}; 6899730Sbenno 6999730Sbennostruct opcode { 7099730Sbenno char *name; 7199730Sbenno u_int32_t mask; 7299730Sbenno u_int32_t code; 7399730Sbenno enum function_mask func; 7499730Sbenno}; 7599730Sbenno 7699730Sbennotypedef u_int32_t instr_t; 7799730Sbennotypedef void (op_class_func) (instr_t, vm_offset_t); 7899730Sbenno 7999730Sbennou_int32_t extract_field(u_int32_t value, u_int32_t base, u_int32_t width); 8099730Sbennovoid disasm_fields(const struct opcode *popcode, instr_t instr, vm_offset_t loc, 8199730Sbenno char *disasm_str); 8299730Sbennovoid dis_ppc(const struct opcode *opcodeset, instr_t instr, vm_offset_t loc); 8399730Sbenno 8499730Sbennoop_class_func op_ill, op_base; 8599730Sbennoop_class_func op_cl_x13, op_cl_x1e, op_cl_x1f; 8699730Sbennoop_class_func op_cl_x3a, op_cl_x3b; 8799730Sbennoop_class_func op_cl_x3e, op_cl_x3f; 8899730Sbenno 8999730Sbennoop_class_func *opcodes_base[] = { 9099730Sbenno/*x00*/ op_ill, op_ill, op_base, op_ill, 9199730Sbenno/*x04*/ op_ill, op_ill, op_ill, op_base, 9299730Sbenno/*x08*/ op_base, op_base, op_ill, op_base, 9399730Sbenno/*x0C*/ op_base, op_base, op_base/*XXX*/, op_base/*XXX*/, 9499730Sbenno/*x10*/ op_base, op_base, op_base, op_cl_x13, 9599730Sbenno/*x14*/ op_base, op_base, op_ill, op_base, 9699730Sbenno/*x18*/ op_base, op_base, op_base, op_base, 9799730Sbenno/*x1C*/ op_base, op_base, op_cl_x1e, op_cl_x1f, 9899730Sbenno/*x20*/ op_base, op_base, op_base, op_base, 9999730Sbenno/*x24*/ op_base, op_base, op_base, op_base, 10099730Sbenno/*x28*/ op_base, op_base, op_base, op_base, 10199730Sbenno/*x2C*/ op_base, op_base, op_base, op_base, 10299730Sbenno/*x30*/ op_base, op_base, op_base, op_base, 10399730Sbenno/*x34*/ op_base, op_base, op_base, op_base, 10499730Sbenno/*x38*/ op_ill, op_ill, op_cl_x3a, op_cl_x3b, 10599730Sbenno/*x3C*/ op_ill, op_ill, op_cl_x3e, op_cl_x3f 10699730Sbenno}; 10799730Sbenno 10899730Sbenno 10999730Sbenno/* This table could be modified to make significant the "reserved" fields 11099730Sbenno * of the opcodes, But I didn't feel like it when typing in the table, 11199730Sbenno * I would recommend that this table be looked over for errors, 11299730Sbenno * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD) 11399730Sbenno * PowerPC Microprocessor Family: The Programming Environments 11499730Sbenno */ 11599730Sbenno 11699730Sbennoconst struct opcode opcodes[] = { 11799730Sbenno { "tdi", 0xfc000000, 0x08000000, Op_TO | Op_A | Op_SIMM }, 11899730Sbenno { "twi", 0xfc000000, 0x0c000000, Op_TO | Op_A | Op_SIMM }, 11999730Sbenno { "mulli", 0xfc000000, 0x1c000000, Op_D | Op_A | Op_SIMM }, 12099730Sbenno { "subfic", 0xfc000000, 0x20000000, Op_D | Op_A | Op_SIMM }, 12199730Sbenno { "cmpli", 0xfc000000, 0x28000000, Op_crfD | Op_L | Op_A | Op_SIMM }, 12299730Sbenno { "cmpi", 0xfc000000, 0x2c000000, Op_crfD | Op_L | Op_A | Op_SIMM }, 12399730Sbenno { "addic", 0xfc000000, 0x30000000, Op_D | Op_A | Op_SIMM }, 12499730Sbenno { "addic.", 0xfc000000, 0x34000000, Op_D | Op_A | Op_SIMM }, 12599730Sbenno { "addi", 0xfc000000, 0x38000000, Op_D | Op_A | Op_SIMM }, 12699730Sbenno { "addis", 0xfc000000, 0x3c000000, Op_D | Op_A | Op_SIMM }, 12799730Sbenno { "bc", 0xfc000000, 0x40000000, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK }, 12899730Sbenno { "sc", 0xffffffff, 0x44000002, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK }, 12999730Sbenno { "b", 0xfc000000, 0x48000000, Op_LI | Op_AA | Op_LK }, 13099730Sbenno 13199730Sbenno { "rlwimi", 0xfc000000, 0x50000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, 13299730Sbenno { "rlwinm", 0xfc000000, 0x54000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, 13399730Sbenno { "rlwnm", 0xfc000000, 0x5c000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, 13499730Sbenno 13599730Sbenno { "ori", 0xfc000000, 0x60000000, Op_S | Op_A | Op_UIMM }, 13699730Sbenno { "oris", 0xfc000000, 0x64000000, Op_S | Op_A | Op_UIMM }, 13799730Sbenno { "xori", 0xfc000000, 0x68000000, Op_S | Op_A | Op_UIMM }, 13899730Sbenno { "xoris", 0xfc000000, 0x6c000000, Op_S | Op_A | Op_UIMM }, 13999730Sbenno 14099730Sbenno { "andi.", 0xfc000000, 0x70000000, Op_S | Op_A | Op_UIMM }, 14199730Sbenno { "andis.", 0xfc000000, 0x74000000, Op_S | Op_A | Op_UIMM }, 14299730Sbenno 14399730Sbenno { "lwz", 0xfc000000, 0x80000000, Op_D | Op_A | Op_d }, 14499730Sbenno { "lwzu", 0xfc000000, 0x84000000, Op_D | Op_A | Op_d }, 14599730Sbenno { "lbz", 0xfc000000, 0x88000000, Op_D | Op_A | Op_d }, 14699730Sbenno { "lbzu", 0xfc000000, 0x8c000000, Op_D | Op_A | Op_d }, 14799730Sbenno { "stw", 0xfc000000, 0x90000000, Op_S | Op_A | Op_d }, 14899730Sbenno { "stwu", 0xfc000000, 0x94000000, Op_S | Op_A | Op_d }, 14999730Sbenno { "stb", 0xfc000000, 0x98000000, Op_S | Op_A | Op_d }, 15099730Sbenno { "stbu", 0xfc000000, 0x9c000000, Op_S | Op_A | Op_d }, 15199730Sbenno 15299730Sbenno { "lhz", 0xfc000000, 0xa0000000, Op_D | Op_A | Op_d }, 15399730Sbenno { "lhzu", 0xfc000000, 0xa4000000, Op_D | Op_A | Op_d }, 15499730Sbenno { "lha", 0xfc000000, 0xa8000000, Op_D | Op_A | Op_d }, 15599730Sbenno { "lhau", 0xfc000000, 0xac000000, Op_D | Op_A | Op_d }, 15699730Sbenno { "sth", 0xfc000000, 0xb0000000, Op_S | Op_A | Op_d }, 15799730Sbenno { "sthu", 0xfc000000, 0xb4000000, Op_S | Op_A | Op_d }, 15899730Sbenno { "lmw", 0xfc000000, 0xb8000000, Op_D | Op_A | Op_d }, 15999730Sbenno { "stmw", 0xfc000000, 0xbc000000, Op_S | Op_A | Op_d }, 16099730Sbenno 16199730Sbenno { "lfs", 0xfc000000, 0xc0000000, Op_D | Op_A | Op_d }, 16299730Sbenno { "lfsu", 0xfc000000, 0xc4000000, Op_D | Op_A | Op_d }, 16399730Sbenno { "lfd", 0xfc000000, 0xc8000000, Op_D | Op_A | Op_d }, 16499730Sbenno { "lfdu", 0xfc000000, 0xcc000000, Op_D | Op_A | Op_d }, 16599730Sbenno 16699730Sbenno { "stfs", 0xfc000000, 0xd0000000, Op_S | Op_A | Op_d }, 16799730Sbenno { "stfsu", 0xfc000000, 0xd4000000, Op_S | Op_A | Op_d }, 16899730Sbenno { "stfd", 0xfc000000, 0xd8000000, Op_S | Op_A | Op_d }, 16999730Sbenno { "stfdu", 0xfc000000, 0xdc000000, Op_S | Op_A | Op_d }, 17099730Sbenno { "", 0x0, 0x0, 0 } 17199730Sbenno 17299730Sbenno}; 17399730Sbenno/* 13 * 4 = 4c */ 17499730Sbennoconst struct opcode opcodes_13[] = { 17599730Sbenno/* 0x13 << 2 */ 17699730Sbenno { "mcrf", 0xfc0007fe, 0x4c000000, Op_crfD | Op_crfS }, 17799730Sbenno { "bclr", 0xfc0007fe, 0x4c000020, Op_BO | Op_BI | Op_LK }, 17899730Sbenno { "crnor", 0xfc0007fe, 0x4c000042, Op_crbD | Op_crbA | Op_crbB }, 17999730Sbenno { "rfi", 0xfc0007fe, 0x4c000064, 0 }, 18099730Sbenno { "crandc", 0xfc0007fe, 0x4c000102, Op_BO | Op_BI | Op_LK }, 18199730Sbenno { "isync", 0xfc0007fe, 0x4c00012c, 0 }, 18299730Sbenno { "crxor", 0xfc0007fe, 0x4c000182, Op_crbD | Op_crbA | Op_crbB }, 18399730Sbenno { "crnand", 0xfc0007fe, 0x4c0001c2, Op_crbD | Op_crbA | Op_crbB }, 18499730Sbenno { "crand", 0xfc0007fe, 0x4c000202, Op_crbD | Op_crbA | Op_crbB }, 18599730Sbenno { "creqv", 0xfc0007fe, 0x4c000242, Op_crbD | Op_crbA | Op_crbB }, 18699730Sbenno { "crorc", 0xfc0007fe, 0x4c000342, Op_crbD | Op_crbA | Op_crbB }, 18799730Sbenno { "cror", 0xfc0007fe, 0x4c000382, Op_crbD | Op_crbA | Op_crbB }, 18899730Sbenno { "bcctr", 0xfc0007fe, 0x4c000420, Op_BO | Op_BI | Op_LK }, 18999730Sbenno { "", 0x0, 0x0, 0 } 19099730Sbenno}; 19199730Sbenno 19299730Sbenno/* 1e * 4 = 78 */ 19399730Sbennoconst struct opcode opcodes_1e[] = { 19499730Sbenno { "rldicl", 0xfc00001c, 0x78000000, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, 19599730Sbenno { "rldicr", 0xfc00001c, 0x78000004, Op_S | Op_A | Op_sh | Op_me | Op_Rc }, 19699730Sbenno { "rldic", 0xfc00001c, 0x78000008, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, 19799730Sbenno { "rldimi", 0xfc00001c, 0x7800000c, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, 19899730Sbenno { "rldcl", 0xfc00003e, 0x78000010, Op_S | Op_A | Op_B | Op_mb | Op_Rc }, 19999730Sbenno { "rldcr", 0xfc00003e, 0x78000012, Op_S | Op_A | Op_B | Op_me | Op_Rc }, 20099730Sbenno { "", 0x0, 0x0, 0 } 20199730Sbenno}; 20299730Sbenno 20399730Sbenno/* 1f * 4 = 7c */ 20499730Sbennoconst struct opcode opcodes_1f[] = { 20599730Sbenno/* 1f << 2 */ 20699730Sbenno { "cmp", 0xfc0007fe, 0x7c000000, Op_S | Op_A | Op_B | Op_me | Op_Rc }, 20799730Sbenno { "tw", 0xfc0007fe, 0x7c000008, Op_TO | Op_A | Op_B }, 20899730Sbenno { "subfc", 0xfc0003fe, 0x7c000010, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 20999730Sbenno { "mulhdu", 0xfc0007fe, 0x7c000012, Op_D | Op_A | Op_B | Op_Rc }, 21099730Sbenno { "addc", 0xfc0003fe, 0x7c000014, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 21199730Sbenno { "mulhwu", 0xfc0007fe, 0x7c000016, Op_D | Op_A | Op_B | Op_Rc }, 21299730Sbenno 21399730Sbenno { "mfcr", 0xfc0007fe, 0x7c000026, Op_D }, 21499730Sbenno { "lwarx", 0xfc0007fe, 0x7c000028, Op_D | Op_A | Op_B }, 21599730Sbenno { "ldx", 0xfc0007fe, 0x7c00002a, Op_D | Op_A | Op_B }, 21699730Sbenno { "lwzx", 0xfc0007fe, 0x7c00002e, Op_D | Op_A | Op_B }, 21799730Sbenno { "slw", 0xfc0007fe, 0x7c000030, Op_D | Op_A | Op_B | Op_Rc }, 21899730Sbenno { "cntlzw", 0xfc0007fe, 0x7c000034, Op_D | Op_A | Op_Rc }, 21999730Sbenno { "sld", 0xfc0007fe, 0x7c000036, Op_D | Op_A | Op_B | Op_Rc }, 22099730Sbenno { "and", 0xfc0007fe, 0x7c000038, Op_D | Op_A | Op_B | Op_Rc }, 22199730Sbenno { "cmpl", 0xfc0007fe, 0x7c000040, Op_crfD | Op_L | Op_A | Op_B }, 22299730Sbenno { "subf", 0xfc0003fe, 0x7c000050, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 22399730Sbenno { "ldux", 0xfc0007fe, 0x7c00006a, Op_D | Op_A | Op_B }, 22499730Sbenno { "dcbst", 0xfc0007fe, 0x7c00006c, Op_A | Op_B }, 22599730Sbenno { "lwzux", 0xfc0007fe, 0x7c00006e, Op_D | Op_A | Op_B }, 22699730Sbenno { "cntlzd", 0xfc0007fe, 0x7c000074, Op_S | Op_A | Op_Rc }, 22799730Sbenno { "andc", 0xfc0007fe, 0x7c000078, Op_S | Op_A | Op_B | Op_Rc }, 22899730Sbenno { "td", 0xfc0007fe, 0x7c000088, Op_TO | Op_A | Op_B }, 22999730Sbenno { "mulhd", 0xfc0007fe, 0x7c000092, Op_D | Op_A | Op_B | Op_Rc }, 23099730Sbenno { "mulhw", 0xfc0007fe, 0x7c000096, Op_D | Op_A | Op_B | Op_Rc }, 23199730Sbenno { "mfmsr", 0xfc0007fe, 0x7c0000a6, Op_D }, 23299730Sbenno { "ldarx", 0xfc0007fe, 0x7c0000a8, Op_D | Op_A | Op_B }, 23399730Sbenno { "dcbf", 0xfc0007fe, 0x7c0000ac, Op_A | Op_B }, 23499730Sbenno { "lbzx", 0xfc0007fe, 0x7c0000ae, Op_D | Op_A | Op_B }, 23599730Sbenno { "neg", 0xfc0003fe, 0x7c0000d0, Op_D | Op_A | Op_OE | Op_Rc }, 23699730Sbenno { "lbzux", 0xfc0007fe, 0x7c0000ee, Op_D | Op_A | Op_B }, 23799730Sbenno { "nor", 0xfc0007fe, 0x7c0000f8, Op_S | Op_A | Op_B | Op_Rc }, 23899730Sbenno { "wrtee", 0xfc0003ff, 0x7c000106, Op_S }, 23999730Sbenno { "subfe", 0xfc0003fe, 0x7c000110, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 24099730Sbenno { "adde", 0xfc0003fe, 0x7c000114, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 24199730Sbenno { "mtcrf", 0xfc0007fe, 0x7c000120, Op_S | Op_CRM }, 24299730Sbenno { "mtmsr", 0xfc0007fe, 0x7c000124, Op_S }, 24399730Sbenno { "stdx", 0xfc0007fe, 0x7c00012a, Op_S | Op_A | Op_B }, 24499730Sbenno { "stwcx.", 0xfc0007ff, 0x7c00012d, Op_S | Op_A | Op_B }, 24599730Sbenno { "stwx", 0xfc0007fe, 0x7c00012e, Op_S | Op_A | Op_B }, 24699730Sbenno { "wrteei", 0xfc0003fe, 0x7c000146 }, /* XXX: out of flags! */ 24799730Sbenno { "stdux", 0xfc0007fe, 0x7c00016a, Op_S | Op_A | Op_B }, 24899730Sbenno { "stwux", 0xfc0007fe, 0x7c00016e, Op_S | Op_A | Op_B }, 24999730Sbenno { "subfze", 0xfc0003fe, 0x7c000190, Op_D | Op_A | Op_OE | Op_Rc }, 25099730Sbenno { "addze", 0xfc0003fe, 0x7c000194, Op_D | Op_A | Op_OE | Op_Rc }, 25199730Sbenno { "mtsr", 0xfc0007fe, 0x7c0001a4, Op_S | Op_SR }, 25299730Sbenno { "stdcx.", 0xfc0007ff, 0x7c0001ad, Op_S | Op_A | Op_B }, 25399730Sbenno { "stbx", 0xfc0007fe, 0x7c0001ae, Op_S | Op_A | Op_B }, 25499730Sbenno { "subfme", 0xfc0003fe, 0x7c0001d0, Op_D | Op_A | Op_OE | Op_Rc }, 25599730Sbenno { "mulld", 0xfc0003fe, 0x7c0001d2, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 25699730Sbenno { "addme", 0xfc0003fe, 0x7c0001d4, Op_D | Op_A | Op_OE | Op_Rc }, 25799730Sbenno { "mullw", 0xfc0003fe, 0x7c0001d6, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 25899730Sbenno { "mtsrin", 0xfc0007fe, 0x7c0001e4, Op_S | Op_B }, 25999730Sbenno { "dcbtst", 0xfc0007fe, 0x7c0001ec, Op_A | Op_B }, 26099730Sbenno { "stbux", 0xfc0007fe, 0x7c0001ee, Op_S | Op_A | Op_B }, 26199730Sbenno { "add", 0xfc0003fe, 0x7c000214, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 26299730Sbenno { "dcbt", 0xfc0007fe, 0x7c00022c, Op_A | Op_B }, 26399730Sbenno { "lhzx", 0xfc0007ff, 0x7c00022e, Op_D | Op_A | Op_B }, 26499730Sbenno { "eqv", 0xfc0007fe, 0x7c000238, Op_S | Op_A | Op_B | Op_Rc }, 26599730Sbenno { "tlbie", 0xfc0007fe, 0x7c000264, Op_B }, 26699730Sbenno { "eciwx", 0xfc0007fe, 0x7c00026c, Op_D | Op_A | Op_B }, 26799730Sbenno { "lhzux", 0xfc0007fe, 0x7c00026e, Op_D | Op_A | Op_B }, 26899730Sbenno { "xor", 0xfc0007fe, 0x7c000278, Op_S | Op_A | Op_B | Op_Rc }, 26999730Sbenno { "mfdcr", 0xfc0007fe, 0x7c000286, Op_D | Op_dcr }, 27099730Sbenno { "mfspr", 0xfc0007fe, 0x7c0002a6, Op_D | Op_spr }, 27199730Sbenno { "lwax", 0xfc0007fe, 0x7c0002aa, Op_D | Op_A | Op_B }, 27299730Sbenno { "lhax", 0xfc0007fe, 0x7c0002ae, Op_D | Op_A | Op_B }, 27399730Sbenno { "tlbia", 0xfc0007fe, 0x7c0002e4, 0 }, 27499730Sbenno { "mftb", 0xfc0007fe, 0x7c0002e6, Op_D | Op_tbr }, 27599730Sbenno { "lwaux", 0xfc0007fe, 0x7c0002ea, Op_D | Op_A | Op_B }, 27699730Sbenno { "lhaux", 0xfc0007fe, 0x7c0002ee, Op_D | Op_A | Op_B }, 27799730Sbenno { "sthx", 0xfc0007fe, 0x7c00032e, Op_S | Op_A | Op_B }, 27899730Sbenno { "orc", 0xfc0007fe, 0x7c000338, Op_S | Op_A | Op_B | Op_Rc }, 27999730Sbenno { "ecowx", 0xfc0007fe, 0x7c00036c, Op_S | Op_A | Op_B | Op_Rc }, 28099730Sbenno { "slbie", 0xfc0007fc, 0x7c000364, Op_B }, 28199730Sbenno { "sthux", 0xfc0007fe, 0x7c00036e, Op_S | Op_A | Op_B }, 28299730Sbenno { "or", 0xfc0007fe, 0x7c000378, Op_S | Op_A | Op_B | Op_Rc }, 28399730Sbenno { "mtdcr", 0xfc0007fe, 0x7c000386, Op_S | Op_dcr }, 28499730Sbenno { "divdu", 0xfc0003fe, 0x7c000392, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 28599730Sbenno { "divwu", 0xfc0003fe, 0x7c000396, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, 28699730Sbenno { "mtspr", 0xfc0007fe, 0x7c0003a6, Op_S | Op_spr }, 28799730Sbenno { "dcbi", 0xfc0007fe, 0x7c0003ac, Op_A | Op_B }, 28899730Sbenno { "nand", 0xfc0007fe, 0x7c0003b8, Op_S | Op_A | Op_B | Op_Rc }, 28999730Sbenno { "dcread", 0xfc0007fe, 0x7c0003cc, Op_D | Op_A | Op_B }, 29099730Sbenno { "divd", 0xfc0003fe, 0x7c0003d2, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, 29199730Sbenno { "divw", 0xfc0003fe, 0x7c0003d6, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, 29299730Sbenno { "slbia", 0xfc0003fe, 0x7c0003e4, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, 29399730Sbenno { "mcrxr", 0xfc0007fe, 0x7c000400, Op_crfD }, 29499730Sbenno { "lswx", 0xfc0007fe, 0x7c00042a, Op_D | Op_A | Op_B }, 29599730Sbenno { "lwbrx", 0xfc0007fe, 0x7c00042c, Op_D | Op_A | Op_B }, 29699730Sbenno { "lfsx", 0xfc0007fe, 0x7c00042e, Op_D | Op_A | Op_B }, 29799730Sbenno { "srw", 0xfc0007fe, 0x7c000430, Op_S | Op_A | Op_B | Op_Rc }, 29899730Sbenno { "srd", 0xfc0007fe, 0x7c000436, Op_S | Op_A | Op_B | Op_Rc }, 29999730Sbenno { "tlbsync", 0xfc0007fe, 0x7c00046c, 0 }, 30099730Sbenno { "lfsux", 0xfc0007fe, 0x7c00046e, Op_D | Op_A | Op_B }, 30199730Sbenno { "mfsr", 0xfc0007fe, 0x7c0004a6, Op_D | Op_SR }, 30299730Sbenno { "lswi", 0xfc0007fe, 0x7c0004aa, Op_D | Op_A | Op_NB }, 30399730Sbenno { "sync", 0xfc0007fe, 0x7c0004ac, 0 }, 30499730Sbenno { "lfdx", 0xfc0007fe, 0x7c0004ae, Op_D | Op_A | Op_B }, 30599730Sbenno { "lfdux", 0xfc0007fe, 0x7c0004ee, Op_D | Op_A | Op_B }, 30699730Sbenno { "mfsrin", 0xfc0007fe, 0x7c000526, Op_D | Op_B }, 30799730Sbenno { "stswx", 0xfc0007fe, 0x7c00052a, Op_S | Op_A | Op_B }, 30899730Sbenno { "stwbrx", 0xfc0007fe, 0x7c00052c, Op_S | Op_A | Op_B }, 30999730Sbenno { "stfsx", 0xfc0007fe, 0x7c00052e, Op_S | Op_A | Op_B }, 31099730Sbenno { "stfsux", 0xfc0007fe, 0x7c00056e, Op_S | Op_A | Op_B }, 31199730Sbenno { "stswi", 0xfc0007fe, 0x7c0005aa, Op_S | Op_A | Op_NB }, 31299730Sbenno { "stfdx", 0xfc0007fe, 0x7c0005ae, Op_S | Op_A | Op_B }, 31399730Sbenno { "stfdux", 0xfc0007fe, 0x7c0005ee, Op_S | Op_A | Op_B }, 31499730Sbenno { "lhbrx", 0xfc0007fe, 0x7c00062c, Op_D | Op_A | Op_B }, 31599730Sbenno { "sraw", 0xfc0007fe, 0x7c000630, Op_S | Op_A | Op_B }, 31699730Sbenno { "srad", 0xfc0007fe, 0x7c000634, Op_S | Op_A | Op_B | Op_Rc }, 31799730Sbenno { "srawi", 0xfc0007fe, 0x7c000670, Op_S | Op_A | Op_B | Op_Rc }, 31899730Sbenno { "sradi", 0xfc0007fc, 0x7c000674, Op_S | Op_A | Op_sh }, 31999730Sbenno { "eieio", 0xfc0007fe, 0x7c0006ac, 0 }, 32099730Sbenno { "tlbsx", 0xfc0007fe, 0x7c000724, Op_S | Op_A | Op_B | Op_Rc }, 32199730Sbenno { "sthbrx", 0xfc0007fe, 0x7c00072c, Op_S | Op_A | Op_B }, 32299730Sbenno { "extsh", 0xfc0007fe, 0x7c000734, Op_S | Op_A | Op_B | Op_Rc }, 32399730Sbenno { "tlbre", 0xfc0007fe, 0x7c000764, Op_D | Op_A | Op_WS }, 32499730Sbenno { "extsb", 0xfc0007fe, 0x7c000774, Op_S | Op_A | Op_Rc }, 32599730Sbenno { "icbi", 0xfc0007fe, 0x7c0007ac, Op_A | Op_B }, 32699730Sbenno { "tlbwe", 0xfc0007fe, 0x7c0007a4, Op_S | Op_A | Op_WS }, 32799730Sbenno { "stfiwx", 0xfc0007fe, 0x7c0007ae, Op_S | Op_A | Op_B }, 32899730Sbenno { "extsw", 0xfc0007fe, 0x7c0007b4, Op_S | Op_A | Op_Rc }, 32999730Sbenno { "dcbz", 0xfc0007fe, 0x7c0007ec, Op_A | Op_B }, 33099730Sbenno { "", 0x0, 0x0, 0 } 33199730Sbenno}; 33299730Sbenno 33399730Sbenno/* 3a * 4 = e8 */ 33499730Sbennoconst struct opcode opcodes_3a[] = { 33599730Sbenno { "ld", 0xfc000003, 0xe8000000, Op_D | Op_A | Op_ds }, 33699730Sbenno { "ldu", 0xfc000003, 0xe8000001, Op_D | Op_A | Op_ds }, 33799730Sbenno { "lwa", 0xfc000003, 0xe8000002, Op_D | Op_A | Op_ds }, 33899730Sbenno { "", 0x0, 0x0, 0 } 33999730Sbenno}; 34099730Sbenno/* 3b * 4 = ec */ 34199730Sbennoconst struct opcode opcodes_3b[] = { 34299730Sbenno { "fdivs", 0xfc00003e, 0xec000024, Op_D | Op_A | Op_B | Op_Rc }, 34399730Sbenno { "fsubs", 0xfc00003e, 0xec000028, Op_D | Op_A | Op_B | Op_Rc }, 34499730Sbenno 34599730Sbenno { "fadds", 0xfc00003e, 0xec00002a, Op_D | Op_A | Op_B | Op_Rc }, 34699730Sbenno { "fsqrts", 0xfc00003e, 0xec00002c, Op_D | Op_B | Op_Rc }, 34799730Sbenno { "fres", 0xfc00003e, 0xec000030, Op_D | Op_B | Op_Rc }, 34899730Sbenno { "fmuls", 0xfc00003e, 0xec000032, Op_D | Op_A | Op_C | Op_Rc }, 34999730Sbenno { "fmsubs", 0xfc00003e, 0xec000038, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 35099730Sbenno { "fmadds", 0xfc00003e, 0xec00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 35199730Sbenno { "fnmsubs", 0xfc00003e, 0xec00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 35299730Sbenno { "fnmadds", 0xfc00003e, 0xec00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 35399730Sbenno { "", 0x0, 0x0, 0 } 35499730Sbenno}; 35599730Sbenno/* 3e * 4 = f8 */ 35699730Sbennoconst struct opcode opcodes_3e[] = { 35799730Sbenno { "std", 0xfc000003, 0xf8000000, Op_S | Op_A | Op_ds }, 35899730Sbenno { "stdu", 0xfc000003, 0xf8000001, Op_S | Op_A | Op_ds }, 35999730Sbenno { "", 0x0, 0x0, 0 } 36099730Sbenno}; 36199730Sbenno 36299730Sbenno/* 3f * 4 = fc */ 36399730Sbennoconst struct opcode opcodes_3f[] = { 36499730Sbenno { "fcmpu", 0xfc0007fe, 0xfc000000, Op_crfD | Op_A | Op_B }, 36599730Sbenno { "frsp", 0xfc0007fe, 0xfc000018, Op_D | Op_B | Op_Rc }, 36699730Sbenno { "fctiw", 0xfc0007fe, 0xfc00001c, Op_D | Op_B | Op_Rc }, 36799730Sbenno { "fctiwz", 0xfc0007fe, 0xfc00001e, Op_D | Op_B | Op_Rc }, 36899730Sbenno 36999730Sbenno { "fdiv", 0xfc00003e, 0xfc000024, Op_D | Op_A | Op_B | Op_Rc }, 37099730Sbenno { "fsub", 0xfc00003e, 0xfc000028, Op_D | Op_A | Op_B | Op_Rc }, 37199730Sbenno { "fadd", 0xfc00003e, 0xfc00002a, Op_D | Op_A | Op_B | Op_Rc }, 37299730Sbenno { "fsqrt", 0xfc00003e, 0xfc00002c, Op_D | Op_B | Op_Rc }, 37399730Sbenno { "fsel", 0xfc00003e, 0xfc00002e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 37499730Sbenno { "fmul", 0xfc00003e, 0xfc000032, Op_D | Op_A | Op_C | Op_Rc }, 37599730Sbenno { "frsqrte", 0xfc00003e, 0xfc000034, Op_D | Op_B | Op_Rc }, 37699730Sbenno { "fmsub", 0xfc00003e, 0xfc000038, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 37799730Sbenno { "fmadd", 0xfc00003e, 0xfc00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 37899730Sbenno { "fnmsub", 0xfc00003e, 0xfc00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 37999730Sbenno { "fnmadd", 0xfc00003e, 0xfc00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, 38099730Sbenno 38199730Sbenno { "fcmpo", 0xfc0007fe, 0xfc000040, Op_crfD | Op_A | Op_B }, 38299730Sbenno { "mtfsb1", 0xfc0007fe, 0xfc00004c, Op_crfD | Op_Rc }, 38399730Sbenno { "fneg", 0xfc0007fe, 0xfc000050, Op_D | Op_B | Op_Rc }, 38499730Sbenno { "mcrfs", 0xfc0007fe, 0xfc000080, Op_D | Op_B | Op_Rc }, 38599730Sbenno { "mtfsb0", 0xfc0007fe, 0xfc00008c, Op_crfD | Op_Rc }, 38699730Sbenno { "fmr", 0xfc0007fe, 0xfc000090, Op_D | Op_B | Op_Rc }, 38799730Sbenno { "mtfsfi", 0xfc0007fe, 0xfc00010c, Op_crfD | Op_IMM | Op_Rc }, 38899730Sbenno 38999730Sbenno { "fnabs", 0xfc0007fe, 0xfc000110, Op_D | Op_B | Op_Rc }, 39099730Sbenno { "fabs", 0xfc0007fe, 0xfc000210, Op_D | Op_B | Op_Rc }, 39199730Sbenno { "mffs", 0xfc0007fe, 0xfc00048e, Op_D | Op_B | Op_Rc }, 39299730Sbenno { "mtfsf", 0xfc0007fe, 0xfc00058e, Op_FM | Op_B | Op_Rc }, 39399730Sbenno { "fctid", 0xfc0007fe, 0xfc00065c, Op_D | Op_B | Op_Rc }, 39499730Sbenno { "fctidz", 0xfc0007fe, 0xfc00065e, Op_D | Op_B | Op_Rc }, 39599730Sbenno { "fcfid", 0xfc0007fe, 0xfc00069c, Op_D | Op_B | Op_Rc }, 39699730Sbenno { "", 0x0, 0x0, 0 } 39799730Sbenno}; 39899730Sbenno 39999730Sbenno 40099730Sbennostruct specialreg { 40199730Sbenno int reg; 40299730Sbenno char *name; 40399730Sbenno}; 40499730Sbenno 40599730Sbennoconst struct specialreg sprregs[] = { 40699730Sbenno { 0x001, "xer" }, 40799730Sbenno { 0x008, "lr" }, 40899730Sbenno { 0x009, "ctr" }, 40999730Sbenno { 0x012, "dsisr" }, 41099730Sbenno { 0x013, "dar" }, 41199730Sbenno { 0x016, "dec" }, 41299730Sbenno { 0x019, "sdr1" }, 41399730Sbenno { 0x01a, "srr0" }, 41499730Sbenno { 0x01b, "srr1" }, 41599730Sbenno { 0x100, "usprg0" }, 41699730Sbenno { 0x110, "sprg0" }, 41799730Sbenno { 0x111, "sprg1" }, 41899730Sbenno { 0x112, "sprg2" }, 41999730Sbenno { 0x113, "sprg3" }, 42099730Sbenno { 0x114, "sprg4" }, 42199730Sbenno { 0x115, "sprg5" }, 42299730Sbenno { 0x116, "sprg6" }, 42399730Sbenno { 0x117, "sprg7" }, 42499730Sbenno { 0x118, "asr" }, 42599730Sbenno { 0x11a, "aer" }, 42699730Sbenno { 0x11c, "tbl" }, 42799730Sbenno { 0x11d, "tbu" }, 42899730Sbenno { 0x11f, "pvr" }, 42999730Sbenno { 0x210, "ibat0u" }, 43099730Sbenno { 0x211, "ibat0l" }, 43199730Sbenno { 0x212, "ibat1u" }, 43299730Sbenno { 0x213, "ibat1l" }, 43399730Sbenno { 0x214, "ibat2u" }, 43499730Sbenno { 0x215, "ibat2l" }, 43599730Sbenno { 0x216, "ibat3u" }, 43699730Sbenno { 0x217, "ibat3l" }, 43799730Sbenno { 0x218, "dbat0u" }, 43899730Sbenno { 0x219, "dbat0l" }, 43999730Sbenno { 0x21a, "dbat1u" }, 44099730Sbenno { 0x21b, "dbat1l" }, 44199730Sbenno { 0x21c, "dbat2u" }, 44299730Sbenno { 0x21d, "dbat2l" }, 44399730Sbenno { 0x21e, "dbat3u" }, 44499730Sbenno { 0x21f, "dbat3l" }, 44599730Sbenno { 0x3b0, "zpr" }, 44699730Sbenno { 0x3b1, "pid" }, 44799730Sbenno { 0x3b3, "ccr0" }, 44899730Sbenno { 0x3b4, "iac3" }, 44999730Sbenno { 0x3b5, "iac4" }, 45099730Sbenno { 0x3b6, "dvc1" }, 45199730Sbenno { 0x3b7, "dvc2" }, 45299730Sbenno { 0x3b9, "sgr" }, 45399730Sbenno { 0x3ba, "dcwr" }, 45499730Sbenno { 0x3bb, "sler" }, 45599730Sbenno { 0x3bc, "su0r" }, 45699730Sbenno { 0x3bd, "dbcr1" }, 45799730Sbenno { 0x3d3, "icdbdr" }, 45899730Sbenno { 0x3d4, "esr" }, 45999730Sbenno { 0x3d5, "dear" }, 46099730Sbenno { 0x3d6, "evpr" }, 46199730Sbenno { 0x3d8, "tsr" }, 46299730Sbenno { 0x3da, "tcr" }, 46399730Sbenno { 0x3db, "pit" }, 46499730Sbenno { 0x3de, "srr2" }, 46599730Sbenno { 0x3df, "srr3" }, 46699730Sbenno { 0x3f0, "dbsr" }, 46799730Sbenno { 0x3f2, "dbcr0" }, 46899730Sbenno { 0x3f4, "iac1" }, 46999730Sbenno { 0x3f5, "iac2" }, 47099730Sbenno { 0x3f6, "dac1" }, 47199730Sbenno { 0x3f7, "dac2" }, 47299730Sbenno { 0x3f9, "l2cr" }, 47399730Sbenno { 0x3fa, "dccr" }, 47499730Sbenno { 0x3fb, "iccr" }, 47599730Sbenno { 0x3ff, "pir" }, 47699730Sbenno { 0, NULL } 47799730Sbenno}; 47899730Sbenno 47999730Sbennoconst struct specialreg dcrregs[] = { 48099730Sbenno { 0x010, "sdram0_cfgaddr" }, 48199730Sbenno { 0x011, "sdram0_cfgdata" }, 48299730Sbenno { 0x012, "ebc0_cfgaddr" }, 48399730Sbenno { 0x013, "ebc0_cfgdata" }, 48499730Sbenno { 0x014, "dcp0_cfgaddr" }, 48599730Sbenno { 0x015, "dcp0_cfgdata" }, 48699730Sbenno { 0x018, "ocm0_isarc" }, 48799730Sbenno { 0x019, "ocm0_iscntl" }, 48899730Sbenno { 0x01a, "ocm0_dsarc" }, 48999730Sbenno { 0x01b, "ocm0_dscntl" }, 49099730Sbenno { 0x084, "plb0_besr" }, 49199730Sbenno { 0x086, "plb0_bear" }, 49299730Sbenno { 0x087, "plb0_acr" }, 49399730Sbenno { 0x0a0, "pob0_besr0" }, 49499730Sbenno { 0x0a2, "pob0_bear" }, 49599730Sbenno { 0x0a4, "pob0_besr1" }, 49699730Sbenno { 0x0b0, "cpc0_pllmr" }, 49799730Sbenno { 0x0b1, "cpc0_cr0" }, 49899730Sbenno { 0x0b2, "cpc0_cr1" }, 49999730Sbenno { 0x0b4, "cpc0_psr" }, 50099730Sbenno { 0x0b5, "cpc0_jtagid" }, 50199730Sbenno { 0x0b8, "cpc0_sr" }, 50299730Sbenno { 0x0b9, "cpc0_er" }, 50399730Sbenno { 0x0ba, "cpc0_fr" }, 50499730Sbenno { 0x0c0, "uic0_sr" }, 50599730Sbenno { 0x0c2, "uic0_er" }, 50699730Sbenno { 0x0c3, "uic0_cr" }, 50799730Sbenno { 0x0c4, "uic0_pr" }, 50899730Sbenno { 0x0c5, "uic0_tr" }, 50999730Sbenno { 0x0c6, "uic0_msr" }, 51099730Sbenno { 0x0c7, "uic0_vr" }, 51199730Sbenno { 0x0c8, "uic0_vcr" }, 51299730Sbenno { 0x100, "dma0_cr0" }, 51399730Sbenno { 0x101, "dma0_ct0" }, 51499730Sbenno { 0x102, "dma0_da0" }, 51599730Sbenno { 0x103, "dma0_sa0" }, 51699730Sbenno { 0x104, "dma0_sg0" }, 51799730Sbenno { 0x108, "dma0_cr1" }, 51899730Sbenno { 0x109, "dma0_ct1" }, 51999730Sbenno { 0x10a, "dma0_da1" }, 52099730Sbenno { 0x10b, "dma0_sa1" }, 52199730Sbenno { 0x10c, "dma0_sg1" }, 52299730Sbenno { 0x110, "dma0_cr2" }, 52399730Sbenno { 0x111, "dma0_ct2" }, 52499730Sbenno { 0x112, "dma0_da2" }, 52599730Sbenno { 0x113, "dma0_sa2" }, 52699730Sbenno { 0x114, "dma0_sg2" }, 52799730Sbenno { 0x118, "dma0_cr3" }, 52899730Sbenno { 0x119, "dma0_ct3" }, 52999730Sbenno { 0x11a, "dma0_da3" }, 53099730Sbenno { 0x11b, "dma0_sa3" }, 53199730Sbenno { 0x11c, "dma0_sg3" }, 53299730Sbenno { 0x120, "dma0_sr" }, 53399730Sbenno { 0x123, "dma0_sgc" }, 53499730Sbenno { 0x125, "dma0_slp" }, 53599730Sbenno { 0x126, "dma0_pol" }, 53699730Sbenno { 0x180, "mal0_cfg" }, 53799730Sbenno { 0x181, "mal0_esr" }, 53899730Sbenno { 0x182, "mal0_ier" }, 53999730Sbenno { 0x184, "mal0_txcasr" }, 54099730Sbenno { 0x185, "mal0_txcarr" }, 54199730Sbenno { 0x186, "mal0_txeobisr" }, 54299730Sbenno { 0x187, "mal0_txdeir" }, 54399730Sbenno { 0x190, "mal0_rxcasr" }, 54499730Sbenno { 0x191, "mal0_rxcarr" }, 54599730Sbenno { 0x192, "mal0_rxeobisr" }, 54699730Sbenno { 0x193, "mal0_rxdeir" }, 54799730Sbenno { 0x1a0, "mal0_txctp0r" }, 54899730Sbenno { 0x1a1, "mal0_txctp1r" }, 54999730Sbenno { 0x1a2, "mal0_txctp2r" }, 55099730Sbenno { 0x1a3, "mal0_txctp3r" }, 55199730Sbenno { 0x1c0, "mal0_rxctp0r" }, 55299730Sbenno { 0x1e0, "mal0_rcbs0" }, 55399730Sbenno { 0, NULL } 55499730Sbenno}; 55599730Sbenno 55699730Sbennovoid 55799730Sbennoop_ill(instr_t instr, vm_offset_t loc) 55899730Sbenno{ 55999730Sbenno db_printf("illegal instruction %x\n", instr); 56099730Sbenno} 56199730Sbenno 56299730Sbennou_int32_t 56399730Sbennoextract_field(u_int32_t value, u_int32_t base, u_int32_t width) 56499730Sbenno{ 56599730Sbenno u_int32_t mask = (1 << width) - 1; 56699730Sbenno return ((value >> base) & mask); 56799730Sbenno} 56899730Sbenno 56999730Sbennoconst struct opcode * search_op(const struct opcode *); 57099730Sbenno 57199730Sbennovoid 57299730Sbennodisasm_fields(const struct opcode *popcode, instr_t instr, vm_offset_t loc, 57399730Sbenno char *disasm_str) 57499730Sbenno{ 57599730Sbenno char * pstr; 57699730Sbenno enum function_mask func; 57799730Sbenno 57899730Sbenno pstr = disasm_str; 57999730Sbenno 58099730Sbenno func = popcode->func; 58199730Sbenno if (func & Op_OE) { 58299730Sbenno u_int OE; 58399730Sbenno /* also for Op_S (they are the same) */ 58499730Sbenno OE = extract_field(instr, 31 - 21, 1); 58599730Sbenno if (OE) { 58699730Sbenno pstr += sprintf(pstr, "o"); 58799730Sbenno } 58899730Sbenno func &= ~Op_OE; 58999730Sbenno } 59099730Sbenno switch (func & Op_LKM) { 59199730Sbenno case Op_Rc: 59299730Sbenno if (instr & 0x1) { 59399730Sbenno pstr += sprintf(pstr, "."); 59499730Sbenno } 59599730Sbenno break; 59699730Sbenno case Op_AA: 59799730Sbenno if (instr & 0x2) { 59899730Sbenno pstr += sprintf(pstr, "a"); 59999730Sbenno loc = 0; /* Absolute address */ 60099730Sbenno } 60199730Sbenno case Op_LK: 60299730Sbenno if (instr & 0x1) { 60399730Sbenno pstr += sprintf(pstr, "l"); 60499730Sbenno } 60599730Sbenno break; 60699730Sbenno default: 60799730Sbenno func &= ~Op_LKM; 60899730Sbenno } 60999730Sbenno pstr += sprintf(pstr, "\t"); 61099730Sbenno 61199730Sbenno /* XXX: special cases here, out of flags in a 32bit word. */ 61299730Sbenno if (strcmp(popcode->name, "wrteei") == 0) { 61399730Sbenno int E; 61499730Sbenno E = extract_field(instr, 31 - 16, 5); 61599730Sbenno pstr += sprintf(pstr, "%d", E); 61699730Sbenno return; 61799730Sbenno } 61899730Sbenno /* XXX: end of special cases here. */ 61999730Sbenno 62099730Sbenno if (func & Op_D) { 62199730Sbenno u_int D; 62299730Sbenno /* also for Op_S (they are the same) */ 62399730Sbenno D = extract_field(instr, 31 - 10, 5); 62499730Sbenno pstr += sprintf(pstr, "r%d, ", D); 62599730Sbenno func &= ~Op_D; 62699730Sbenno } 62799730Sbenno if (func & Op_crbD) { 62899730Sbenno u_int crbD; 62999730Sbenno crbD = extract_field(instr, 31 - 10, 5); 63099730Sbenno pstr += sprintf(pstr, "crb%d, ", crbD); 63199730Sbenno func &= ~Op_crbD; 63299730Sbenno } 63399730Sbenno if (func & Op_crfD) { 63499730Sbenno u_int crfD; 63599730Sbenno crfD = extract_field(instr, 31 - 8, 3); 63699730Sbenno pstr += sprintf(pstr, "crf%d, ", crfD); 63799730Sbenno func &= ~Op_crfD; 63899730Sbenno } 63999730Sbenno if (func & Op_L) { 64099730Sbenno u_int L; 64199730Sbenno L = extract_field(instr, 31 - 10, 1); 64299730Sbenno if (L) { 64399730Sbenno pstr += sprintf(pstr, "L, "); 64499730Sbenno } 64599730Sbenno func &= ~Op_L; 64699730Sbenno } 64799730Sbenno if (func & Op_FM) { 64899730Sbenno u_int FM; 64999730Sbenno FM = extract_field(instr, 31 - 10, 8); 65099730Sbenno pstr += sprintf(pstr, "%d, ", FM); 65199730Sbenno func &= ~Op_FM; 65299730Sbenno } 65399730Sbenno if (func & Op_TO) { 65499730Sbenno u_int TO; 65599730Sbenno TO = extract_field(instr, 31 - 10, 1); 65699730Sbenno pstr += sprintf(pstr, "%d, ", TO); 65799730Sbenno func &= ~Op_TO; 65899730Sbenno } 65999730Sbenno if (func & Op_crfS) { 66099730Sbenno u_int crfS; 66199730Sbenno crfS = extract_field(instr, 31 - 13, 3); 66299730Sbenno pstr += sprintf(pstr, "%d, ", crfS); 66399730Sbenno func &= ~Op_crfS; 66499730Sbenno } 66599730Sbenno if (func & Op_BO) { 66699730Sbenno u_int BO; 66799730Sbenno BO = extract_field(instr, 31 - 10, 5); 66899730Sbenno pstr += sprintf(pstr, "%d, ", BO); 66999730Sbenno func &= ~Op_BO; 67099730Sbenno } 67199730Sbenno if (func & Op_A) { 67299730Sbenno u_int A; 67399730Sbenno A = extract_field(instr, 31 - 15, 5); 67499730Sbenno pstr += sprintf(pstr, "r%d, ", A); 67599730Sbenno func &= ~Op_A; 67699730Sbenno } 67799730Sbenno if (func & Op_B) { 67899730Sbenno u_int B; 67999730Sbenno B = extract_field(instr, 31 - 20, 5); 68099730Sbenno pstr += sprintf(pstr, "r%d, ", B); 68199730Sbenno func &= ~Op_B; 68299730Sbenno } 68399730Sbenno if (func & Op_C) { 68499730Sbenno u_int C; 68599730Sbenno C = extract_field(instr, 31 - 25, 5); 68699730Sbenno pstr += sprintf(pstr, "r%d, ", C); 68799730Sbenno func &= ~Op_C; 68899730Sbenno } 68999730Sbenno if (func & Op_BI) { 69099730Sbenno u_int BI; 69199730Sbenno BI = extract_field(instr, 31 - 10, 5); 69299730Sbenno pstr += sprintf(pstr, "%d, ", BI); 69399730Sbenno func &= ~Op_BI; 69499730Sbenno } 69599730Sbenno if (func & Op_crbA) { 69699730Sbenno u_int crbA; 69799730Sbenno crbA = extract_field(instr, 31 - 15, 5); 69899730Sbenno pstr += sprintf(pstr, "%d, ", crbA); 69999730Sbenno func &= ~Op_crbA; 70099730Sbenno } 70199730Sbenno if (func & Op_crbB) { 70299730Sbenno u_int crbB; 70399730Sbenno crbB = extract_field(instr, 31 - 20, 5); 70499730Sbenno pstr += sprintf(pstr, "%d, ", crbB); 70599730Sbenno func &= ~Op_crbB; 70699730Sbenno } 70799730Sbenno if (func & Op_CRM) { 70899730Sbenno u_int CRM; 70999730Sbenno CRM = extract_field(instr, 31 - 19, 8); 71099730Sbenno pstr += sprintf(pstr, "0x%x, ", CRM); 71199730Sbenno func &= ~Op_CRM; 71299730Sbenno } 71399730Sbenno if (func & Op_LI) { 71499730Sbenno int LI; 71599730Sbenno LI = extract_field(instr, 31 - 29, 24); 71699730Sbenno /* Need to sign extend and shift up 2, then add addr */ 71799730Sbenno LI = LI << 8; 71899730Sbenno LI = LI >> 6; 71999730Sbenno LI += loc; 720104435Sgrehan pstr += sprintf (pstr, "0x%x, ", LI); 72199730Sbenno func &= ~Op_LI; 72299730Sbenno } 72399730Sbenno switch (func & Op_SIMM) { 72499730Sbenno u_int IMM; 72599730Sbenno case Op_SIMM: /* same as Op_d */ 72699730Sbenno IMM = extract_field(instr, 31 - 31, 16); 72799730Sbenno if (IMM & 0x8000) { 72899730Sbenno pstr += sprintf(pstr, "-"); 72999730Sbenno IMM = 0x10000-IMM; 73099730Sbenno } 73199730Sbenno func &= ~Op_SIMM; 73299730Sbenno goto common; 73399730Sbenno case Op_UIMM: 73499730Sbenno IMM = extract_field(instr, 31 - 31, 16); 73599730Sbenno func &= ~Op_UIMM; 73699730Sbenno goto common; 73799730Sbenno common: 73899730Sbenno pstr += sprintf(pstr, "0x%x", IMM); 73999730Sbenno break; 74099730Sbenno default: 741104435Sgrehan break; 74299730Sbenno } 74399730Sbenno if (func & Op_BD) { 74499730Sbenno u_int BD; 74599730Sbenno BD = extract_field(instr, 31 - 29, 14); 74699730Sbenno pstr += sprintf(pstr, "0x%x, ", BD); 74799730Sbenno func &= ~Op_BD; 74899730Sbenno } 74999730Sbenno if (func & Op_ds) { 75099730Sbenno u_int ds; 75199730Sbenno ds = extract_field(instr, 31 - 29, 14) << 2; 75299730Sbenno pstr += sprintf(pstr, "0x%x, ", ds); 75399730Sbenno func &= ~Op_ds; 75499730Sbenno } 75599730Sbenno if (func & Op_spr) { 75699730Sbenno u_int spr; 75799730Sbenno u_int sprl; 75899730Sbenno u_int sprh; 75999730Sbenno const struct specialreg *regs; 76099730Sbenno int i; 76199730Sbenno sprl = extract_field(instr, 31 - 15, 5); 76299730Sbenno sprh = extract_field(instr, 31 - 20, 5); 76399730Sbenno spr = sprh << 5 | sprl; 76499730Sbenno 76599730Sbenno /* ugly hack - out of bitfields in the function mask */ 76699730Sbenno if (popcode->name[2] == 'd') /* m.Dcr */ 76799730Sbenno regs = dcrregs; 76899730Sbenno else 76999730Sbenno regs = sprregs; 77099730Sbenno for (i = 0; regs[i].name != NULL; i++) 77199730Sbenno if (spr == regs[i].reg) 77299730Sbenno break; 77399730Sbenno if (regs[i].reg == 0) 77499730Sbenno pstr += sprintf(pstr, "[unknown special reg (%d)]", spr); 77599730Sbenno else 77699730Sbenno pstr += sprintf(pstr, "%s", regs[i].name); 77799730Sbenno func &= ~Op_spr; 77899730Sbenno } 77999730Sbenno 78099730Sbenno if (func & Op_me) { 78199730Sbenno u_int me, mel, meh; 78299730Sbenno mel = extract_field(instr, 31 - 25, 4); 78399730Sbenno meh = extract_field(instr, 31 - 26, 1); 78499730Sbenno me = meh << 4 | mel; 78599730Sbenno pstr += sprintf(pstr, ", 0x%x", me); 78699730Sbenno func &= ~Op_me; 78799730Sbenno } 78899730Sbenno if ((func & Op_MB) && (func & Op_sh_mb_sh)) { 78999730Sbenno u_int MB; 79099730Sbenno u_int ME; 79199730Sbenno MB = extract_field(instr, 31 - 20, 5); 79299730Sbenno pstr += sprintf(pstr, ", %d", MB); 79399730Sbenno ME = extract_field(instr, 31 - 25, 5); 79499730Sbenno pstr += sprintf(pstr, ", %d", ME); 79599730Sbenno } 79699730Sbenno if ((func & Op_SH) && (func & Op_sh_mb_sh)) { 79799730Sbenno u_int SH; 79899730Sbenno SH = extract_field(instr, 31 - 20, 5); 79999730Sbenno pstr += sprintf(pstr, ", %d", SH); 80099730Sbenno } 80199730Sbenno if ((func & Op_sh) && ! (func & Op_sh_mb_sh)) { 80299730Sbenno u_int sh, shl, shh; 80399730Sbenno shl = extract_field(instr, 31 - 19, 4); 80499730Sbenno shh = extract_field(instr, 31 - 20, 1); 80599730Sbenno sh = shh << 4 | shl; 80699730Sbenno pstr += sprintf(pstr, ", %d", sh); 80799730Sbenno } 80899730Sbenno if ((func & Op_mb) && ! (func & Op_sh_mb_sh)) { 80999730Sbenno u_int mb, mbl, mbh; 81099730Sbenno mbl = extract_field(instr, 31 - 25, 4); 81199730Sbenno mbh = extract_field(instr, 31 - 26, 1); 81299730Sbenno mb = mbh << 4 | mbl; 81399730Sbenno pstr += sprintf(pstr, ", %d", mb); 81499730Sbenno } 81599730Sbenno if ((func & Op_me) && ! (func & Op_sh_mb_sh)) { 81699730Sbenno u_int me, mel, meh; 81799730Sbenno mel = extract_field(instr, 31 - 25, 4); 81899730Sbenno meh = extract_field(instr, 31 - 26, 1); 81999730Sbenno me = meh << 4 | mel; 82099730Sbenno pstr += sprintf(pstr, ", %d", me); 82199730Sbenno } 82299730Sbenno if (func & Op_tbr) { 82399730Sbenno u_int tbr; 82499730Sbenno u_int tbrl; 82599730Sbenno u_int tbrh; 82699730Sbenno char *reg; 82799730Sbenno tbrl = extract_field(instr, 31 - 15, 5); 82899730Sbenno tbrh = extract_field(instr, 31 - 20, 5); 82999730Sbenno tbr = tbrh << 5 | tbrl; 83099730Sbenno 83199730Sbenno switch (tbr) { 83299730Sbenno case 268: 83399730Sbenno reg = "tbl"; 83499730Sbenno break; 83599730Sbenno case 269: 83699730Sbenno reg = "tbu"; 83799730Sbenno break; 83899730Sbenno default: 83999730Sbenno reg = 0; 84099730Sbenno } 84199730Sbenno if (reg == 0) 84299730Sbenno pstr += sprintf(pstr, ", [unknown tbr %d ]", tbr); 84399730Sbenno else 84499730Sbenno pstr += sprintf(pstr, ", %s", reg); 84599730Sbenno func &= ~Op_tbr; 84699730Sbenno } 84799730Sbenno if (func & Op_SR) { 84899730Sbenno u_int SR; 84999730Sbenno SR = extract_field(instr, 31 - 15, 3); 85099730Sbenno pstr += sprintf(pstr, ", sr%d", SR); 85199730Sbenno func &= ~Op_SR; 85299730Sbenno } 85399730Sbenno if (func & Op_NB) { 85499730Sbenno u_int NB; 85599730Sbenno NB = extract_field(instr, 31 - 20, 5); 85699730Sbenno if (NB == 0) 85799730Sbenno NB = 32; 85899730Sbenno pstr += sprintf(pstr, ", %d", NB); 85999730Sbenno func &= ~Op_SR; 86099730Sbenno } 86199730Sbenno if (func & Op_IMM) { 86299730Sbenno u_int IMM; 86399730Sbenno IMM = extract_field(instr, 31 - 19, 4); 86499730Sbenno pstr += sprintf(pstr, ", %d", IMM); 86599730Sbenno func &= ~Op_SR; 86699730Sbenno } 86799730Sbenno} 86899730Sbenno 86999730Sbennovoid 87099730Sbennoop_base(instr_t instr, vm_offset_t loc) 87199730Sbenno{ 87299730Sbenno dis_ppc(opcodes, instr, loc); 87399730Sbenno} 87499730Sbenno 87599730Sbennovoid 87699730Sbennoop_cl_x13(instr_t instr, vm_offset_t loc) 87799730Sbenno{ 87899730Sbenno dis_ppc(opcodes_13, instr, loc); 87999730Sbenno} 88099730Sbenno 88199730Sbennovoid 88299730Sbennoop_cl_x1e(instr_t instr, vm_offset_t loc) 88399730Sbenno{ 88499730Sbenno dis_ppc(opcodes_1e, instr, loc); 88599730Sbenno} 88699730Sbenno 88799730Sbennovoid 88899730Sbennoop_cl_x1f(instr_t instr, vm_offset_t loc) 88999730Sbenno{ 89099730Sbenno dis_ppc(opcodes_1f, instr, loc); 89199730Sbenno} 89299730Sbenno 89399730Sbennovoid 89499730Sbennoop_cl_x3a(instr_t instr, vm_offset_t loc) 89599730Sbenno{ 89699730Sbenno dis_ppc(opcodes_3a, instr, loc); 89799730Sbenno} 89899730Sbenno 89999730Sbennovoid 90099730Sbennoop_cl_x3b(instr_t instr, vm_offset_t loc) 90199730Sbenno{ 90299730Sbenno dis_ppc(opcodes_3b, instr, loc); 90399730Sbenno} 90499730Sbenno 90599730Sbennovoid 90699730Sbennoop_cl_x3e(instr_t instr, vm_offset_t loc) 90799730Sbenno{ 90899730Sbenno dis_ppc(opcodes_3e, instr, loc); 90999730Sbenno} 91099730Sbenno 91199730Sbennovoid 91299730Sbennoop_cl_x3f(instr_t instr, vm_offset_t loc) 91399730Sbenno{ 91499730Sbenno dis_ppc(opcodes_3f, instr, loc); 91599730Sbenno} 91699730Sbenno 91799730Sbennovoid 91899730Sbennodis_ppc(const struct opcode *opcodeset, instr_t instr, vm_offset_t loc) 91999730Sbenno{ 92099730Sbenno const struct opcode *op; 92199730Sbenno int found = 0; 92299730Sbenno int i; 92399730Sbenno char disasm_str[30]; 92499730Sbenno 92599730Sbenno for (i = 0, op = &opcodeset[0]; 92699730Sbenno found == 0 && op->mask != 0; 92799730Sbenno i++, op = &opcodeset[i]) { 92899730Sbenno if ((instr & op->mask) == op->code) { 92999730Sbenno found = 1; 93099730Sbenno disasm_fields(op, instr, loc, disasm_str); 93199730Sbenno db_printf("%s%s\n", op->name, disasm_str); 93299730Sbenno return; 93399730Sbenno } 93499730Sbenno } 93599730Sbenno op_ill(instr, loc); 93699730Sbenno} 93799730Sbenno 93899730Sbennodb_addr_t 93999730Sbennodb_disasm(db_addr_t loc, boolean_t extended) 94099730Sbenno{ 94199730Sbenno int class; 94299730Sbenno instr_t opcode; 94399730Sbenno opcode = *(instr_t *)(loc); 94499730Sbenno class = opcode >> 26; 94599730Sbenno (opcodes_base[class])(opcode, loc); 94699730Sbenno 94799730Sbenno return (loc + 4); 94899730Sbenno} 94999730Sbenno 95099730Sbennovm_offset_t opc_disasm(vm_offset_t loc, int); 95199730Sbenno 95299730Sbennovm_offset_t 95399730Sbennoopc_disasm(vm_offset_t loc, int xin) 95499730Sbenno{ 95599730Sbenno int class; 95699730Sbenno instr_t opcode; 95799730Sbenno opcode = xin; 95899730Sbenno class = opcode >> 26; 95999730Sbenno (opcodes_base[class])(opcode, loc); 96099730Sbenno 96199730Sbenno return (loc + 4); 96299730Sbenno} 963