]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Handle fre and frsqrtes. Even though the IBM docs manage to
authorJulian Seward <jseward@acm.org>
Sun, 29 Jan 2006 17:07:57 +0000 (17:07 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 29 Jan 2006 17:07:57 +0000 (17:07 +0000)
contradict themselves about whether these insns exist or not.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1559

VEX/priv/guest-ppc/toIR.c

index 47355c6150fc671fef277943373c6cd9575cccf8..0014ffbb01f7d9585eb16258fe60ac998edafbe8 100644 (file)
@@ -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