static void add_reg(unsigned reg, unsigned size) { if (reg >= 8) { add_char('r'); add_dec_uint32(reg); switch (size) { case 1: add_char('l'); break; case 2: add_char('w'); break; case 4: add_char('d'); break; } return; } if (x86_64 && size == 1 && reg >= 4 && reg <= 7) { switch (reg) { case 4: add_str("spl"); break; case 5: add_str("bpl"); break; case 6: add_str("sil"); break; case 7: add_str("dil"); break; } return; } if (size == 1) { switch (reg) { case 0: add_str("al"); break; case 1: add_str("cl"); break; case 2: add_str("dl"); break; case 3: add_str("bl"); break; case 4: add_str("ah"); break; case 5: add_str("ch"); break; case 6: add_str("dh"); break; case 7: add_str("bh"); break; } } else { switch (size) { case 4: add_char('e'); break; case 8: add_char('r'); break; } switch (reg) { case 0: add_str("ax"); break; case 1: add_str("cx"); break; case 2: add_str("dx"); break; case 3: add_str("bx"); break; case 4: add_str("sp"); break; case 5: add_str("bp"); break; case 6: add_str("si"); break; case 7: add_str("di"); break; } } }
static void add_dbg_reg(unsigned reg) { add_str("dr"); add_dec_uint32(reg); }
static void add_ctrl_reg(unsigned reg) { add_str("cr"); add_dec_uint32(reg); }
static void add_op_31(uint32_t instr) { uint32_t xop = bits_uint32(instr, 21, 10); uint8_t rX = bits_uint8(instr, 6, 5); uint8_t rA = bits_uint8(instr, 11, 5); uint8_t rB = bits_uint8(instr, 16, 5); switch (xop) { case 0: add_str("cmp"); add_str(" "); add_dec_uint8(bits_uint8(instr, 6, 3)); add_str(", "); add_dec_uint8(bits_uint8(instr, 10, 1)); add_str(", r"); add_dec_uint8(rA); add_str(", r"); add_dec_uint8(rB); break; case 4: add_str("tw"); add_str(" "); add_dec_uint8(bits_uint8(instr, 6, 5)); add_str(", r"); add_dec_uint8(rA); add_str(", r"); add_dec_uint8(rB); break; case 8: add_xo_form(instr, "subfc"); break; case 9: add_xo_form(instr, "mulhdu"); break; case 10: add_xo_form(instr, "addc"); break; case 11: add_xo_form(instr, "mulhwu"); break; case 19: if (bits_uint8(instr, 11, 1) == 0) { add_str("mfcr"); add_str(" r"); add_dec_uint8(bits_uint8(instr, 6, 5)); } else { add_str("mfocrf"); add_str(" r"); add_dec_uint8(bits_uint8(instr, 6, 5)); add_str(", "); add_dec_uint8(bits_uint32(instr, 12, 8)); } break; case 20: add_op_3r(instr, "lwarx"); break; case 21: add_op_3r(instr, "ldx"); break; case 23: add_op_3r(instr, "lwzx"); break; case 24: add_op_3r_rc(instr, "slw"); break; case 26: add_op_2r_rc(instr, "cntlzw"); break; case 27: add_op_3r_rc(instr, "sld"); break; case 28: add_op_3r_rc(instr, "and"); break; case 32: add_str("cmpl"); add_str(" "); add_dec_uint8(bits_uint8(instr, 6, 3)); add_str(", "); add_dec_uint8(bits_uint8(instr, 10, 1)); add_str(", r"); add_dec_uint8(rA); add_str(", r"); add_dec_uint8(rB); break; case 40: add_xo_form(instr, "subf"); break; case 55: add_op_3r(instr, "lwzux"); break; case 73: add_xo_form(instr, "mulhd"); break; case 75: add_xo_form(instr, "mulhw"); break; case 83: add_str("mfmsr"); add_str(" r"); add_dec_uint8(rX); break; case 104: add_xo_form(instr, "neg"); break; case 136: add_xo_form(instr, "subfe"); break; case 138: add_xo_form(instr, "adde"); break; case 146: add_str("mtmsr"); add_str(" r"); add_dec_uint8(rX); add_str(", "); add_dec_uint8(bits_uint8(instr, 15, 1)); break; case 200: add_xo_form(instr, "subfze"); break; case 202: add_xo_form(instr, "addze"); break; case 232: add_xo_form2(instr, "subfme"); break; case 233: add_xo_form(instr, "mulld"); break; case 234: add_xo_form2(instr, "addme"); break; case 235: add_xo_form(instr, "mullw"); break; case 266: add_xo_form(instr, "add"); break; case 339: { uint32_t spr = bits_uint8(instr, 11, 10); if (spr == 1) { add_str("mfxer"); add_str(" r"); add_dec_uint8(rX); } else if (spr == 8) { add_str("mflr"); add_str(" r"); add_dec_uint8(rX); } else if (spr == 9) { add_str("mfctr"); add_str(" r"); add_dec_uint8(rX); } else { add_str("mfspr"); add_str(" r"); add_dec_uint8(rX); add_str(", "); add_dec_uint32(spr); } } break; case 444: if (rX == rB) { add_str("mr"); add_str(" r"); add_dec_uint8(rA); add_str(", r"); add_dec_uint8(rX); } else { add_str("or"); add_str(" r"); add_dec_uint8(rA); add_str(", r"); add_dec_uint8(rX); add_str(", r"); add_dec_uint8(rB); } break; case 457: add_xo_form(instr, "divdu"); break; case 459: add_xo_form(instr, "divwu"); break; case 467: { uint32_t spr = bits_uint8(instr, 11, 10); if (spr == 1) { add_str("mtxer"); add_str(" r"); add_dec_uint8(rX); } else if (spr == 8) { add_str("mtlr"); add_str(" r"); add_dec_uint8(rX); } else if (spr == 9) { add_str("mtctr"); add_str(" r"); add_dec_uint8(rX); } else { add_str("mtspr"); add_str(" "); add_dec_uint32(spr); add_str(", "); add_dec_uint8(rX); } } break; case 489: add_xo_form(instr, "divd"); break; case 491: add_xo_form(instr, "divw"); break; case 792: add_op_3r_rc(instr, "sraw"); break; case 794: add_op_3r_rc(instr, "srad"); break; case 824: add_op_3r_rc(instr, "srawi"); break; case 922: add_op_2r_rc(instr, "extsh"); break; case 954: add_op_2r_rc(instr, "extsb"); break; case 986: add_op_2r_rc(instr, "extsw"); break; } }