]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
PPC64, fix implementation of xvcvsxdsp and xvcvuxddp instructions.
authorCarl Love <carll@us.ibm.com>
Fri, 22 Mar 2019 16:56:38 +0000 (11:56 -0500)
committerCarl Love <carll@us.ibm.com>
Fri, 22 Mar 2019 16:56:38 +0000 (11:56 -0500)
Instructions need to write result to upper and lower 32-bit half of the
64-bit result.

This is a fix for Valgrind bug 405356.

NEWS
VEX/priv/guest_ppc_toIR.c

diff --git a/NEWS b/NEWS
index a460d8eae5df59ce1c163e4da905ff27d919992b..a2c055ed3129494e393b6a30201c7d2eae255a13 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -113,6 +113,8 @@ where XXXXXX is the bug number as listed below.
 405403  s390x disassembler cannot be used on x86
 405458  MIPS mkFormVEC arguments swapped?
 405716  drd: Fix an integer overflow in the stack margin calculation
+405356  PPC64, xvcvsxdsp, xvcvuxdsp are supposed to write the 32-bit result to
+        the upper and lower 32-bits of the 64-bit result
 
 n-i-bz  add syswrap for PTRACE_GET|SET_THREAD_AREA on amd64.
 n-i-bz  Fix callgrind_annotate non deterministic order for equal total
index 00ae6df2d6010a18ca068b87ea0e8c57aa0098b9..d6c671ababe8f53480868a32f68f86bf79cb6b74 100644 (file)
@@ -16312,52 +16312,71 @@ dis_vx_conv ( UInt theInstr, UInt opc2 )
          break;
       case 0x370: // xvcvsxdsp (VSX Vector Convert and round Signed Integer Doubleword
                   //            to Single-Precision format)
-         DIP("xvcvsxddp v%u,v%u\n",  XT, XB);
+      {
+         IRTemp result32hi = newTemp(Ity_I32);
+         IRTemp result32lo = newTemp(Ity_I32);
+
+         DIP("xvcvsxdsp v%u,v%u\n",  XT, XB);
+         assign( result32hi,
+                 unop( Iop_ReinterpF32asI32,
+                       unop( Iop_TruncF64asF32,
+                             binop( Iop_RoundF64toF32,
+                                    get_IR_roundingmode(),
+                                    binop( Iop_I64StoF64,
+                                           get_IR_roundingmode(),
+                                           mkexpr( xB ) ) ) ) ) );
+         assign( result32lo,
+                 unop( Iop_ReinterpF32asI32,
+                       unop( Iop_TruncF64asF32,
+                             binop( Iop_RoundF64toF32,
+                                    get_IR_roundingmode(),
+                                    binop( Iop_I64StoF64,
+                                           get_IR_roundingmode(),
+                                           mkexpr( xB2 ) ) ) ) ) );
+
          putVSReg( XT,
                    binop( Iop_64HLtoV128,
                           binop( Iop_32HLto64,
-                                 unop( Iop_ReinterpF32asI32,
-                                       unop( Iop_TruncF64asF32,
-                                             binop( Iop_RoundF64toF32,
-                                                    get_IR_roundingmode(),
-                                                    binop( Iop_I64StoF64,
-                                                           get_IR_roundingmode(),
-                                                           mkexpr( xB ) ) ) ) ),
-                                 mkU32( 0 ) ),
+                                 mkexpr( result32hi ),
+                                 mkexpr( result32hi ) ),
                           binop( Iop_32HLto64,
-                                 unop( Iop_ReinterpF32asI32,
-                                       unop( Iop_TruncF64asF32,
-                                             binop( Iop_RoundF64toF32,
-                                                    get_IR_roundingmode(),
-                                                    binop( Iop_I64StoF64,
-                                                           get_IR_roundingmode(),
-                                                           mkexpr( xB2 ) ) ) ) ),
-                                 mkU32( 0 ) ) ) );
-         break;
+                                 mkexpr( result32lo ),
+                                 mkexpr( result32lo ) ) ) );
+      }
+      break;
       case 0x350: // xvcvuxdsp (VSX Vector Convert and round Unsigned Integer Doubleword
                   //            to Single-Precision format)
-         DIP("xvcvuxddp v%u,v%u\n", XT, XB);
+      {
+         IRTemp result32hi = newTemp(Ity_I32);
+         IRTemp result32lo = newTemp(Ity_I32);
+
+         DIP("xvcvuxdsp v%u,v%u\n", XT, XB);
+         assign( result32hi,
+                 unop( Iop_ReinterpF32asI32,
+                       unop( Iop_TruncF64asF32,
+                             binop( Iop_RoundF64toF32,
+                                    get_IR_roundingmode(),
+                                    binop( Iop_I64UtoF64,
+                                           get_IR_roundingmode(),
+                                           mkexpr( xB ) ) ) ) ) );
+         assign( result32lo,
+                 unop( Iop_ReinterpF32asI32,
+                       unop( Iop_TruncF64asF32,
+                             binop( Iop_RoundF64toF32,
+                                    get_IR_roundingmode(),
+                                    binop( Iop_I64UtoF64,
+                                           get_IR_roundingmode(),
+                                           mkexpr( xB2 ) ) ) ) ) );
          putVSReg( XT,
                    binop( Iop_64HLtoV128,
                           binop( Iop_32HLto64,
-                                 unop( Iop_ReinterpF32asI32,
-                                       unop( Iop_TruncF64asF32,
-                                             binop( Iop_RoundF64toF32,
-                                                    get_IR_roundingmode(),
-                                                    binop( Iop_I64UtoF64,
-                                                           get_IR_roundingmode(),
-                                                           mkexpr( xB ) ) ) ) ),
-                                 mkU32( 0 ) ),
+                                 mkexpr( result32hi ),
+                                 mkexpr( result32hi ) ),
                           binop( Iop_32HLto64,
-                                 unop( Iop_ReinterpF32asI32,
-                                       unop( Iop_TruncF64asF32,
-                                             binop( Iop_RoundF64toF32,
-                                                    get_IR_roundingmode(),
-                                                    binop( Iop_I64UtoF64,
-                                                           get_IR_roundingmode(),
-                                                           mkexpr( xB2 ) ) ) ) ),
-                                 mkU32( 0 ) ) ) );
-         break;
+                                 mkexpr( result32lo ),
+                                 mkexpr( result32lo ) ) ) );
+      }
+      break;
 
       case 0x1f0: // xvcvsxwdp (VSX Vector Convert Signed Integer Word to Double-Precision format)
          DIP("xvcvsxwdp v%u,v%u\n",  XT, XB);