From: Carl Love Date: Thu, 4 Apr 2019 17:31:05 +0000 (-0500) Subject: PPC64, patch to test case issues reported in bugzilla 401827 and 401828. X-Git-Tag: VALGRIND_3_15_0~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82e94fff802aece376d5ca8458ef49d24afd7bdf;p=thirdparty%2Fvalgrind.git PPC64, patch to test case issues reported in bugzilla 401827 and 401828. This corrects a valgrind instruction emulation issue revealed by a GCC change. The xscvdpsp,xscvdpspn,xscvdpuxws instructions each convert double precision values to single precision values, and write the results into bits 0-32 of the 128 bit target register. To get the value into the normal position for a scalar register the result needed to be right-shifted 32 bits, so gcc always did that. It was determined that hardware also always did that, so the (redundant) gcc shift was removed. This exposed an issue because valgrind was only writing the result to bits 0-31 of the target register. This patch updates the emulation to write the result to both of the involved 32-bit fields. VEX/priv/guest_ppc_toIR.c: - rearrange ops in dis_vx_conv to update more portions of the target register with copies of the result. xscvdpsp,xscvdpspn,xscvdpuxws none/tests/ppc64/test_isa_2_06_part1.c - update res32 checking to explicitly include fcfids and fcfidus in the 32-bit result grouping. none/tests/ppc64/test_isa_2_07_part2.c - correct NULL initializer for logic_tests definition [*1] - GCC change referenced: 2017-09-26 Michael Meissner * config/rs6000/rs6000.md (movsi_from_sf): Adjust code to eliminate doing a 32-bit shift right or vector extract after doing XSCVDPSPN. patch submitted by: Will Schmidt reviewed, committed by: Carl Love --- diff --git a/NEWS b/NEWS index d215c367c6..8e5ea704ac 100644 --- a/NEWS +++ b/NEWS @@ -98,6 +98,9 @@ where XXXXXX is the bug number as listed below. 401578 drd: crashes sometimes on fork() 401627 memcheck errors with glibc avx2 optimized wcsncmp 401822 none/tests/ppc64/jm-vmx fails and produces assembler warnings +401827 none/tests/ppc64/test_isa_2_06_part3 failure on ppc64le (xvrsqrtesp) +401828 none/tests/ppc64/test_isa_2_06_part1 failure on ppc64le (fcfids and + fcfidus) 402006 mark helper regs defined in final_tidyup before freeres_wrapper call 402048 WARNING: unhandled ppc64[be|le]-linux syscall: 26 (ptrace) 402123 invalid assembler opcodes for mips32r2 diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index ec7c63a6fc..a8cadd23a4 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -16324,28 +16324,36 @@ dis_vx_conv ( UInt theInstr, UInt opc2 ) } case 0x212: // xscvdpsp (VSX Scalar round Double-Precision to single-precision and // Convert to Single-Precision format + // Apr 2019 update - write the result to both halves of the + // target VSR. (see bug 401827,401828). DIP("xscvdpsp v%u,v%u\n", XT, XB); + IRTemp ResultI32a = newTemp(Ity_I32); + assign(ResultI32a, unop( Iop_ReinterpF32asI32, + unop( Iop_TruncF64asF32, + binop( Iop_RoundF64toF32, + get_IR_roundingmode(), + mkexpr( xB ) ) ) ) ); putVSReg( XT, binop( Iop_64HLtoV128, binop( Iop_32HLto64, - unop( Iop_ReinterpF32asI32, - unop( Iop_TruncF64asF32, - binop( Iop_RoundF64toF32, - get_IR_roundingmode(), - mkexpr( xB ) ) ) ), - mkU32( 0 ) ), + mkexpr(ResultI32a ), + mkexpr(ResultI32a ) ), mkU64( 0ULL ) ) ); break; case 0x216: /* xscvdpspn (VSX Scalar convert scalar Single-Precision to vector Single-Precision non-signalling */ + // Apr 2019 update - write the result to both halves of the + // target VSR. (see bug 401827,401828). DIP("xscvdpspn v%u,v%u\n", XT, XB); + IRTemp ResultI32b = newTemp(Ity_I32); + assign(ResultI32b, unop( Iop_ReinterpF32asI32, + unop( Iop_TruncF64asF32, + mkexpr( xB ) ) ) ); putVSReg( XT, binop( Iop_64HLtoV128, binop( Iop_32HLto64, - unop( Iop_ReinterpF32asI32, - unop( Iop_TruncF64asF32, - mkexpr( xB ) ) ), - mkU32( 0 ) ), + mkexpr(ResultI32b ), + mkexpr(ResultI32b ) ), mkU64( 0ULL ) ) ); break; case 0x090: // xscvdpuxws (VSX Scalar truncate Double-Precision to integer diff --git a/none/tests/ppc32/test_isa_2_06_part1.c b/none/tests/ppc32/test_isa_2_06_part1.c index 7a14c6df31..e84fafaa05 100644 --- a/none/tests/ppc32/test_isa_2_06_part1.c +++ b/none/tests/ppc32/test_isa_2_06_part1.c @@ -1873,7 +1873,12 @@ static void test_p7_fpops ( void ) double resd; unsigned long long u0; int i; - int res32 = strcmp(fp_tests[k].name, "fcfidu"); + // fcfids - 64-bit fp converted to inf precise fp integer, rounded to SP. (32) + // fcfidus - 64-bit fp converted to inf precise fp integer, rounded to SP. (32) + // fcfidu - 64-bit fp converted to inf precise fp integer, rounded to DP. (64) + int res32 = ( + (strcmp(fp_tests[k].name, "fcfids")==0) || + (strcmp(fp_tests[k].name, "fcfidus")==0) ); for (i = 0; i < nb_fargs; i++) { u0 = *(unsigned long long *) (&fargs[i]); diff --git a/none/tests/ppc64/test_isa_2_07_part2.c b/none/tests/ppc64/test_isa_2_07_part2.c index a2458a9b0c..5ac1d574ef 100644 --- a/none/tests/ppc64/test_isa_2_07_part2.c +++ b/none/tests/ppc64/test_isa_2_07_part2.c @@ -781,7 +781,7 @@ logic_tests[] = { { &test_xxleqv, "xxleqv", VSX_EQV }, { &test_xxlorc, "xxlorc", VSX_ORC }, { &test_xxlnand, "xxlnand", VSX_NAND }, - { NULL, NULL} + { NULL, NULL, 0} }; Bool check_reciprocal_estimate(Bool is_rsqrte, int idx, int output_vec_idx)