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