]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 402519 - POWER 3.0 addex instruction incorrectly implemented
authorMark Wielaard <mark@klomp.org>
Mon, 31 Dec 2018 21:26:31 +0000 (22:26 +0100)
committerMark Wielaard <mark@klomp.org>
Mon, 31 Dec 2018 21:26:31 +0000 (22:26 +0100)
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
VEX/priv/guest_ppc_toIR.c
none/tests/ppc64/test_isa_3_0.c
none/tests/ppc64/test_isa_3_0_other.stdout.exp-LE

diff --git a/NEWS b/NEWS
index bfb784869e1a04c587522ee3f12668dd4066a760..2d1f2e99b9cbbab8d367bf5d072e21a13f369755 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -84,6 +84,7 @@ where XXXXXX is the bug number as listed below.
 402480  Do not use %rsp in clobber list
 402481  vbit-test fails on x86 for Iop_CmpEQ64 iselInt64Expr Sar64
 402515  Implement new option --show-error-list=no|yes / -s
+402519  POWER 3.0 addex instruction incorrectly implemented
 
 Release 3.14.0 (9 October 2018)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 18df822fdb742201a70c939dc2b0580629a3b98b..d685383be13f9cdad6e0c5f51a92333513159f31 100644 (file)
@@ -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);
index 2d13505767f97f5b99a79f799c280b824218f588..1c2cda361d04584314b4ea4c5174b05ded591ca4 100644 (file)
@@ -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
index 152ff284b133514f374553a2bc37b0da85a60b8f..cc0e88e9a3044a9463ae786e6d679b9445f89c1f 100644 (file)
@@ -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