📄 disassemble.c
字号:
{ "fdiv", 0xfc00003e, 0xfc000024, Op_D | Op_A | Op_B | Op_Rc }, { "fsub", 0xfc00003e, 0xfc000028, Op_D | Op_A | Op_B | Op_Rc }, { "fadd", 0xfc00003e, 0xfc00002a, Op_D | Op_A | Op_B | Op_Rc }, { "fsqrt", 0xfc00003e, 0xfc00002c, Op_D | Op_B | Op_Rc }, { "fsel", 0xfc00003e, 0xfc00002e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, { "fmul", 0xfc00003e, 0xfc000032, Op_D | Op_A | Op_C | Op_Rc }, { "frsqrte", 0xfc00003e, 0xfc000034, Op_D | Op_B | Op_Rc }, { "fmsub", 0xfc00003e, 0xfc000038, Op_D | Op_A | Op_B | Op_C | Op_Rc }, { "fmadd", 0xfc00003e, 0xfc00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc }, { "fnmsub", 0xfc00003e, 0xfc00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc }, { "fnmadd", 0xfc00003e, 0xfc00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, { "fcmpo", 0xfc0007fe, 0xfc000040, Op_crfD | Op_A | Op_B }, { "mtfsb1", 0xfc0007fe, 0xfc00004c, Op_crfD | Op_Rc }, { "fneg", 0xfc0007fe, 0xfc000050, Op_D | Op_B | Op_Rc }, { "mcrfs", 0xfc0007fe, 0xfc000080, Op_D | Op_B | Op_Rc }, { "mtfsb0", 0xfc0007fe, 0xfc00008c, Op_crfD | Op_Rc }, { "fmr", 0xfc0007fe, 0xfc000090, Op_D | Op_B | Op_Rc }, { "mtfsfi", 0xfc0007fe, 0xfc00010c, Op_crfD | Op_IMM | Op_Rc }, { "fnabs", 0xfc0007fe, 0xfc000110, Op_D | Op_B | Op_Rc }, { "fabs", 0xfc0007fe, 0xfc000210, Op_D | Op_B | Op_Rc }, { "mffs", 0xfc0007fe, 0xfc00048e, Op_D | Op_B | Op_Rc }, { "mtfsf", 0xfc0007fe, 0xfc00058e, Op_FM | Op_B | Op_Rc }, { "fctid", 0xfc0007fe, 0xfc00065c, Op_D | Op_B | Op_Rc }, { "fctidz", 0xfc0007fe, 0xfc00065e, Op_D | Op_B | Op_Rc }, { "fcfid", 0xfc0007fe, 0xfc00069c, Op_D | Op_B | Op_Rc }, { "", 0x0, 0x0, 0 }};struct sprreg { int regno; char *regname;} const sprlut[] = { { 1, "xer" }, { 8, "lr" }, { 9, "ctr" }, { 18, "dsisr" }, { 19, "dar" }, { 22, "dec" }, { 25, "sdr1" }, { 26, "srr0" }, { 27, "srr1" }, { 272, "sprg0" }, { 273, "sprg1" }, { 274, "sprg3" }, { 275, "sprg3" }, { 280, "asr" }, { 282, "ear" }, { 284, "tbl" }, { 285, "tbu" }, { 287, "pvr" }, { 528, "ibat0u" }, { 529, "ibat0l" }, { 530, "ibat1u" }, { 531, "ibat1l" }, { 532, "ibat2u" }, { 533, "ibat2l" }, { 534, "ibat3u" }, { 535, "ibat3l" }, { 536, "dbat0u" }, { 537, "dbat0l" }, { 538, "dbat1u" }, { 539, "dbat1l" }, { 540, "dbat2u" }, { 541, "dbat2l" }, { 542, "dbat3u" }, { 543, "dbat3l" }, { 936, "ummcr0" }, { 937, "upmc1" }, { 938, "upmc2" }, { 939, "usia" }, { 940, "ummcr1" }, { 941, "upmc3" }, { 942, "upmc4" }, { 952, "mmcr0" }, { 953, "pmc1" }, { 954, "pmc2" }, { 955, "sia" }, { 956, "mmcr1" }, { 957, "pmc3" }, { 958, "pmc4" }, { 1008, "hid0" }, { 1009, "hid1" }, { 1010, "iabr" }, { 1013, "dabr" }, { 1017, "l2cr" }, { 1019, "ictc" }, { 1020, "thrm1" }, { 1021, "thrm2" }, { 1022, "thrm3" }, { 0, NULL },};/*typedef void (op_class_func) (instr_t);*/void * md_disasm __P((char *buf, void *loc));static u_int32_t extract_field __P((u_int32_t, u_int32_t, u_int32_t));static void disasm_fields __P((const struct opcode *, instr_t, char *, void *));static void dispchist __P((int, int));const struct opcode * search_op(const struct opcode *);voidop_ill(char *buf, instr_t instr, void *pc){ sprintf(buf, "illegal instruction %x\n", instr);}static u_int32_textract_field(u_int32_t value, u_int32_t base, u_int32_t width){ u_int32_t mask = (1 << width) - 1; return ((value >> base) & mask);}static voiddisasm_fields(const struct opcode *popcode, instr_t instr, char *disasm_str, void *pc){ char * pstr; enum function_mask func; char cbuf[64]; pstr = disasm_str; func = popcode->func; if (func & Op_OE) { u_int OE; /* also for Op_S (they are the same) */ OE = extract_field(instr, 31 - 21, 1); if (OE) { pstr += sprintf (pstr, "o"); } func &= ~Op_D; } switch (func & Op_LKM) { case Op_Rc: if (instr & 0x1) { pstr += sprintf (pstr,". "); } break; case Op_AA: if (instr & 0x1) { pstr += sprintf (pstr,"l "); } if (instr & 0x2) { pstr += sprintf (pstr,"a"); } break; case Op_LK: if (instr & 0x1) { pstr += sprintf (pstr,"l "); } break; default: func &= ~Op_LKM; } pstr += sprintf (pstr, " "); if (func & Op_D) { u_int D; /* also for Op_S (they are the same) */ D = extract_field(instr, 31 - 10, 5); pstr += sprintf (pstr, "r%d, ", D); func &= ~Op_D; } if (func & Op_crbD) { u_int crbD; crbD = extract_field(instr, 31 - 10, 5); pstr += sprintf (pstr, "crb%d, ", crbD); func &= ~Op_crbD; } if (func & Op_crfD) { u_int crfD; crfD = extract_field(instr, 31 - 8, 3); pstr += sprintf (pstr, "crf%d, ", crfD); func &= ~Op_crfD; } if (func & Op_L) { u_int L; L = extract_field(instr, 31 - 10, 1); if (L) { pstr += sprintf (pstr, "L, "); } func &= ~Op_L; } if (func & Op_FM) { u_int FM; FM = extract_field(instr, 31 - 10, 8); pstr += sprintf (pstr, "%d, ", FM); func &= ~Op_FM; } if (func & Op_TO) { u_int TO; TO = extract_field(instr, 31 - 10, 1); pstr += sprintf (pstr, "%d, ", TO); func &= ~Op_TO; } if (func & Op_crfS) { u_int crfS; crfS = extract_field(instr, 31 - 13, 3); pstr += sprintf (pstr, "%d, ", crfS); func &= ~Op_crfS; } if (func & Op_BO) { u_int BO; BO = extract_field(instr, 31 - 10, 5); pstr += sprintf (pstr ,"%d, ", BO); func &= ~Op_BO; } if (func & Op_A) { u_int A; A = extract_field(instr, 31 - 15, 5); pstr += sprintf (pstr, "r%d, ", A); func &= ~Op_A; } if (func & Op_B) { u_int B; B = extract_field(instr, 31 - 20, 5); pstr += sprintf (pstr, "r%d, ", B); func &= ~Op_B; } if (func & Op_C) { u_int C; C = extract_field(instr, 31 - 25, 5); pstr += sprintf (pstr, "r%d, ", C); func &= ~Op_C; } if (func & Op_BI) { u_int BI; BI = extract_field(instr, 31 - 10, 5); pstr += sprintf (pstr, "%d, ", BI); func &= ~Op_BI; } if (func & Op_crbA) { u_int crbA; crbA = extract_field(instr, 31 - 15, 5); pstr += sprintf (pstr, "%d, ", crbA); func &= ~Op_crbA; } if (func & Op_crbB) { u_int crbB; crbB = extract_field(instr, 31 - 20, 5); pstr += sprintf (pstr, "%d, ", crbB); func &= ~Op_crbB; } if (func & Op_CRM) { u_int CRM; CRM = extract_field(instr, 31 - 19, 8); pstr += sprintf (pstr, "0x%x, ", CRM); func &= ~Op_CRM; } if (func & Op_LI) { u_int LI; LI = extract_field(instr, 31 - 29, 24); LI = LI << (31 - 29);/* XXX Target address needs fixing. Look at AA bit! */ if(adr2symoff(cbuf, (int)pc + LI, 0)) { pstr += sprintf(pstr, "%s ", cbuf); } else { pstr += sprintf (pstr, "0x%x, ", LI + pc); } func &= ~Op_LI; } switch (func & Op_SIMM) { u_int IMM; case Op_SIMM: /* same as Op_d */ IMM = extract_field(instr, 31 - 31, 16); if (IMM & 0x8000) { pstr += sprintf (pstr, "-"); } /* no break */ func &= ~Op_SIMM; case Op_UIMM: IMM = extract_field(instr, 31 - 31, 16); pstr += sprintf (pstr, "0x%x ", IMM); func &= ~Op_UIMM; break; default: } if (func & Op_BD ) { u_int BD; BD = extract_field(instr, 31 - 29, 14); BD = (BD | (0 - (BD & 0x2000))) * 4; if(adr2symoff(cbuf, (int)pc + BD, 0)) { pstr += sprintf(pstr, "%s ", cbuf); } else { pstr += sprintf (pstr, "0x%x, ", BD + pc); } func &= ~Op_BD; } if (func & Op_ds ) { u_int ds; ds = extract_field(instr, 31 - 29, 14) << 2; pstr += sprintf (pstr, "0x%x, ", ds); func &= ~Op_ds; } if (func & Op_spr ) { u_int spr; u_int sprl; u_int sprh; char *reg; const struct sprreg *sprtab = sprlut; sprl = extract_field(instr, 31 - 15, 5); sprh = extract_field(instr, 31 - 20, 5); spr = sprh << 5 | sprl; while(sprtab->regno != spr && sprtab->regno != 0) { sprtab++; } reg = sprtab->regname; if (reg == 0) { pstr += sprintf (pstr, "[unknown spr (%d)]", spr); } else { pstr += sprintf (pstr, "%s", reg); } func &= ~Op_spr; } if (func & Op_me) { u_int me, mel, meh; mel = extract_field(instr, 31 - 25, 4); meh = extract_field(instr, 31 - 26, 1); me = meh << 4 | mel; pstr += sprintf (pstr, ", 0x%x", me); func &= ~Op_me; } if ((func & Op_MB ) && (func & Op_sh_mb_sh)) { u_int MB; u_int ME; MB = extract_field(instr, 31 - 20, 5); pstr += sprintf (pstr, "%d", MB); ME = extract_field(instr, 31 - 25, 5); pstr += sprintf (pstr, ", %d", ME); } if ((func & Op_SH ) && (func & Op_sh_mb_sh)) { u_int SH; SH = extract_field(instr, 31 - 20, 5); pstr += sprintf (pstr, ", %d", SH); } if ((func & Op_sh ) && ! (func & Op_sh_mb_sh)) { u_int sh, shl, shh; shl = extract_field(instr, 31 - 19, 4); shh = extract_field(instr, 31 - 20, 1); sh = shh << 4 | shl; pstr += sprintf (pstr, ", %d", sh); } if ((func & Op_mb ) && ! (func & Op_sh_mb_sh)) { u_int mb, mbl, mbh; mbl = extract_field(instr, 31 - 25, 4); mbh = extract_field(instr, 31 - 26, 1); mb = mbh << 4 | mbl; pstr += sprintf (pstr, ", %d", mb); } if ((func & Op_me ) && ! (func & Op_sh_mb_sh)) { u_int me, mel, meh; mel = extract_field(instr, 31 - 25, 4); meh = extract_field(instr, 31 - 26, 1); me = meh << 4 | mel; pstr += sprintf (pstr, ", %d", me); } if (func & Op_tbr ) { u_int tbr; u_int tbrl; u_int tbrh; char *reg; tbrl = extract_field(instr, 31 - 15, 5); tbrh = extract_field(instr, 31 - 20, 5); tbr = tbrh << 5 | tbrl; switch (tbr) { case 268: reg = "tbl"; break; case 269: reg = "tbu"; break; default: reg = 0; } if (reg == 0) { pstr += sprintf (pstr, ", [unknown tbr %d ]", tbr); } else { pstr += sprintf (pstr, ", %s", reg); } func &= ~Op_tbr; } if (func & Op_SR) { u_int SR; SR = extract_field(instr, 31 - 15, 3); pstr += sprintf (pstr, "sr%d", SR); func &= ~Op_SR; } if (func & Op_NB) { u_int NB; NB = extract_field(instr, 31 - 20, 5); if (NB == 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -