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 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest-ppc/toIR.c b/priv/guest-ppc/toIR.c
index 47355c6..0014ffb 100644
--- a/priv/guest-ppc/toIR.c
+++ b/priv/guest-ppc/toIR.c
@@ -5710,7 +5710,9 @@
}
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 @@
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 @@
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 @@
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 @@
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