From 2c1f016e634bf79faf45e81c14c955c711bc202f 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 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. --- NEWS | 1 + VEX/priv/guest_ppc_toIR.c | 52 ++++++++++++++--------- none/tests/ppc64/test_isa_3_0.c | 3 +- none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE | 36 ++++++++++------ 4 files changed, 58 insertions(+), 34 deletions(-) diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index 18df822..d685383 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -2645,21 +2645,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 ) { @@ -3005,6 +2990,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) ); + } +} + /*------------------------------------------------------------*/ @@ -5094,16 +5106,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 2d13505..1c2cda3 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 152ff28..cc0e88e 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 -- 1.8.3.1