From 35f3014237dc198356438b167725c6bec8b5bcaf Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 31 Dec 2018 22:26:31 +0100 Subject: [PATCH] Bug 402519 - POWER 3.0 addex instruction incorrectly implemented References: bsc#1121025 Patch-mainline: 3.15 Git-commit: 2c1f016e634bf79faf45e81c14c955c711bc202f addex uses OV as carry in and carry out. For all other instructions OV is the signed overflow flag. And instructions like adde use CA as carry. Replace set_XER_OV_OV32 with set_XER_OV_OV32_ADDEX, which will call calculate_XER_CA_64 and calculate_XER_CA_32, but with OV as input, and sets OV and OV32. Enable test_addex in none/tests/ppc64/test_isa_3_0.c and update the expected output. test_addex would fail to match the expected output before this patch. Acked-by: Michal Suchanek --- NEWS | 1 + VEX/priv/guest_ppc_toIR.c | 52 ++++++++++++------- none/tests/ppc64/test_isa_3_0.c | 3 +- .../ppc64/test_isa_3_0_other.stdout.exp-LE | 36 ++++++++----- 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/NEWS b/NEWS index 91e572e8d031..49df52158fa9 100644 --- a/NEWS +++ b/NEWS @@ -174,6 +174,7 @@ where XXXXXX is the bug number as listed below. 397424 glibc 2.27 and gdb_server tests 398028 Assertion `cfsi_fits` failing in simple C program 398066 s390x: cgijl dep1, 0 reports false unitialised values warning +402519 POWER 3.0 addex instruction incorrectly implemented n-i-bz Fix missing workq_ops operations (macOS) n-i-bz fix bug in strspn replacement diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index cb1cae176af3..b6f4a6cde30f 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -2622,21 +2622,6 @@ static void copy_OV_to_OV32( void ) { putXER_OV32( getXER_OV() ); } -static void set_XER_OV_OV32 ( IRType ty, UInt op, IRExpr* res, - IRExpr* argL, IRExpr* argR ) -{ - if (ty == Ity_I32) { - set_XER_OV_OV32_32( op, res, argL, argR ); - } else { - IRExpr* xer_ov_32; - set_XER_OV_64( op, res, argL, argR ); - xer_ov_32 = calculate_XER_OV_32( op, unop(Iop_64to32, res), - unop(Iop_64to32, argL), - unop(Iop_64to32, argR)); - putXER_OV32( unop(Iop_32to8, xer_ov_32) ); - } -} - static void set_XER_OV_OV32_SO ( IRType ty, UInt op, IRExpr* res, IRExpr* argL, IRExpr* argR ) { @@ -2982,6 +2967,33 @@ static void set_XER_CA_CA32 ( IRType ty, UInt op, IRExpr* res, } } +/* Used only by addex instruction, which uses and sets OV as carry. */ +static void set_XER_OV_OV32_ADDEX ( IRType ty, IRExpr* res, + IRExpr* argL, IRExpr* argR, + IRExpr* old_ov ) +{ + if (ty == Ity_I32) { + IRTemp xer_ov = newTemp(Ity_I32); + assign ( xer_ov, unop(Iop_32to8, + calculate_XER_CA_32( PPCG_FLAG_OP_ADDE, + res, argL, argR, old_ov ) ) ); + putXER_OV( mkexpr (xer_ov) ); + putXER_OV32( mkexpr (xer_ov) ); + } else { + IRExpr *xer_ov; + IRExpr* xer_ov_32; + xer_ov = calculate_XER_CA_64( PPCG_FLAG_OP_ADDE, + res, argL, argR, old_ov ); + putXER_OV( unop(Iop_32to8, xer_ov) ); + xer_ov_32 = calculate_XER_CA_32( PPCG_FLAG_OP_ADDE, + unop(Iop_64to32, res), + unop(Iop_64to32, argL), + unop(Iop_64to32, argR), + unop(Iop_64to32, old_ov) ); + putXER_OV32( unop(Iop_32to8, xer_ov_32) ); + } +} + /*------------------------------------------------------------*/ @@ -5071,16 +5083,18 @@ static Bool dis_int_arith ( UInt theInstr ) } case 0xAA: {// addex (Add Extended alternate carry bit Z23-form) + IRTemp old_xer_ov = newTemp(ty); DIP("addex r%u,r%u,r%u,%d\n", rD_addr, rA_addr, rB_addr, (Int)flag_OE); + assign( old_xer_ov, mkWidenFrom32(ty, getXER_OV_32(), False) ); assign( rD, binop( mkSzOp(ty, Iop_Add8), mkexpr(rA), binop( mkSzOp(ty, Iop_Add8), mkexpr(rB), - mkWidenFrom8( ty, getXER_OV(), False ) ) ) ); + mkexpr(old_xer_ov) ) ) ); /* CY bit is same as OE bit */ if (flag_OE == 0) { - /* Exception, do not set SO bit */ - set_XER_OV_OV32( ty, PPCG_FLAG_OP_ADDE, - mkexpr(rD), mkexpr(rA), mkexpr(rB) ); + /* Exception, do not set SO bit and set OV from carry. */ + set_XER_OV_OV32_ADDEX( ty, mkexpr(rD), mkexpr(rA), mkexpr(rB), + mkexpr(old_xer_ov) ); } else { /* CY=1, 2 and 3 (AKA flag_OE) are reserved */ vex_printf("addex instruction, CY = %d is reserved.\n", flag_OE); diff --git a/none/tests/ppc64/test_isa_3_0.c b/none/tests/ppc64/test_isa_3_0.c index 2d13505767f9..1c2cda361d04 100644 --- a/none/tests/ppc64/test_isa_3_0.c +++ b/none/tests/ppc64/test_isa_3_0.c @@ -286,7 +286,7 @@ static test_list_t testgroup_ia_ops_two[] = { { &test_moduw, "moduw" }, { &test_modsd, "modsd" }, { &test_modud, "modud" }, - //{ &test_addex, "addex" }, + { &test_addex, "addex" }, { NULL , NULL }, }; @@ -2741,7 +2741,6 @@ static void testfunction_gpr_vector_logical_one (const char* instruction_name, * rt, xa */ int i; - int t; volatile HWord_t res; VERBOSE_FUNCTION_CALLOUT diff --git a/none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE b/none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE index 152ff284b133..cc0e88e9a304 100644 --- a/none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE +++ b/none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE @@ -40,7 +40,17 @@ modud ffffffffffffffff, 0000000000000000 => 0000000000000000 (00000000) modud ffffffffffffffff, 0000001cbe991def => 000000043eb0c0b2 (00000000) modud ffffffffffffffff, ffffffffffffffff => 0000000000000000 (00000000) -All done. Tested 4 different instructions +addex 0000000000000000, 0000000000000000 => 0000000000000000 (00000000) +addex 0000000000000000, 0000001cbe991def => 0000001cbe991def (00000000) +addex 0000000000000000, ffffffffffffffff => ffffffffffffffff (00000000) +addex 0000001cbe991def, 0000000000000000 => 0000001cbe991def (00000000) +addex 0000001cbe991def, 0000001cbe991def => 000000397d323bde (00000000) OV32 +addex 0000001cbe991def, ffffffffffffffff => 0000001cbe991dee (00000000) OV OV32 +addex ffffffffffffffff, 0000000000000000 => 0000000000000000 (00000000) OV OV32 +addex ffffffffffffffff, 0000001cbe991def => 0000001cbe991def (00000000) OV OV32 +addex ffffffffffffffff, ffffffffffffffff => ffffffffffffffff (00000000) OV OV32 + +All done. Tested 5 different instructions ppc one argument plus shift: Test instruction group [ppc one argument plus shift] extswsli aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0 ffffffffffffffff => aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0 ffffffffffffffff @@ -85,7 +95,7 @@ extswsli. aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0 ffaa5599113377cc => aaaaaaaaaaaaaa extswsli. 5152535455565758 5152535455565758 0 ffaa5599113377cc => 5152535455565758 5152535455565758 0 ffaa5599113377cc extswsli. 0000000000000000 0000000000000000 0 ffaa5599113377cc => 0000000000000000 0000000000000000 0 ffaa5599113377cc -All done. Tested 6 different instructions +All done. Tested 7 different instructions ppc three parameter ops: Test instruction group [ppc three parameter ops] maddhd 0000000000000000, 0000000000000000, 0000000000000000 => 0000000000000000 (00000000) @@ -172,7 +182,7 @@ maddld ffffffffffffffff, ffffffffffffffff, 0000000000000000 => 000000000000000 maddld ffffffffffffffff, ffffffffffffffff, 0000001cbe991def => 0000001cbe991df0 (00000000) maddld ffffffffffffffff, ffffffffffffffff, ffffffffffffffff => 0000000000000000 (00000000) -All done. Tested 9 different instructions +All done. Tested 10 different instructions ppc count zeros: Test instruction group [ppc count zeros] cnttzw 0000000000000000 => 0000000000000020 @@ -197,7 +207,7 @@ cnttzd. 0000001cbe991def => 0000000000000000 Expected cr0 to be zero, it is (200 cnttzd. ffffffffffffffff => 0000000000000000 Expected cr0 to be zero, it is (20000000) -All done. Tested 13 different instructions +All done. Tested 14 different instructions ppc set boolean: Test instruction group [ppc set boolean] setb cr_field:0 cr_value::00000000 => 0000000000000000 @@ -265,7 +275,7 @@ setb cr_field:7 cr_value::00000005 => 0000000000000001 setb cr_field:7 cr_value::00000006 => 0000000000000001 setb cr_field:7 cr_value::00000007 => 0000000000000001 -All done. Tested 14 different instructions +All done. Tested 15 different instructions ppc char compare: Test instruction group [ppc char compare] cmprb l=0 0x61 (a) (cmpeq:0x5b427b625a417a61) (cmprb:src22(a-z) src21(A-Z)) => in range/found @@ -1711,7 +1721,7 @@ cmpeqb 0x5d (]) (cmpeq:0x4642666245416561) (cmprb:src22(a-e) src21(A-E)) => cmpeqb 0x60 (`) (cmpeq:0x4642666245416561) (cmprb:src22(a-e) src21(A-E)) => cmpeqb 0x5f (_) (cmpeq:0x4642666245416561) (cmprb:src22(a-e) src21(A-E)) => -All done. Tested 17 different instructions +All done. Tested 18 different instructions ppc vector scalar move to/from: Test instruction group [ppc vector scalar move to/from] mfvsrld aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0 ffffffffffffffff => aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa ffffffffffffffff @@ -1777,7 +1787,7 @@ mtvsrws aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa 0 ffaa5599113377cc => 113377cc113377cc mtvsrws 5152535455565758 5152535455565758 0 ffaa5599113377cc => 113377cc113377cc 113377cc113377cc 0 ffaa5599113377cc mtvsrws 0000000000000000 0000000000000000 0 ffaa5599113377cc => 113377cc113377cc 113377cc113377cc 0 ffaa5599113377cc -All done. Tested 20 different instructions +All done. Tested 21 different instructions ppc dfp significance: Test instruction group [ppc dfp significance] dtstsfi significance(0x00) +Finite 0 * 10 ^ -12 (GT) (4) @@ -1862,7 +1872,7 @@ dtstsfiq significance(0x20) -inf (GT) (4) dtstsfiq significance(0x30) -inf (GT) (4) dtstsfiq significance(0x3f) -inf (GT) (4) -All done. Tested 22 different instructions +All done. Tested 23 different instructions ppc bcd misc: Test instruction group [ppc bcd misc] bcdadd. p0 xa:0000000000000000 000000000000000c (+|0) xb:0000000000000000 000000000000000c (+|0) => (EQ) (2) xt:0000000000000000 000000000000000c(+|0) @@ -33338,12 +33348,12 @@ bcdcfsq. p1 xa:0000000000000000 000000000000000c (+|0) xb:9999999999999999 99999 bcdcfsq. p1 xa:0000000000000000 000000000000000c (+|0) xb:0000000000000000 000000001234567d ( - ) => (GT) (4) xt:0000000000000000 000000305419901f(+|0) -All done. Tested 51 different instructions +All done. Tested 52 different instructions ppc noop misc: Test instruction group [ppc noop misc] wait => -All done. Tested 52 different instructions +All done. Tested 53 different instructions ppc addpc_misc: Test instruction group [ppc addpc_misc] addpcis 0000000000000000 => 0000000000000000 @@ -33380,7 +33390,7 @@ subpcis 000000000000000d => 0000000000000000 subpcis 000000000000000e => 0000000000000000 subpcis 000000000000000f => 0000000000000000 -All done. Tested 54 different instructions +All done. Tested 55 different instructions ppc mffpscr: Test instruction group [ppc mffpscr] mffsce => 000000000.000000 @@ -33395,7 +33405,7 @@ mffs => 000000000.000000 fpscr: f14 local_fpscr: -All done. Tested 57 different instructions +All done. Tested 58 different instructions ppc mffpscr: Test instruction group [ppc mffpscr] mffscdrni 0 => 0X0 @@ -33426,4 +33436,4 @@ mffscrn f15 0X1 => 0X200000000 mffscrn f15 0X2 => 0X200000000 fpscr: f14 local_fpscr: 30-DRN1 RN-bit62 -All done. Tested 61 different instructions +All done. Tested 62 different instructions -- 2.19.2