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