summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Love <carll@us.ibm.com>2017-10-05 12:19:59 -0500
committerCarl Love <carll@us.ibm.com>2017-10-05 12:19:59 -0500
commit856d45eb7e3661a61ace32be2cfa10bf198620c8 (patch)
tree7657688d3abef3a92282d8cea9468086b048cfc7
parentPPC64, revert the change to vperm instruction. (diff)
downloadvalgrind-856d45eb7e3661a61ace32be2cfa10bf198620c8.tar.gz
valgrind-856d45eb7e3661a61ace32be2cfa10bf198620c8.tar.bz2
valgrind-856d45eb7e3661a61ace32be2cfa10bf198620c8.tar.xz
PPC64, vpermr, xxperm, xxpermr fix Iop_Perm8x16 selector field
The implementation of the vpermr, xxperm, xxpermr violate this by using a mask of 0x1F. Fix the code and the corresponding comments to met the definition for Iop_Perm8x16. Use Iop_Dup8x16 to generate vector value for subtraction. Bugzilla 385334.
-rw-r--r--NEWS1
-rw-r--r--VEX/priv/guest_ppc_toIR.c38
2 files changed, 20 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index efa1f4a..097930a 100644
--- a/NEWS
+++ b/NEWS
@@ -63,6 +63,7 @@ n-i-bz Fix missing workq_ops operations (macOS)
63385208 PPC64, xxperm instruction exhausts temporary memory 63385208 PPC64, xxperm instruction exhausts temporary memory
64385210 PPC64, vpermr instruction could exhaust temporary memory 64385210 PPC64, vpermr instruction could exhaust temporary memory
65385183 PPC64, Add support for xscmpeqdp, xscmpgtdp, xscmpgedp, xsmincdp instructions 65385183 PPC64, Add support for xscmpeqdp, xscmpgtdp, xscmpgedp, xsmincdp instructions
66385334 PPC64, fix vpermr, xxperm, xxpermr mask value.
66 67
67Release 3.13.0 (15 June 2017) 68Release 3.13.0 (15 June 2017)
68~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
index b5b0d03..f63146e 100644
--- a/VEX/priv/guest_ppc_toIR.c
+++ b/VEX/priv/guest_ppc_toIR.c
@@ -22579,6 +22579,7 @@ dis_vx_permute_misc( UInt theInstr, UInt opc2 )
22579 IRTemp b_perm = newTemp(Ity_V128); 22579 IRTemp b_perm = newTemp(Ity_V128);
22580 IRTemp mask = newTemp(Ity_V128); 22580 IRTemp mask = newTemp(Ity_V128);
22581 IRTemp perm_val = newTemp(Ity_V128); 22581 IRTemp perm_val = newTemp(Ity_V128);
22582 IRTemp vB_adj = newTemp( Ity_V128 );
22582 22583
22583 if ( opc2 == 0x68 ) { 22584 if ( opc2 == 0x68 ) {
22584 DIP("xxperm v%d,v%d,v%d\n", (UInt)XT, (UInt)XA, (UInt)XB); 22585 DIP("xxperm v%d,v%d,v%d\n", (UInt)XT, (UInt)XA, (UInt)XB);
@@ -22591,29 +22592,27 @@ dis_vx_permute_misc( UInt theInstr, UInt opc2 )
22591 assign( vT, getVSReg( XT ) ); 22592 assign( vT, getVSReg( XT ) );
22592 22593
22593 if ( opc2 == 0x68 ) // xxperm 22594 if ( opc2 == 0x68 ) // xxperm
22594 assign( perm_val, 22595 assign( vB_adj, mkexpr( vB ) );
22595 binop( Iop_AndV128, mkexpr( vB ),
22596 unop( Iop_Dup8x16, mkU8( 0x1F ) ) ) );
22597 22596
22598 else // xxpermr 22597 else // xxpermr
22599 assign( perm_val, 22598 assign( vB_adj,
22600 binop( Iop_Sub16x8, 22599 binop( Iop_Sub16x8,
22601 binop( Iop_64HLtoV128, 22600 unop( Iop_Dup8x16, mkU8( 0x1F ) ),
22602 mkU64( 0x1F1F1F1F1F1F1F1F ), 22601 mkexpr( vB ) ) );
22603 mkU64( 0x1F1F1F1F1F1F1F1F ) ),
22604 binop( Iop_AndV128, mkexpr( vB ),
22605 unop( Iop_Dup8x16, mkU8( 0x1F ) ) ) ) );
22606 22602
22607 /* Limit the Perm8x16 steering values to 0 .. 31 as that is what 22603 /* Limit the Perm8x16 steering values to 0 .. 15 as that is what
22608 IR specifies, and also to hide irrelevant bits from 22604 IR specifies, and also to hide irrelevant bits from
22609 memcheck. 22605 memcheck.
22610 */ 22606 */
22607 assign( perm_val,
22608 binop( Iop_AndV128, mkexpr( vB_adj ),
22609 unop( Iop_Dup8x16, mkU8( 0xF ) ) ) );
22611 assign( a_perm, 22610 assign( a_perm,
22612 binop( Iop_Perm8x16, mkexpr( vA ), mkexpr( perm_val ) ) ); 22611 binop( Iop_Perm8x16, mkexpr( vA ), mkexpr( perm_val ) ) );
22613 assign( b_perm, 22612 assign( b_perm,
22614 binop( Iop_Perm8x16, mkexpr( vT ), mkexpr( perm_val ) ) ); 22613 binop( Iop_Perm8x16, mkexpr( vT ), mkexpr( perm_val ) ) );
22615 assign( mask, binop( Iop_SarN8x16, 22614 assign( mask, binop( Iop_SarN8x16,
22616 binop( Iop_ShlN8x16, mkexpr( perm_val ), 22615 binop( Iop_ShlN8x16, mkexpr( vB_adj ),
22617 mkU8( 3 ) ), 22616 mkU8( 3 ) ),
22618 mkU8( 7 ) ) ); 22617 mkU8( 7 ) ) );
22619 // dst = (a & ~mask) | (b & mask) 22618 // dst = (a & ~mask) | (b & mask)
@@ -24361,28 +24360,29 @@ static Bool dis_av_permute ( UInt theInstr )
24361 IRTemp b_perm = newTemp( Ity_V128 ); 24360 IRTemp b_perm = newTemp( Ity_V128 );
24362 IRTemp mask = newTemp( Ity_V128 ); 24361 IRTemp mask = newTemp( Ity_V128 );
24363 IRTemp vC_andF = newTemp( Ity_V128 ); 24362 IRTemp vC_andF = newTemp( Ity_V128 );
24363 IRTemp vC_adj = newTemp( Ity_V128 );
24364 24364
24365 DIP( "vpermr v%d,v%d,v%d,v%d\n", 24365 DIP( "vpermr v%d,v%d,v%d,v%d\n",
24366 vD_addr, vA_addr, vB_addr, vC_addr); 24366 vD_addr, vA_addr, vB_addr, vC_addr);
24367 /* Limit the Perm8x16 steering values to 0 .. 31 as that is what 24367 /* Limit the Perm8x16 steering values to 0 .. 15 as that is what
24368 IR specifies, and also to hide irrelevant bits from 24368 IR specifies, and also to hide irrelevant bits from
24369 memcheck. 24369 memcheck.
24370 */ 24370 */
24371 24371
24372 assign( vC_adj,
24373 binop( Iop_Sub16x8,
24374 unop( Iop_Dup8x16, mkU8( 0x1F ) ),
24375 mkexpr( vC ) ) );
24372 assign( vC_andF, 24376 assign( vC_andF,
24373 binop( Iop_Sub16x8, 24377 binop( Iop_AndV128, mkexpr( vC_adj),
24374 binop( Iop_64HLtoV128, 24378 unop( Iop_Dup8x16, mkU8( 0xF ) ) ) );
24375 mkU64( 0x1F1F1F1F1F1F1F1F ),
24376 mkU64( 0x1F1F1F1F1F1F1F1F ) ),
24377 binop( Iop_AndV128, mkexpr( vC ),
24378 unop( Iop_Dup8x16, mkU8( 0x1F ) ) ) ) );
24379 assign( a_perm, 24379 assign( a_perm,
24380 binop( Iop_Perm8x16, mkexpr( vA ), mkexpr( vC_andF ) ) ); 24380 binop( Iop_Perm8x16, mkexpr( vA ), mkexpr( vC_andF ) ) );
24381 assign( b_perm, 24381 assign( b_perm,
24382 binop( Iop_Perm8x16, mkexpr( vB ), mkexpr( vC_andF ) ) ); 24382 binop( Iop_Perm8x16, mkexpr( vB ), mkexpr( vC_andF ) ) );
24383 // mask[i8] = (vC[i8]_4 == 1) ? 0xFF : 0x0 24383 // mask[i8] = (vC[i8]_4 == 1) ? 0xFF : 0x0
24384 assign( mask, binop(Iop_SarN8x16, 24384 assign( mask, binop(Iop_SarN8x16,
24385 binop( Iop_ShlN8x16, mkexpr( vC_andF ), 24385 binop( Iop_ShlN8x16, mkexpr( vC_adj ),
24386 mkU8( 3 ) ), mkU8( 7 ) ) ); 24386 mkU8( 3 ) ), mkU8( 7 ) ) );
24387 // dst = (a & ~mask) | (b & mask) 24387 // dst = (a & ~mask) | (b & mask)
24388 putVReg( vD_addr, binop( Iop_OrV128, 24388 putVReg( vD_addr, binop( Iop_OrV128,