diff --git a/cpu/ppc/ppcdisasm.cpp b/cpu/ppc/ppcdisasm.cpp index e50d75c..a3bcb60 100644 --- a/cpu/ppc/ppcdisasm.cpp +++ b/cpu/ppc/ppcdisasm.cpp @@ -159,7 +159,7 @@ void fmt_twoop_tospr(string& buf, const char* opc, int dst, int src) void fmt_twoop_flt(string& buf, const char* opc, int dst, int src1) { - buf = my_sprintf("%-8sfr%d, fr%d", opc, dst, src1); + buf = my_sprintf("%-8sf%d, f%d", opc, dst, src1); } void fmt_threeop(string& buf, const char* opc, int dst, int src1, int src2) @@ -185,12 +185,12 @@ void fmt_threeop_simm(string& buf, const char* opc, int dst, int src1, int imm) void fmt_threeop_flt(string& buf, const char* opc, int dst, int src1, int src2) { - buf = my_sprintf("%-8sfr%d, fr%d, fr%d", opc, dst, src1, src2); + buf = my_sprintf("%-8sf%d, f%d, f%d", opc, dst, src1, src2); } void fmt_fourop_flt(string& buf, const char* opc, int dst, int src1, int src2, int src3) { - buf = my_sprintf("%-8sfr%d, fr%d, fr%d, fr%d", opc, dst, src1, src2, src3); + buf = my_sprintf("%-8sf%d, f%d, f%d, f%d", opc, dst, src1, src2, src3); } void fmt_rotateop(string& buf, const char* opc, int dst, int src, int sh, int mb, int me, bool imm) @@ -917,31 +917,29 @@ void opc_group31(PPCDisasmContext* ctx) case 0x17: /* indexed load/store instructions */ + if (index == 30) { /* stfiwx sneaks in here */ + if (rc_set) { + opc_illegal(ctx); + return; + } + else { + if (ra == 0) + ctx->instr_str = my_sprintf("%-8sf%d, 0, r%d", opc_idx_ldst[index], rs, rb); + else { + ctx->instr_str = my_sprintf("%-8sf%d, r%d, r%d", opc_idx_ldst[index], rs, ra, rb); + } + return; + } + } if (index > 23 || rc_set || strlen(opc_idx_ldst[index]) == 0) { opc_illegal(ctx); return; } if (index < 16) { - if (index == 30) { /* stfiwx sneaks in here */ - if (rc_set) { - opc_illegal(ctx); - return; - } - else { - if (ra == 0) - ctx->instr_str = my_sprintf("%-8sr%d, 0, r%d", opc_idx_ldst[index], rs, rb); - else { - fmt_threeop(ctx->instr_str, opc_idx_ldst[index], rs, ra, rb); - } - return; - } - } - else { - fmt_threeop(ctx->instr_str, opc_idx_ldst[index], rs, ra, rb); - } + fmt_threeop(ctx->instr_str, opc_idx_ldst[index], rs, ra, rb); } else { - ctx->instr_str = my_sprintf("%-8sfp%d, r%d, r%d", + ctx->instr_str = my_sprintf("%-8sfp%d, r%d, r%d", \ opc_idx_ldst[index], rs, ra, rb); } return; @@ -981,10 +979,10 @@ void opc_group31(PPCDisasmContext* ctx) ctx->instr_str = my_sprintf("%-8s", opcode); return; } - /* dcba, dcbf, dcbi, dcbst, dcbt, dcbz, icbi */ + /* dcba, dcbf, dcbi, dcbst, dcbt, dcbz */ else if ((index == 1) | (index == 2) | (index == 7) \ | (index == 8) | (index == 14) \ - | (index == 23) | (index == 30) | (index == 31)) { + | (index == 23) | (index == 31)) { if (rc_set | (rs != 0)) { opc_illegal(ctx); return; @@ -997,6 +995,12 @@ void opc_group31(PPCDisasmContext* ctx) return; } } + else if (index == 30) { /* icbi */ + if (rs == 0) + opc_illegal(ctx); + else + fmt_twoop(ctx->instr_str, opcode, ra, rb); + } else if (index == 17) { /* tlbsync */ ctx->instr_str = my_sprintf("%-8s", opcode); } @@ -1016,7 +1020,7 @@ void opc_group31(PPCDisasmContext* ctx) if (rc_set) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8sr%d, r%d, r%d", "cmp", rs, ra, rb); + ctx->instr_str = my_sprintf("%-8scr%d, %d, r%d, r%d", "cmp", (rs >> 2), (rs & 1), ra, rb); break; case 4: /* tw */ if (rc_set) { @@ -1028,7 +1032,7 @@ void opc_group31(PPCDisasmContext* ctx) if (strlen(opcode) != 0) { ctx->instr_str = my_sprintf("%-8sr%d, r%d", opcode, ra, rb); - return; + break; } } @@ -1051,12 +1055,13 @@ void opc_group31(PPCDisasmContext* ctx) } break; case 26: /* cntlzw */ - strcpy(opcode, "cntlzw"); + printf("CASE REACH! \n"); if (rc_set) - strcat(opcode, "."); + fmt_twoop(ctx->instr_str, "cntlzw.", rs, ra); + else + fmt_twoop(ctx->instr_str, "cntlzw", rs, ra); - fmt_twoop(ctx->instr_str, opcode, rs, ra); break; case 29: /* maskg */ strcpy(opcode, "maskg"); @@ -1070,7 +1075,7 @@ void opc_group31(PPCDisasmContext* ctx) if (rc_set) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8sr%d, r%d, r%d", "cmpl", rs, ra, rb); + ctx->instr_str = my_sprintf("%-8scr%d, %d, r%d, r%d", "cmpl", (rs >> 2), (rs & 1), ra, rb); break; case 83: /* mfmsr */ ctx->instr_str = my_sprintf("%-8sr%d", "mfmsr", @@ -1087,6 +1092,18 @@ void opc_group31(PPCDisasmContext* ctx) case 146: /* mtmsr */ fmt_oneop(ctx->instr_str, "mtmsr", rs); break; + case 210: /* mtsr */ + if (ra & 16) + opc_illegal(ctx); + else + ctx->instr_str = my_sprintf("%-8%d, r%d", "mtsr", ra, rs); + break; + case 242: /* mtsrin */ + if (rb & 16) + opc_illegal(ctx); + else + ctx->instr_str = my_sprintf("%-8r%d, r%d", "mtsr", rs, rb); + break; case 277: /* lscbx */ strcpy(opcode, "lscbx"); @@ -1163,7 +1180,7 @@ void opc_group31(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_threeop(ctx->instr_str, opcode, rs, ra, rb); + fmt_twoop(ctx->instr_str, opcode, rs, ra); break; case 533: /* lswx */ if (rc_set) { @@ -1182,13 +1199,16 @@ void opc_group31(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_threeop(ctx->instr_str, opcode, rs, ra, rb); + fmt_threeop(ctx->instr_str, opcode, ra, rs, rb); return; case 597: /* lswi */ if (rc_set) { opc_illegal(ctx); } else { + if (rb == 0) + rb = 32; + if (ra == 0) ctx->instr_str = my_sprintf("%-8sr%d, 0, %x", "lswi", rs, rb); else @@ -1214,6 +1234,9 @@ void opc_group31(PPCDisasmContext* ctx) return; } else { + if (rb == 0) + rb = 32; + if (ra == 0) ctx->instr_str = my_sprintf("%-8sr%d, 0, %d", "stswi", rs, rb); else @@ -1327,7 +1350,7 @@ void opc_group59(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1339,7 +1362,7 @@ void opc_group59(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1351,7 +1374,7 @@ void opc_group59(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1363,7 +1386,7 @@ void opc_group59(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; } @@ -1469,7 +1492,7 @@ void opc_group63(PPCDisasmContext* ctx) if ((rc != 0) | (ra != 0)) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8s%d, fr%d, fr%d", opcode, rs, rb); + ctx->instr_str = my_sprintf("%-8sf%d, f%d", opcode, rs, rb); return; @@ -1479,7 +1502,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1489,7 +1512,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1499,7 +1522,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; @@ -1509,7 +1532,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rb, rc); + fmt_fourop_flt(ctx->instr_str, opcode, rs, ra, rc, rb); return; } @@ -1521,7 +1544,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rs & 3) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8scr%d, r%d, r%d,", "fcmpu", (rs >> 2), ra, rb); + ctx->instr_str = my_sprintf("%-8scr%d, f%d, f%d", "fcmpu", (rs >> 2), ra, rb); break; case 12: /* frsp */ if (ra != 0) @@ -1545,7 +1568,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rs & 3) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8scr%d, r%d, r%d,", "fcmpo", (rs >> 2), ra, rb); + ctx->instr_str = my_sprintf("%-8scr%d, f%d, f%d", "fcmpo", (rs >> 2), ra, rb); break; case 38: /* mtfsb1 */ strcpy(opcode, "mtfsb1"); @@ -1553,7 +1576,7 @@ void opc_group63(PPCDisasmContext* ctx) if (rc_set) strcat(opcode, "."); - ctx->instr_str = my_sprintf("%-8scrb%d", opcode, rs); + ctx->instr_str = my_sprintf("%-8s%d", opcode, rs); break; case 40: /* fneg */ strcpy(opcode, "fneg"); @@ -1595,13 +1618,13 @@ void opc_group63(PPCDisasmContext* ctx) if (ra != 0) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8s%d, fr%d, fr%d", "fnabs", rs, rb); + ctx->instr_str = my_sprintf("%-8sf%d, f%d", "fnabs", rs, rb); break; case 264: /* fabs */ if (ra != 0) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8s%d, fr%d, fr%d", "fabs", rs, rb); + ctx->instr_str = my_sprintf("%-8s%d, f%d, f%d", "fabs", rs, rb); break; case 583: /* mffs */ strcpy(opcode, "mffs"); @@ -1612,7 +1635,7 @@ void opc_group63(PPCDisasmContext* ctx) if ((ra != 0) | (rb != 0)) opc_illegal(ctx); else - ctx->instr_str = my_sprintf("%-8sfr%d", opcode, rs); + ctx->instr_str = my_sprintf("%-8sf%d", opcode, rs); break; case 711: /* mtfsf */ ctx->instr_str = my_sprintf("%-8sfm%d, r%d", "mtfsf", fm, rb); @@ -1663,11 +1686,11 @@ void opc_fltldst(PPCDisasmContext* ctx) } if (ra) { - ctx->instr_str = my_sprintf("%-8sfr%d, %s0x%X(r%d)", opc_flt_ldst[opcode], + ctx->instr_str = my_sprintf("%-8sf%d, %s0x%X(r%d)", opc_flt_ldst[opcode], rd, ((imm < 0) ? "-" : ""), abs(imm), ra); } else { - ctx->instr_str = my_sprintf("%-8sfr%d, %s0x%X", opc_flt_ldst[opcode], + ctx->instr_str = my_sprintf("%-8sf%d, %s0x%X", opc_flt_ldst[opcode], rd, ((imm < 0) ? "-" : ""), abs(imm)); } } diff --git a/cpu/ppc/test/ppcdisasmtest.csv b/cpu/ppc/test/ppcdisasmtest.csv index 1fe32ab..7a1f57e 100644 --- a/cpu/ppc/test/ppcdisasmtest.csv +++ b/cpu/ppc/test/ppcdisasmtest.csv @@ -1,12 +1,13 @@ # Test data for PowerPC disassembler supplied as comma-separated values # Data format: # instruction address (hex), instruction code (hex), expected disassembly: opcode, [operands...] -# (lines starting with "#" will be treated as comments and ignored) +# (lines starting with a hash sign (#) will be treated as comments and ignored) # unconditional branches 0xFFF03008,0x48000355,bl,0xFFF0335C 0xFFF03000,0x4280035C,b,0xFFF0335C 0xFFF03000,0x48000802,ba,0x00000800 +0xFFF03000,0x48000803,bla,0x00000800 # bcctr variants with simplified mnemonics 0xFFF03000,0x4E800420,bctr @@ -193,9 +194,16 @@ 0xFFF00100,0x7E007120,mtcrf,0x07,r16 # rotation instructions +0xFFF00100,0x5084442E,rlwimi,r4,r4,8,16,23 0xFFF00100,0x5400EFFE,rlwinm,r0,r0,29,31,31 # shift instructions, primary opcode 0x1F +0xFFF00100,0x7C695830,slw,r9,r3,r11 +0xFFF00100,0x7C00F831,slw.,r0,r0,r31 +0xFFF00100,0x7FC4FC30,srw,r4,r30,r31 +0xFFF00100,0x7CE92C31,srw.,r9,r7,r5 +0xFFF00100,0x7D235E30,sraw,r3,r9,r11 +0xFFF00100,0x7D290631,sraw.,r9,r9,r0 0xFFF00100,0x7C65FE70,srawi,r5,r3,0x1F 0xFFF00100,0x7D6B1E70,srawi,r11,r11,0x3 0xFFF00100,0x7C090E71,srawi.,r9,r0,0x1 @@ -218,16 +226,22 @@ 0xFFF00100,0x7C6023B8,nand,r0,r3,r4 0xFFF00100,0x7F8B63B9,nand.,r11,r28,r12 +#logical immediate instructions +0xFFF00100,0x60009BA5,ori,r0,r0,0x9BA5 +0xFFF00100,0x6744AAAA,oris,r4,r26,0xAAAA + # synchronization instructions 0xFFF00100,0x7D201828,lwarx,r9,0,r3 0xFFF00100,0x7D20192D,stwcx.,r9,0,r3 0xFFF00100,0x7FAB052C,stwbrx,r29,r11,r0 0xFFF03000,0x4C00012C,isync -0xFFF00100,7C0006AC,eieio +0xFFF00100,0x7C0004AC,sync +0xFFF00100,0x7C0006AC,eieio +0xFFF00100,0x7C05272C,sthbrx,r0,r5,r4 # trap instructions 0xFFF00100,0x7F800008,tw,28,r0,r0 -0xFFF00100,0C000000,twi,0,r0,0 +0xFFF00100,0x0C000000,twi,0,r0,0 # integer load and stores 0xFFF00100,0x80BF0808,lwz,r5,0x808(r31) @@ -266,13 +280,42 @@ 0xFFF00100,0xBB41FFE8,lmw,r26,-0x18(r1) 0xFFF00100,0xBC410008,stmw,r2,0x8(r1) 0xFFF00100,0xBFC1FFF8,stmw,r30,-0x8(r1) +0xFFF00100,0xD58B0004,stfsu,f12,4(r11) + +#floating point operations +0xFFF00100,0xFC03282A,fadd,f0,f3,f5 +0xFFF00100,0xFDAD682B,fadd.,f13,f13,f13 +0xFFF00100,0xFC0D0024,fdiv,f0,f13,f0 +0xFFF00100,0xFC2B0025,fdiv.,f1,f11,f0 +0xFFF00100,0xFD8952FC,fnmsub,f12,f9,f11,f10 +0xFFF00100,0xFD600110,fnabs,f11,f0 +0xFFF00100,0xFD002034,frsqrte,f8,f4 +0xFFF00100,0x7FF957AE,stfiwx,f31,r25,r10 #compare instructions +0xFFF00100,0x7FBFB800,cmp,cr7,1,r31,r23 +0xFFF00100,0x7FA05840,cmpl,cr7,1,r0,r11 +0xFFF00100,0x2FA90000,cmpi,cr7,1,r9,0x0 0xFFF00100,0x2AA3FFFF,cmpli,cr5,1,r3,0xFFFF +0xFFF00100,0xFE17C840,fcmpo,cr4,f23,f25 +0xFFF00100,0xFF0C6800,fcmpu,cr6,f12,f13 # misc instructions -0xFFF00100,0x7D453D2A,stswx,r10,r5,r7 +0xFFF00100,0x7D290034,cntlzw,r9,r9 +0xFFF00100,0x7FFF0035,cntlzw.,r31,r31 +0xFFF00100,0x7C00D7AC,icbi,r0,r26 0xFFF00100,0x7D604828,lwarx,r11,0,r9 +0xFFF00100,0x7CBC04AA,lswi,r5,r28,0x20 +0xFFF00100,0x7FEF2C2A,lswx,r31,r15,r5 +0xFFF00100,0x7E000400,mcrxr,cr4 +0xFFF00100,0xFFE0004C,mtfsb1,31 +0xFFF00100,0xFFE0048F,mffs.,f31 +0xFFF00100,0x7FEF01A4,mtsr,15,r31 +0xFFF00100,0x7C6021E4,mtsrin,r3,r4 +0xFFF00100,0x7CA305AA,stswi,r5,r3,0x20 +0xFFF00100,0x7D453D2A,stswx,r10,r5,r7 +0xFFF00100,0x7C0002E4,tlbia +0xFFF00100,0x7C004A64,tlbie,r9 # various simplified (extended) mnemonics 0xFFF00100,0x60000000,nop @@ -289,4 +332,7 @@ 0xFFF00100,0x7C642D90,dc.l,0x7C642D90 # POWER/PPC601 specific instructions -#0xFFF00100,0x7E3EE43A,maskir,r30,r17,r28 +0xFFF00100,0x7C440426,clcs,r2,r4 +0xFFF00100,0x24000800,dozi,r0,r0,0x800 +0xFFF00100,0x7C00003A,maskg,r0,r0,r0 +0xFFF00100,0x7E3EE43A,maskir,r30,r17,r28 \ No newline at end of file