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