--- mon/src/mon_ppc.cpp 2003/09/27 20:33:06 1.7 +++ mon/src/mon_ppc.cpp 2005/03/13 17:09:19 1.9 @@ -1,7 +1,7 @@ /* * mon_ppc.cpp - PowerPC disassembler * - * cxmon (C) 1997-2003 Christian Bauer, Marc Hellwig + * cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ // Instruction fields -static int primop, exop, ra, rb, rc, rd; +static int primop, exop, vxop, ra, rb, rc, rd; static unsigned short imm; @@ -96,6 +96,11 @@ static char *to_code[32] = { #define dsform(s) fprintf(f, "%s\tr%d,$%04x(r%d)\n", s, rd, short(imm & 0xfffc), ra) +#define xform_vls(s) \ + if (ra == 0) \ + fprintf(f, "%s\tv%d,r%d\n", s, rd, rb); \ + else \ + fprintf(f, "%s\tv%d,r%d,r%d\n", s, rd, ra, rb) #define xform_ls(s) \ if (ra == 0) \ fprintf(f, "%s\tr%d,r%d\n", s, rd, rb); \ @@ -160,8 +165,12 @@ static char *to_code[32] = { #define mdsform(s) fprintf(f, "%s%s\tr%d,r%d,r%d,%d\n", s, w & 1 ? "." : "", ra, rd, rb, rc | (w & 32 ? 32 : 0)) +#define vx_form(s) fprintf(f, "%s\tv%d,v%d,v%d\n", s, rd, ra, rb) +#define vxi_form(s) fprintf(f, "%s\tv%d,v%d,v%d,%d\n", s, rd, ra, rb, (rc & 15)) +#define va_form(s) fprintf(f, "%s\tv%d,v%d,v%d,v%d\n", s, rd, ra, rb, rc) // Prototypes +static void disass4(FILE *f, unsigned int adr, unsigned int w); static void disass19(FILE *f, unsigned int adr, unsigned int w); static void disass31(FILE *f, unsigned int adr, unsigned int w); static void disass59(FILE *f, unsigned int adr, unsigned int w); @@ -183,6 +192,7 @@ void disass_ppc(FILE *f, unsigned int ad rb = w >> 11 & 0x1f; rc = w >> 6 & 0x1f; exop = w >> 1 & 0x3ff; + vxop = w & 0x7ff; imm = w & 0xffff; // Decode primary opcode @@ -201,7 +211,9 @@ void disass_ppc(FILE *f, unsigned int ad dform_to("twi"); break; -// case 4: // AltiVec + case 4: // AltiVec + disass4(f, adr, w); + break; case 7: dform_simm("mulli"); break; case 8: dform_simm("subfic"); break; @@ -393,6 +405,115 @@ void disass_ppc(FILE *f, unsigned int ad /* + * Disassemble instruction with primary opcode = 4 (VX-Form) + */ + +static void disass4(FILE *f, unsigned int adr, unsigned int w) +{ + switch (vxop) { + case 384: vx_form("vaddcuw"); break; + case 10: vx_form("vaddfp"); break; + case 768: vx_form("vaddsbs"); break; + case 832: vx_form("vaddshs"); break; + case 896: vx_form("vaddsws"); break; + case 0: vx_form("vaddubm"); break; + case 512: vx_form("vaddubs"); break; + case 64: vx_form("vadduhm"); break; + case 576: vx_form("vadduhs"); break; + case 128: vx_form("vadduwm"); break; + case 640: vx_form("vadduws"); break; + case 1028: vx_form("vand"); break; + case 1092: vx_form("vandc"); break; + case 1282: vx_form("vavgsb"); break; + case 1346: vx_form("vavgsh"); break; + case 1410: vx_form("vavgsw"); break; + case 1026: vx_form("vavgub"); break; + case 1090: vx_form("vavguh"); break; + case 1154: vx_form("vavguw"); break; + case 1034: vx_form("vmaxfp"); break; + case 258: vx_form("vmaxsb"); break; + case 322: vx_form("vmaxsh"); break; + case 386: vx_form("vmaxsw"); break; + case 2: vx_form("vmaxub"); break; + case 66: vx_form("vmaxus"); break; + case 130: vx_form("vmaxuw"); break; + case 1098: vx_form("vminfp"); break; + case 770: vx_form("vminsb"); break; + case 834: vx_form("vminsh"); break; + case 898: vx_form("vminsw"); break; + case 514: vx_form("vminub"); break; + case 578: vx_form("vminuh"); break; + case 642: vx_form("vminuw"); break; + case 12: vx_form("vmrghb"); break; + case 76: vx_form("vmrghh"); break; + case 140: vx_form("vmrghw"); break; + case 268: vx_form("vmrglb"); break; + case 332: vx_form("vmrglh"); break; + case 396: vx_form("vmrglw"); break; + case 776: vx_form("vmulesb"); break; + case 840: vx_form("vmulesh"); break; + case 520: vx_form("vmuleub"); break; + case 584: vx_form("vmuleuh"); break; + case 264: vx_form("vmulosb"); break; + case 328: vx_form("vmulosh"); break; + case 8: vx_form("vmuloub"); break; + case 72: vx_form("vmulouh"); break; + case 1284: vx_form("vnor"); break; + case 1156: vx_form("vor"); break; + case 1220: vx_form("vxor"); break; + case 782: vx_form("vpkpx"); break; + case 398: vx_form("vpkshss"); break; + case 270: vx_form("vpkshus"); break; + case 462: vx_form("vpkswss"); break; + case 334: vx_form("vpkswus"); break; + case 14: vx_form("vpkuhum"); break; + case 142: vx_form("vpkuhus"); break; + case 78: vx_form("vpkuwum"); break; + case 206: vx_form("vpkuwus"); break; + case 4: vx_form("vrlb"); break; + case 68: vx_form("vrlh"); break; + case 132: vx_form("vrlw"); break; + case 452: vx_form("vsl"); break; + case 260: vx_form("vslb"); break; + case 324: vx_form("vslh"); break; + case 1036: vx_form("vslo"); break; + case 388: vx_form("vslw"); break; + case 708: vx_form("vsr"); break; + case 772: vx_form("vsrab"); break; + case 836: vx_form("vsrah"); break; + case 900: vx_form("vsraw"); break; + case 516: vx_form("vsrb"); break; + case 580: vx_form("vsrh"); break; + case 1100: vx_form("vsro"); break; + case 644: vx_form("vsrw"); break; + case 1408: vx_form("vsubcuw"); break; + case 74: vx_form("vsubfp"); break; + case 1792: vx_form("vsubsbs"); break; + case 1856: vx_form("vsubshs"); break; + case 1920: vx_form("vsubsws"); break; + case 1024: vx_form("vsububm"); break; + case 1536: vx_form("vsububs"); break; + case 1088: vx_form("vsubuhm"); break; + case 1600: vx_form("vsubuhs"); break; + case 1152: vx_form("vsubuwm"); break; + case 1664: vx_form("vsubuws"); break; + case 1928: vx_form("vsumsws"); break; + case 1672: vx_form("vsum2sws"); break; + case 1800: vx_form("vsum4sbs"); break; + case 1608: vx_form("vsum4shs"); break; + case 1544: vx_form("vsum4ubs"); break; + default: + if ((vxop & 0x43f) == 44) { + vxi_form("vsldoi"); + break; + } + fprintf(f, "?\n"); + break; + } +} + + +/* * Disassemble instruction with primary opcode = 19 (XL-Form) */ @@ -494,6 +615,8 @@ static void disass31(FILE *f, unsigned i xform_to("tw"); break; + case 6: xform_vls("lvsl"); break; + case 7: xform_vls("lvebx"); break; case 8: xoform_dab("subfc"); break; case 8+512: xoform_dab("subfco"); break; case 9: case 9+512: xoform_dab("mulhdu"); break; // 64 bit @@ -516,6 +639,8 @@ static void disass31(FILE *f, unsigned i xform_crlab("cmplw"); break; + case 38: xform_vls("lvsr"); break; + case 39: xform_vls("lvehx"); break; case 40: xoform_dab("subf"); break; case 40+512: xoform_dab("subfo"); break; case 53: xform_ls("ldux"); break; // 64 bit @@ -531,12 +656,14 @@ static void disass31(FILE *f, unsigned i xform_to("td"); break; + case 71: xform_vls("lvewx"); break; case 73: case 73+512: xoform_dab("mulhd"); break; // 64 bit case 75: case 75+512: xoform_dab("mulhw"); break; case 83: xform_d("mfmsr"); break; case 84: xform_ls("ldarx"); break; // 64 bit case 86: xform_ab("dcbf"); break; case 87: xform_ls("lbzx"); break; + case 103: xform_vls("lvx"); break; case 104: xoform_da("neg"); break; case 104+512: xoform_da("nego"); break; case 119: xform_ls("lbzux"); break; @@ -548,6 +675,7 @@ static void disass31(FILE *f, unsigned i xform_sabc("nor"); break; + case 135: xform_vls("stvebx"); break; case 136: xoform_dab("subfe"); break; case 136+512: xoform_dab("subfeo"); break; case 138: xoform_dab("adde"); break; @@ -564,8 +692,10 @@ static void disass31(FILE *f, unsigned i break; case 151: xform_ls("stwx"); break; + case 167: xform_vls("stvehx"); break; case 181: xform_ls("stdux"); break; // 64 bit case 183: xform_ls("stwux"); break; + case 199: xform_vls("stvewx"); break; case 200: xoform_da("subfze"); break; case 200+512: xoform_da("subfzeo"); break; case 202: xoform_da("addze"); break; @@ -580,6 +710,7 @@ static void disass31(FILE *f, unsigned i break; case 215: xform_ls("stbx"); break; + case 231: xform_vls("stvx"); break; case 232: xoform_da("subfme"); break; case 232+512: xoform_da("subfmeo"); break; case 233: xoform_dab("mulld"); break; // 64 bit @@ -608,6 +739,8 @@ static void disass31(FILE *f, unsigned i fprintf(f, "mflr\tr%d\n", rd); else if ((ra | (rb << 5)) == 9) fprintf(f, "mfctr\tr%d\n", rd); + else if ((ra | (rb << 5)) == 256) + fprintf(f, "mfvrsave\tr%d\n", rd); else { char *spr = get_spr(ra | (rb << 5)); if (spr) @@ -619,6 +752,7 @@ static void disass31(FILE *f, unsigned i case 341: xform_ls("lwax"); break; // 64 bit case 343: xform_ls("lhax"); break; + case 359: xform_vls("lvxl"); break; case 370: xform("tlbia"); break; case 371: @@ -657,6 +791,8 @@ static void disass31(FILE *f, unsigned i fprintf(f, "mtlr\tr%d\n", rd); else if ((ra | (rb << 5)) == 9) fprintf(f, "mtctr\tr%d\n", rd); + else if ((ra | (rb << 5)) == 256) + fprintf(f, "mtvrsave\tr%d\n", rd); else { char *spr = get_spr(ra | (rb << 5)); if (spr) @@ -668,6 +804,7 @@ static void disass31(FILE *f, unsigned i case 470: xform_ab("dcbi"); break; case 476: xform_sabc("nand"); break; + case 487: xform_vls("stvxl"); break; case 489: xoform_dab("divd"); break; // 64 bit case 489+512: xoform_dab("divdo"); break; // 64 bit case 491: xoform_dab("divw"); break;