From: Julian Seward Date: Sun, 29 Jan 2006 17:07:57 +0000 (+0000) Subject: Handle fre and frsqrtes. Even though the IBM docs manage to X-Git-Tag: svn/VALGRIND_3_2_3^2~102 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57168c1310028cd64dca1d517332fa766583581b;p=thirdparty%2Fvalgrind.git Handle fre and frsqrtes. Even though the IBM docs manage to contradict themselves about whether these insns exist or not. git-svn-id: svn://svn.valgrind.org/vex/trunk@1559 --- diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c index 47355c6150..0014ffbb01 100644 --- a/VEX/priv/guest-ppc/toIR.c +++ b/VEX/priv/guest-ppc/toIR.c @@ -5710,7 +5710,9 @@ static Bool dis_fp_arith ( UInt theInstr ) } DIP("fsqrts%s fr%u,fr%u\n", flag_rC ? ".":"", frD_addr, frB_addr); - assign( frD, roundToSgl( unop(Iop_SqrtF64, mkexpr(frB)) )); + // however illogically, on ppc970 this insn behaves identically + // to fsqrt (double-precision). So don't do round-to-single. + assign( frD, unop(Iop_SqrtF64, mkexpr(frB)) ); break; case 0x18: // fres (Floating Reciprocal Estimate Single, PPC32 p421) @@ -5735,6 +5737,18 @@ static Bool dis_fp_arith ( UInt theInstr ) mkexpr(frA), mkexpr(frC)) )); break; + case 0x1A: // frsqrtes (Floating Recip SqRt Est Single) + // NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX) + // Undocumented instruction? + if (frA_addr != 0 || frC_addr != 0) { + vex_printf("dis_fp_arith(ppc)(instr,frsqrte)\n"); + return False; + } + DIP("frsqrtes%s fr%u,fr%u\n", flag_rC ? ".":"", + frD_addr, frB_addr); + assign( frD, unop(Iop_Est5FRSqrt, mkexpr(frB)) ); + break; + default: vex_printf("dis_fp_arith(ppc)(3B: opc2)\n"); return False; @@ -5809,6 +5823,19 @@ static Bool dis_fp_arith ( UInt theInstr ) break; } + case 0x18: // fre (Floating Reciprocal Estimate) + // NOTE: POWERPC OPTIONAL, "Graphics Group" (PPC32_GX) + // Note: unclear whether this insn really exists or not + // ppc970 doesn't have it, but POWER5 does + if (frA_addr != 0 || frC_addr != 0) { + vex_printf("dis_fp_arith(ppc)(instr,fres)\n"); + return False; + } + DIP("fre%s fr%u,fr%u\n", flag_rC ? ".":"", + frD_addr, frB_addr); + assign( frD, unop(Iop_Est8FRecip, mkexpr(frB)) ); + break; + case 0x19: // fmul (Floating Mult (Double Precision), PPC32 p413) if (frB_addr != 0) { vex_printf("dis_fp_arith(ppc)(instr,fmul)\n"); @@ -8645,6 +8672,11 @@ DisResult disInstr_PPC_WRK ( case 0x1F: // fnmadds if (dis_fp_multadd(theInstr)) goto decode_success; goto decode_failure; + + case 0x1A: // frsqrtes + if (!allow_GX) goto decode_noGX; + if (dis_fp_arith(theInstr)) goto decode_success; + goto decode_failure; default: goto decode_failure; @@ -8683,6 +8715,11 @@ DisResult disInstr_PPC_WRK ( case 0x1F: // fnmadd if (dis_fp_multadd(theInstr)) goto decode_success; goto decode_failure; + + case 0x18: // fre + if (!allow_GX) goto decode_noGX; + if (dis_fp_arith(theInstr)) goto decode_success; + goto decode_failure; default: break; // Fall through