]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
PPC64: Fix load store instructions
authorCarl Love <cel@us.ibm.com>
Mon, 11 Jan 2021 17:39:23 +0000 (11:39 -0600)
committerCarl Love <cel@us.ibm.com>
Mon, 11 Jan 2021 21:28:34 +0000 (15:28 -0600)
This patch fixes numerous errors in the ISA support.

The word and prefix versions of the instructions do not use the same mask
to extract the immediate values.  The prefix instructions should all use
the DFOM_IMMASK.

The parsing of prefix instructions has been fixed to ensure the ISA 3.1
instructions all have the ISA_3_1_PREFIX_CHECK check.

Fixed the commenting to improve the comments for the instruction parsing.

Fixed the parsing of the plxv instruction.

General code cleanup.

VEX/priv/guest_ppc_toIR.c

index cd59687f5ba2e90cd5c99ae17e55da9083e382ef..0b7fe2387486ec88d0c182984a1a65219a119bdd 100644 (file)
@@ -8805,7 +8805,7 @@ static Bool dis_int_load_ds_form_prefix ( UInt prefix,
       pDIP( is_prefix, "ld r%u,%llu(r%u)", rT_addr, immediate_val, rA_addr);
       DIPn( is_prefix);
       assign( EA, calculate_prefix_EA( prefix, theInstr,
-                                       rA_addr, ptype, DSFORM_IMMASK,
+                                       rA_addr, ptype, DFORM_IMMASK,
                                        &immediate_val, &R ) );
 
       putIReg( rT_addr, load( Ity_I64, mkexpr( EA ) ) );
@@ -8815,15 +8815,14 @@ static Bool dis_int_load_ds_form_prefix ( UInt prefix,
       /* Word version DS Form - 64bit Loads.  In each case EA will have been
          formed with the lowest 2 bits masked off the immediate offset. */
       UInt uimm16 = ifieldUIMM16(theInstr);
-      Int  simm16 = extend_s_16to32(uimm16);
+      Int simm16 = extend_s_16to32(uimm16);
 
-      simm16 = simm16 & 0xFFFFFFFC;
+      simm16 = simm16 & DSFORM_IMMASK;
       assign( EA, ea_rAor0_simm( rA_addr, simm16  ) );
 
       switch ((b1<<1) | b0) {
       case 0x0: // ld (Load DWord, PPC64 p472)
-         pDIP( is_prefix, "ld r%u,%llu(r%u)", rT_addr, immediate_val, rA_addr);
-         DIPp( is_prefix, ",%u", R );
+         DIP("ld r%u,%llu(r%u)", rT_addr, immediate_val, rA_addr);
          putIReg( rT_addr, load( Ity_I64, mkexpr( EA ) ) );
          break;
 
@@ -8879,15 +8878,22 @@ static Bool dis_int_load_prefix ( UInt prefix, UInt theInstr )
                                        rA_addr, ptype, DFORM_IMMASK,
                                        &immediate_val, &R ) );
 
-   } else if (( opc1 == 0x28 ) || ( opc1 == 0x2A )) {
-      // half word loads lwz, plwz, lha, plha
+   } else if ( opc1 == 0x28 ) {
+      // half word loads lhz, plhz
+      size = Ity_I16;
+      assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                       rA_addr, ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+
+   } else if ( opc1 == 0x2A ) {
+      // half word loads lha, plha
       size = Ity_I16;
       assign( EA, calculate_prefix_EA( prefix, theInstr,
                                        rA_addr, ptype, DFORM_IMMASK,
                                        &immediate_val, &R ) );
 
    } else if (opc1 == 0x20 ) {
-      // word load
+      // word load lwz, plwz
       size = Ity_I32;
       assign( EA, calculate_prefix_EA( prefix, theInstr,
                                        rA_addr, ptype, DFORM_IMMASK,
@@ -8931,7 +8937,7 @@ static Bool dis_int_load_prefix ( UInt prefix, UInt theInstr )
       pDIP( is_prefix, "lhz r%u,%llu(r%u)", rT_addr, immediate_val, rA_addr );
       DIPp( is_prefix, ",%u", R );
 
-     putIReg( rT_addr, mkWidenFrom16( ty, val, False ) );
+      putIReg( rT_addr, mkWidenFrom16( ty, val, False ) );
       break;
 
    case 0x2A: // lha (Load HW Alg, PPC32 p445)
@@ -9607,7 +9613,7 @@ static Bool dis_int_store_ds_prefix ( UInt prefix,
       b0 = 0;
       b1 = 0;
       assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
-                                       ptype, DSFORM_IMMASK, &immediate_val,
+                                       ptype, DFORM_IMMASK, &immediate_val,
                                        &R ) );
 
    } else if ( opc1 == 0x3 ) {
@@ -9800,8 +9806,10 @@ static Bool dis_int_store ( UInt prefix, UInt theInstr, const VexAbiInfo* vbi )
       break;
 
    case 0x24: // stw (Store W, PPC32 p530)
+      {
       DIP("stw r%u,%d(r%u)\n", rS_addr, simm16, rA_addr);
       store( mkexpr(EA), mkNarrowTo32(ty, mkexpr(rS)) );
+      }
       break;
 
    case 0x25: // stwu (Store W, Update, PPC32 p534)
@@ -12754,6 +12762,7 @@ static Bool dis_fp_store ( UInt prefix, UInt theInstr )
       store( mkexpr(EA), unop(Iop_TruncF64asF32, mkexpr(frS)) );
       putIReg( rA_addr, mkexpr(EA) );
       break;
+
    case 0x37: // stfdu (Store Float Double, Update, PPC32 p514)
       if (rA_addr == 0)
          return False;
@@ -14040,35 +14049,125 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
    break;
 
    case 0x2A:   // plxsd
+   {
+      UChar vRT = ifieldRegDS(theInstr);
+      /* The prefixed word version uses the D-form.  */
+      assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
+                                       ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+
+      pDIP( is_prefix, "lxsd v%u,%llu(r%u)\n", vRT, immediate_val, rA_addr );
+      DIPp( is_prefix, ",%u", R );
+
+      putVSReg( vRT+32, binop( Iop_64HLtoV128,
+                               load( Ity_I64, mkexpr( EA ) ),
+                               mkU64( 0 ) ) );
+      return True;
+   }
+
    case 0x2B:   // plxssp
-   case 0x39:   // lxsd, lxssp
+   {
+      UChar vRT = ifieldRegDS(theInstr);
+      /* The prefixed word version uses the D-form.  */
+      assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
+                                       ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+
+
+      pDIP( is_prefix, "lxssp v%u,%llu(r%u)\n", vRT, immediate_val, rA_addr );
+      DIPp( is_prefix, ",%u", R );
+      putVSReg( vRT+32,
+                binop( Iop_64HLtoV128,
+                       unop( Iop_ReinterpF64asI64,
+                             unop( Iop_F32toF64,
+                                   unop( Iop_ReinterpI32asF32,
+                                         load( Ity_I32, mkexpr( EA ) )
+                                      ) ) ),
+                       mkU64( 0 ) ) );
+      return True;
+   }
+
+   case 0x32:   // plxv0
+   case 0x33:   // plxv1  These are both plxv, but bit 5 is used for TX
+   {
+      IRExpr* irx_addr;
+      IRTemp word[2];
+      UInt ea_off = 8;
+      UChar vRS  = ifieldRegDS(theInstr);
+      UInt  T  = IFIELD( theInstr, 21, 5);
+      UInt  TX = IFIELD( theInstr, 26, 1);
+
+      assign( EA,
+              calculate_prefix_EA( prefix, theInstr, rA_addr, ptype,
+                                   DFORM_IMMASK, &immediate_val, &R ) );
+
+      // plxv (Load VSX Vector)
+      pDIP( is_prefix, "lxv v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr );
+      DIPp( is_prefix, ",%u", R );
+
+      word[0] = newTemp(Ity_I64);
+      assign( word[0], load( Ity_I64, mkexpr( EA ) ) );
+
+      irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+                        ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+
+      word[1] = newTemp(Ity_I64);
+      assign( word[1], load( Ity_I64, irx_addr ) );
+
+      if (host_endness == VexEndnessBE)
+         putVSReg( TX*32+T, binop( Iop_64HLtoV128,
+                                   mkexpr( word[0] ),
+                                   mkexpr( word[1] ) ) );
+      else
+         putVSReg( TX*32+T, binop( Iop_64HLtoV128,
+                                   mkexpr( word[1] ),
+                                   mkexpr( word[0] ) ) );
+      return True;
+   }
+   break;
+
+   case 0x39:   // lxsd, plxsd, lxssp, plxssp
    {
       UChar vRT = ifieldRegDS(theInstr);
       opc2 = ifieldOPC0o2(theInstr);
-      if (opc1 == 0x2A)
+
+      if (opc1 == 0x2A) {  // plxsd
          opc2 = 0x2;  // map plxsd to lxsd inst
+         /* The prefixed word version uses the D-form.  */
+         assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
+                                          ptype, DFORM_IMMASK,
+                                          &immediate_val, &R ) );
 
-      if (opc1 == 0x2B)
+      } else if (opc1 == 0x2B) { // plxssp
          opc2 = 0x3;  // map plxssp to lxssp inst
-
-      /* The word version uses the DS-form.  */
-      assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
-                                       ptype, DSFORM_IMMASK,
-                                       &immediate_val, &R ) );
+         /* The prefixed word version uses the D-form.  */
+         assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
+                                          ptype, DFORM_IMMASK,
+                                          &immediate_val, &R ) );
+      } else {
+         /* The word version uses the DS-form.  */
+         assign( EA, calculate_prefix_EA( prefix, theInstr, rA_addr,
+                                          ptype, DSFORM_IMMASK,
+                                          &immediate_val, &R ) );
+      }
 
       switch(opc2) {
-      case 0x2:     // lxsd (Load VSX Scalar Doubleword)
-         pDIP( is_prefix, "lxsd v%u,%llu(r%u)\n", vRT, immediate_val, rA_addr );
+      case 0x2:     // lxsd, plxsd (Load VSX Scalar Doubleword)
+      {
+         pDIP( is_prefix, "lxsd v%u,%llu(r%u)\n", vRT, immediate_val,
+               rA_addr );
          DIPp( is_prefix, ",%u", R );
-
          putVSReg( vRT+32, binop( Iop_64HLtoV128,
                                   load( Ity_I64, mkexpr( EA ) ),
                                   mkU64( 0 ) ) );
          return True;
+      }
+      break;
 
       case 0x3:     // lxssp (Load VSX Scalar Single from memory,
                     // store as double in register)
-         pDIP( is_prefix, "lxssp v%u,%llu(r%u)\n", vRT, immediate_val, rA_addr );
+         pDIP( is_prefix, "lxssp v%u,%llu(r%u)\n", vRT, immediate_val,
+               rA_addr );
          DIPp( is_prefix, ",%u", R );
 
          putVSReg( vRT+32,
@@ -14089,107 +14188,98 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
    }
 
    case 0x2E:  // pstxsd
-   case 0x2F:  // pstxssp
-   case 0x3d:  // lxv, stxv, stxsd, stxssp, pstd
-   case 0x32:  // plxv  (TX=0)
-   case 0x33:  // plxv  (TX=1)
-   case 0x36:  // pstxv
    {
+      // pstxsd (Store VSX Scalar Doubleword)
       UChar vRS  = ifieldRegDS(theInstr);
-      UInt  TX = IFIELD( theInstr,  3, 1);  // default TX or SX bit field
-
-      opc2 = IFIELD(theInstr, 0, 3);
 
-      if ((opc1 == 0x32) || (opc1 == 0x33)) {
-         TX = IFIELD( theInstr,  26, 1);  // TX special case
-         opc2 = 1;  // Force plxv to match lxv case
-      }
-      if (opc1 == 0x2E) opc2 = 2;  // Map pstxsd inst to stxsd
-      if (opc1 == 0x2F) opc2 = 3;  // Map pstxssp inst to stxssp
-      if (opc1 == 0x36) {
-         opc2 = 5;  // Map pstxv inst to stxv
-         TX = IFIELD( theInstr,  26, 1);  // Actually SX in the ISA
-      }
-      if ((opc2 == 0x1) || (opc2 == 0x5)) {    // lxv, stxv, stxsd
-         UInt ea_off = 8;
-         IRTemp word[2];
-         IRExpr* irx_addr;
-         UInt  T  = IFIELD( theInstr, 21, 5);  // T or S depending on inst
+      assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                       rA_addr, ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+      pDIP( is_prefix, "stxsd v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
+      DIPp( is_prefix, ",%u", R );
+      store( mkexpr(EA), unop( Iop_V128HIto64,
+                               getVSReg( vRS+32 ) ) );
+      /* HW is clearing vector element 1.  Don't see that in the ISA but
+       * matching the HW.
+       */
+      putVSReg( vRS+32, binop( Iop_64HLtoV128,
+                               unop( Iop_V128HIto64,
+                                     getVSReg( vRS+32 ) ),
+                               mkU64( 0 ) ) );
+      return True;
+   }
+   break;
 
-         /* Effective address calculation */
-         if (opc1 == 0x3D) {   // stxv
-            UInt uimm16   = ifieldUIMM16(theInstr);
-            Int  simm16 = extend_s_16to32(uimm16);
+   case 0x2F:
+   {
+      // pstxssp (Store VSX Scalar Single - store double precision
+      // value from register into memory in single precision format)
+      UChar vRS  = ifieldRegDS(theInstr);
+      IRTemp high64 = newTemp(Ity_F64);
+      IRTemp val32  = newTemp(Ity_I32);
 
-            simm16 = simm16 & DQFORM_IMMASK;
-            assign( EA, ea_rAor0_simm( rA_addr, simm16  ) );
+      assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                       rA_addr, ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+      pDIP( is_prefix, "stxssp v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
+      DIPp( is_prefix, ",%u", R );
 
-         } else {
-            assign( EA,
-                    calculate_prefix_EA( prefix, theInstr, rA_addr, ptype,
-                                         DFORM_IMMASK, &immediate_val, &R ) );
-         }
+      assign(high64, unop( Iop_ReinterpI64asF64,
+                           unop( Iop_V128HIto64, getVSReg( vRS+32 ) ) ) );
 
-         word[0] = newTemp(Ity_I64);
-         word[1] = newTemp(Ity_I64);
+      assign(val32, unop( Iop_ReinterpF32asI32,
+                          unop( Iop_TruncF64asF32,
+                                mkexpr(high64) ) ) );
+      store( mkexpr(EA), mkexpr( val32 ) );
 
-         if ( opc2 == 1) {
-            // lxv (Load VSX Vector)
-            pDIP( is_prefix, "lxv v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr );
-            DIPp( is_prefix, ",%u", R );
-            assign( word[0], load( Ity_I64, mkexpr( EA ) ) );
+      return True;
+   }
+   break;
 
-            irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
-                           ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+   case 0x3d:  // lxv
+   {
+      IRExpr* irx_addr;
+      IRTemp word[2];
+      UInt ea_off = 8;
+      UChar vRS = ifieldRegDS(theInstr);
+      UInt T = IFIELD( theInstr, 21, 5);
+      UInt TX = IFIELD( theInstr, 3, 1);
 
-            assign( word[1], load( Ity_I64, irx_addr ) );
+      opc2 = IFIELD(theInstr, 0, 3);
 
-            if (host_endness == VexEndnessBE)
-               putVSReg( TX*32+T, binop( Iop_64HLtoV128,
-                                         mkexpr( word[0] ),
-                                         mkexpr( word[1] ) ) );
-            else
-               putVSReg( TX*32+T, binop( Iop_64HLtoV128,
-                                         mkexpr( word[1] ),
-                                         mkexpr( word[0] ) ) );
-            return True;
+      if ( IFIELD( theInstr, 0, 3) == 1) {
+         // lxv (Load VSX Vector)
+         assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                          rA_addr, ptype, DQFORM_IMMASK,
+                                          &immediate_val, &R ) );
 
-         } else if ( opc2 == 5) {
-            // stxv (Store VSX Vector)
-            pDIP( is_prefix, "stxv v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr );
-            DIPp( is_prefix, ",%u", R );
+         DIP("lxv v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr );
+         word[0] = newTemp(Ity_I64);
+         assign( word[0], load( Ity_I64, mkexpr( EA ) ) );
 
-            if (host_endness == VexEndnessBE) {
-               store( mkexpr(EA), unop( Iop_V128HIto64,
-                                        getVSReg( TX*32+T ) ) );
-               irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
-                           ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
-               store( irx_addr, unop( Iop_V128to64,
-                                       getVSReg( TX*32+T ) ) );
-            } else {
-               store( mkexpr(EA), unop( Iop_V128to64,
-                                        getVSReg( TX*32+T ) ) );
-               irx_addr
-                  = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+         irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
                            ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
-               store( irx_addr, unop( Iop_V128HIto64,
-                                      getVSReg( TX*32+T ) ) );
-            }
-            return True;
-
-         } else
-            return False;
+         word[1] = newTemp(Ity_I64);
+         assign( word[1], load( Ity_I64, irx_addr ) );
 
-         break;
+         if (host_endness == VexEndnessBE)
+            putVSReg( TX*32+T, binop( Iop_64HLtoV128,
+                                      mkexpr( word[0] ),
+                                      mkexpr( word[1] ) ) );
+         else
+            putVSReg( TX*32+T, binop( Iop_64HLtoV128,
+                                      mkexpr( word[1] ),
+                                      mkexpr( word[0] ) ) );
+         return True;
 
-      } else if ((opc2 & 0x3) == 0x2) {
+       } else if ((opc2 & 0x3) == 0x2) {
          // stxsd (Store VSX Scalar Doubleword)
-         pDIP( is_prefix, "stxsd v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
-         DIPp( is_prefix, ",%u", R );
-
+         R = 0;  // must be zero for word instruction
          assign( EA, calculate_prefix_EA( prefix, theInstr,
                                           rA_addr, ptype, DSFORM_IMMASK,
                                           &immediate_val, &R ) );
+
+         DIP("stxsd v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
          store( mkexpr(EA), unop( Iop_V128HIto64,
                                   getVSReg( vRS+32 ) ) );
          /* HW is clearing vector element 1.  Don't see that in the ISA but
@@ -14207,12 +14297,10 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
          IRTemp high64 = newTemp(Ity_F64);
          IRTemp val32  = newTemp(Ity_I32);
 
-         pDIP( is_prefix, "stxssp v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
-         DIPp( is_prefix, ",%u", R );
-
-         assign( EA, calculate_prefix_EA( prefix, theInstr,
-                                          rA_addr, ptype, DSFORM_IMMASK,
-                                          &immediate_val, &R ) );
+         assign( EA,
+                 calculate_prefix_EA( prefix, theInstr, rA_addr, ptype,
+                                      DSFORM_IMMASK, &immediate_val, &R ) );
+         DIP("stxssp v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr);
          assign(high64, unop( Iop_ReinterpI64asF64,
                               unop( Iop_V128HIto64, getVSReg( vRS+32 ) ) ) );
 
@@ -14223,31 +14311,51 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
 
          return True;
 
+      } else if (opc2  == 0x5) {
+         // stxv (Store VSX Vector)
+         assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                          rA_addr, ptype, DQFORM_IMMASK,
+                                          &immediate_val, &R ) );
+         DIP("stxv v%u,%llu(r%u)\n", vRS, immediate_val, rA_addr );
+
+         if (host_endness == VexEndnessBE) {
+            store( mkexpr(EA), unop( Iop_V128HIto64,
+                                     getVSReg( TX*32+T ) ) );
+            irx_addr
+               = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+                        ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+            store( irx_addr, unop( Iop_V128to64,
+                                   getVSReg( TX*32+T ) ) );
+         } else {
+            store( mkexpr(EA), unop( Iop_V128to64,
+                                     getVSReg( TX*32+T ) ) );
+            irx_addr
+               = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+                        ty == Ity_I64 ? mkU64( ea_off ) : mkU32( ea_off ) );
+               store( irx_addr, unop( Iop_V128HIto64,
+                                      getVSReg( TX*32+T ) ) );
+         }
+         return True;
+
       } else {
-         vex_printf("dis_fp_pair_prefix(ppc) : DS-form wrong opc2\n");
+         vex_printf("dis_fp_pair vector load/store (ppc) : DS-form wrong opc2\n");
          return False;
       }
-      break;
    }
+   break;
 
    case 0x3A:  // plxvp
    {
       UChar XTp = ifieldRegXTp(theInstr);
 
-      /* Endian aware prefixed load */
-      pDIP( is_prefix, "lxvp %u,%llu(%u)", XTp, immediate_val, rA_addr );
-      DIPp( is_prefix, ",%u", R );
-
-      if (R == 1 ) {
-         vex_printf("Illegal instruction R = 1; plxvp %u,%llu(%u)\n",
-                    XTp, immediate_val, rA_addr );
-         return False;
-      }
-
       assign( EA, calculate_prefix_EA( prefix, theInstr,
                                        rA_addr, ptype, DFORM_IMMASK,
                                        &immediate_val, &R ) );
 
+      /* Endian aware prefixed load */
+      pDIP( is_prefix, "lxvp %u,%llu(%u)", XTp, immediate_val, rA_addr );
+      DIPp( is_prefix, ",%u", R );
+
       // address of next 128bits
       assign( EA_16, binop( Iop_Add64, mkU64( 16 ), mkexpr( EA ) ) );
       if (host_endness == VexEndnessBE) {
@@ -14266,6 +14374,10 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
       IRTemp EA_24 = newTemp(ty);
       UChar XTp = ifieldRegXTp(theInstr);
 
+      assign( EA, calculate_prefix_EA( prefix, theInstr,
+                                       rA_addr, ptype, DFORM_IMMASK,
+                                       &immediate_val, &R ) );
+
       /* Endian aware prefixed load */
       pDIP( is_prefix, "stxvp %u,%llu(%u)\n", XTp, immediate_val, rA_addr );
       DIPp( is_prefix, ",%u", R );
@@ -14276,10 +14388,6 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
          return False;
       }
 
-      assign( EA, calculate_prefix_EA( prefix, theInstr,
-                                       rA_addr, ptype, DFORM_IMMASK,
-                                       &immediate_val, &R ) );
-
       assign( EA_8, binop( Iop_Add64, mkU64( 8 ), mkexpr( EA ) ) );
       assign( EA_16, binop( Iop_Add64, mkU64( 16 ), mkexpr( EA ) ) );
       assign( EA_24, binop( Iop_Add64, mkU64( 24 ), mkexpr( EA ) ) );
@@ -14298,6 +14406,50 @@ static Bool dis_fp_pair_prefix ( UInt prefix, UInt theInstr )
       return True;
    }
 
+   case 0x36:  // pstxv0
+   case 0x37:  // pstxv1, pstxv inst where bit 5 is SX
+   {
+      // pstxv (Prefixed store VSX Vector 1 8LS:D-form)
+      // AKA pstxv0, pstxv1
+      UInt  S  = IFIELD( theInstr, 21, 5);
+      UInt  SX = IFIELD( theInstr, 26, 1);
+      UInt  XS = 32*SX+S;
+      UChar vRS  = ifieldRegDS(theInstr);
+      IRTemp tmpV128  = newTemp(Ity_V128);
+      IRExpr* irx_addr;
+      UInt ea_off = 8;
+
+      DIP("pstxv v%u,%llu(r%u)", vRS, immediate_val, rA_addr );
+      DIPp( is_prefix, ",%u", R );
+
+      assign( tmpV128, getVSReg( XS ) );
+
+      assign( EA,
+              calculate_prefix_EA( prefix, theInstr,
+                                   rA_addr, ptype, DFORM_IMMASK,
+                                   &immediate_val, &R ) );
+
+      if (host_endness == VexEndnessBE) {
+         store( mkexpr(EA), unop( Iop_V128HIto64,
+                                  mkexpr( tmpV128 ) ) );
+         irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+                           ty == Ity_I64 ? mkU64( ea_off ):
+                           mkU32( ea_off ) );
+         store( irx_addr, unop( Iop_V128to64,
+                                mkexpr( tmpV128 ) ) );
+
+      } else {
+         store( mkexpr(EA), unop( Iop_V128to64,
+                                  mkexpr( tmpV128 ) ) );
+         irx_addr = binop( mkSzOp( ty, Iop_Add8 ), mkexpr( EA ),
+                           ty == Ity_I64 ? mkU64( ea_off ):
+                           mkU32( ea_off ) );
+         store( irx_addr, unop( Iop_V128HIto64,
+                                mkexpr( tmpV128 ) ) );
+      }
+      return True;
+   }
+
    default:
       vex_printf("dis_fp_pair_prefix(ppc)(instr)\n");
       return False;
@@ -34336,6 +34488,7 @@ DisResult disInstr_PPC_WRK (
    Bool      allow_isa_2_07 = False;
    Bool      allow_isa_3_0  = False;
    Bool      allow_isa_3_1  = False;
+   Bool      is_prefix;
 
    /* What insn variants are we supporting today? */
    if (mode64) {
@@ -34534,6 +34687,7 @@ DisResult disInstr_PPC_WRK (
 
    opc1 = ifieldOPC(theInstr);
    opc2 = ifieldOPClo10(theInstr);
+   is_prefix = prefix_instruction( prefix );
 
    // Note: all 'reserved' bits must be cleared, else invalid
    switch (opc1) {
@@ -34556,13 +34710,21 @@ DisResult disInstr_PPC_WRK (
 
    /* Integer Logical Instructions */
    case 0x1C: case 0x1D: case 0x18: // andi., andis., ori
-   case 0x1A: case 0x1B: // xori,   xoris
+   case 0x1A:  // xori
       if (dis_int_logic( prefix, theInstr )) goto decode_success;
       goto decode_failure;
 
-   case 0x19: // oris
-      if (dis_int_logic( prefix, theInstr ))  //oris
+   case 0x1B:
+      if ( !is_prefix ) {  // oris
+         if (dis_int_logic( prefix, theInstr )) goto decode_success;
+      }
+      goto decode_failure;
+
+   case 0x19:
+      if ( !is_prefix ) {  //oris
+         if (dis_int_logic( prefix, theInstr ))
          goto decode_success;
+      }
       goto decode_failure;
 
    /* Integer Rotate Instructions */
@@ -34579,15 +34741,19 @@ DisResult disInstr_PPC_WRK (
    /* Integer Load Instructions */
    case 0x20:   // lwz
       {
-         UChar tmp_opc2 = IFIELD(theInstr, (31-(46-32)), 4);  // bits[43:46]
+         UInt ptype  = PrefixType(prefix);
 
-         // splat instructions: xxspltiw, xxspltidp, xxsplti32dx
-         if (( tmp_opc2 >= 0 ) && ( tmp_opc2 <= 3 )
-             && prefix_instruction( prefix)) {
+         if (( ptype == 1) && prefix_instruction( prefix)) {
+            // splat instructions: xxspltiw, xxspltidp, xxsplti32dx
             if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
             if (dis_vector_splat_imm_prefix( prefix, theInstr ))
                goto decode_success;
 
+         } else if ( is_prefix && (ptype == pType2) ) {  // plwz
+            if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+            if (dis_int_load_prefix( prefix, theInstr ))
+               goto decode_success;
+
          } else {  // lwz
             if (dis_int_load_prefix( prefix, theInstr ))
                goto decode_success;
@@ -34599,11 +34765,15 @@ DisResult disInstr_PPC_WRK (
       {
          UInt ptype  = PrefixType(prefix);
 
-         if (prefix_instruction( prefix) && ( ptype == pType1 ) ) {
+         if (is_prefix && ( ptype == pType1 ) ) {
             if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
             // splat instructions: xxpermx
             if (dis_vector_permute_prefix( prefix, theInstr, abiinfo ))
                goto decode_success;
+         } else if (is_prefix && ( ptype == pType1 ) ) {  // plbz:  load instruction
+            if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+            if (dis_int_load_prefix( prefix, theInstr ))
+               goto decode_success;
          } else {  // lbz:  load instruction
             if (dis_int_load_prefix( prefix, theInstr ))
                goto decode_success;
@@ -34625,47 +34795,77 @@ DisResult disInstr_PPC_WRK (
       goto decode_failure;
 
    /* Integer Store Instructions */
-   case 0x26: case 0x2C: case 0x24: // stb, sth, stw
-      ISA_3_1_PREFIX_CHECK
-      if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
-         goto decode_success;
+   case 0x24:
+      if (is_prefix && (PrefixType(prefix) == pType2)) {  // pstw
+         ISA_3_1_PREFIX_CHECK
+         if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+            goto decode_success;
+      } else if ( !is_prefix ) {   // stw
+         if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+            goto decode_success;
+      }
+      goto decode_failure;
+
+   case 0x26:
+      if (is_prefix && (PrefixType(prefix) == pType2)) {  // pstb
+         ISA_3_1_PREFIX_CHECK
+         if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+            goto decode_success;
+      } else if ( !is_prefix ) {  // stb
+         if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+            goto decode_success;
+      }
+      goto decode_failure;
+
+   case 0x2C:
+      if (is_prefix && (PrefixType(prefix) == pType2)) {  // psth
+         ISA_3_1_PREFIX_CHECK
+        if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+           goto decode_success;
+      } else if ( !is_prefix ) {  //sth
+         if (dis_int_store_prefix( prefix, theInstr, abiinfo ))
+            goto decode_success;
+      }
       goto decode_failure;
 
    case 0x27: case 0x2D: case 0x25: // stbu, sthu, stwu
       if (dis_int_store( prefix, theInstr, abiinfo )) goto decode_success;
       goto decode_failure;
 
-   case 0x28:    // lhz
-      ISA_3_1_PREFIX_CHECK
-      if (dis_int_load_prefix( prefix, theInstr ))
-         goto decode_success;
+   case 0x28:
+      if (is_prefix && (PrefixType(prefix) == pType2)) {  // plhz
+         ISA_3_1_PREFIX_CHECK
+         if (dis_int_load_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if ( !is_prefix ) {   // lhz
+         if (dis_int_load_prefix( prefix, theInstr ))
+            goto decode_success;
+      }
       goto decode_failure;
 
-   case 0x29:                 // lhzu, plwa
-      if (prefix_instruction( prefix)) {
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+   case 0x29:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plwa
+         ISA_3_1_PREFIX_CHECK
          // prefix inst: plwa
          if (dis_int_load_ds_form_prefix( prefix, theInstr ))
             goto decode_success;
-      } else {
-         // lhzu
-         if (dis_int_load( prefix, theInstr )) goto decode_success;
+      } else if ( !is_prefix ) {  // lhzu
+         if (dis_int_load( prefix, theInstr ))
+            goto decode_success;
       }
       goto decode_failure;
 
    case 0x2A:   // lha, plha, plxsd
    {
-      if (prefix_instruction( prefix )) {
-         UInt ptype  = PrefixType(prefix);
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
-         if (ptype == pType0) {
-           if (dis_fp_pair_prefix( prefix, theInstr )) // plxsd
-               goto decode_success;
-         } else if (ptype == pType2) {
-            if (dis_int_load_prefix( prefix, theInstr )) // plha
-               goto decode_success;
-         }
-      } else {
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plxsd
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if (is_prefix && (PrefixType(prefix) == pType2)) {  // plha
+         ISA_3_1_PREFIX_CHECK
+         if (dis_int_load_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if ( !is_prefix ) {
          if (dis_int_load_prefix( prefix, theInstr )) // lha
             goto decode_success;
       }
@@ -34673,11 +34873,11 @@ DisResult disInstr_PPC_WRK (
    goto decode_failure;
 
    case 0x2B:   //  lhau, plxssp
-      if (prefix_instruction( prefix)) {
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
-         if (dis_fp_pair_prefix( prefix, theInstr )) // plxssp
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plxssp
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
             goto decode_success;
-      } else {
+      } else if ( !is_prefix ) {  // lhau
          if (dis_int_load( prefix, theInstr ))
             goto decode_success;
       }
@@ -34685,22 +34885,21 @@ DisResult disInstr_PPC_WRK (
 
    /* Integer Load and Store Multiple Instructions */
    case 0x2E:
-      if (prefix_instruction( prefix )) { // pstxsd
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+      if (is_prefix && (PrefixType(prefix) == pType0)) { // pstxsd
+         ISA_3_1_PREFIX_CHECK
          if (dis_fp_pair_prefix( prefix, theInstr )) goto decode_success;
-      } else {  // lmw,
+      } else if ( !is_prefix ) {  // lmw,
          if (dis_int_ldst_mult( prefix, theInstr )) goto decode_success;
       }
       goto decode_failure;
 
    case 0x2F:
-      if (prefix_instruction( prefix )) { // pstxssp
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+      if (is_prefix && (PrefixType(prefix) == pType0)) { // pstxssp
+         ISA_3_1_PREFIX_CHECK
          if (dis_fp_pair_prefix( prefix, theInstr )) goto decode_success;
-      } else {  // stmw
+      } else if ( !is_prefix ) {  // stmw
          if (dis_int_ldst_mult( prefix, theInstr )) goto decode_success;
       }
-
       goto decode_failure;
 
    /* Branch Instructions */
@@ -34730,10 +34929,14 @@ DisResult disInstr_PPC_WRK (
       goto decode_failure;
 
    /* Floating Point Load Instructions */
-   case 0x30:                      // lfs
+   case 0x30:
       if (!allow_F) goto decode_noF;
-      ISA_3_1_PREFIX_CHECK
-      if (dis_fp_load_prefix( prefix, theInstr )) goto decode_success;
+      if (is_prefix && (PrefixType(prefix) == pType2)) { // plfs
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_load_prefix( prefix, theInstr )) goto decode_success;
+      } else if ( !is_prefix ) {  // lfs
+         if (dis_fp_load_prefix( prefix, theInstr )) goto decode_success;
+      }
       goto decode_failure;
 
    case 0x31:   // lfsu, stxv
@@ -34746,71 +34949,87 @@ DisResult disInstr_PPC_WRK (
       }
       goto decode_failure;
 
-   case 0x32:            //  plfd, lfd, plxv
-      if (!allow_F) goto decode_noF;
-      if (prefix_instruction( prefix )) {
-         UInt ptype = PrefixType(prefix);
-
-         if (ptype == pType0)       //plxv  (TX=0)
-            if (dis_fp_pair_prefix( prefix, theInstr ))
-               goto decode_success;
-
-         if (ptype == pType2)     // plfd
-            if (dis_fp_load_prefix( prefix, theInstr ))
-               goto decode_success;
-
-      } else {  // lfd
+   case 0x32:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plxv, TX bit = 0
+         if (!allow_F) goto decode_noF;
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if (is_prefix && (PrefixType(prefix) == pType2)) {  // plfd
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_load_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if ( !is_prefix ) { // lfd
          if (dis_fp_load_prefix( prefix, theInstr ))
             goto decode_success;
       }
       goto decode_failure;
 
-   case 0x33:            //  lfdu, plxv
-      if (prefix_instruction( prefix )) {
-         UInt ptype = PrefixType(prefix);
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
-
-         if (ptype == pType0)       //plxv  (TX=1)
-            if (dis_fp_pair_prefix( prefix, theInstr ))
-               goto decode_success;
-      } else {
+   case 0x33:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plxv, TX bit = 1
+         if (!allow_F) goto decode_noF;
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else {  //  lfdu
          if (!allow_F) goto decode_noF;
          if (dis_fp_load( prefix, theInstr )) goto decode_success;
       }
       goto decode_failure;
 
    /* Floating Point Store Instructions */
-   case 0x34:                       // stfs
+   case 0x34:
       if (!allow_F) goto decode_noF;
-      ISA_3_1_PREFIX_CHECK
-      if (dis_fp_store_prefix( prefix, theInstr )) goto decode_success;
+      if (is_prefix && (PrefixType(prefix) == pType2)) {  // pstfs
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_store_prefix( prefix, theInstr )) goto decode_success;
+      } else if ( !is_prefix ) { // stfs
+         if (dis_fp_store_prefix( prefix, theInstr )) goto decode_success;
+      }
       goto decode_failure;
 
-   case 0x36:
+   case 0x35:            // stfsu
       if (!allow_F) goto decode_noF;
-      if (!prefix_instruction( prefix )) {  // stfd
+      if (dis_fp_store( prefix, theInstr )) goto decode_success;
+      goto decode_failure;
+
+   case 0x36:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // pstxv, XS bit = 0
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if ( is_prefix && (PrefixType(prefix) == pType2)) { // pstfd
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_store_prefix( prefix, theInstr ))
+            goto decode_success;
+      } else if ( !is_prefix ) {  // stfd
+         if (!allow_F) goto decode_noF;
          if (dis_fp_store_prefix( prefix, theInstr )) goto decode_success;
-      } else {
-         UInt ptype = PrefixType(prefix);
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
-         if (ptype == 0) {                       // pstxv
-            if (dis_fp_pair_prefix( prefix, theInstr ))
-               goto decode_success;
-         } else if (ptype == 2) {                 // pstfd
-            if (dis_fp_store_prefix( prefix, theInstr ))
-               goto decode_success;
-         } else {
-            vex_printf("ERROR, opc1 = 0x36, Unknown prefix instruction\n");
-         }
       }
       goto decode_failure;
 
-   case 0x35: case 0x37:            // stfsu, stfdu
-      if (!allow_F) goto decode_noF;
-      if (dis_fp_store( prefix, theInstr )) goto decode_success;
+   case 0x37:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // pstxv, XS bit = 1
+         ISA_3_1_PREFIX_CHECK
+         if (dis_fp_pair_prefix( prefix, theInstr ))
+            goto decode_success;
+      }  else if ( !is_prefix )  {  // stfdu
+         if (!allow_F) goto decode_noF;
+         if (dis_fp_store( prefix, theInstr )) goto decode_success;
+      }
+     goto decode_failure;
+
+   /* 128-bit Integer Load */
+   case 0x38:
+      if (is_prefix && (PrefixType(prefix) == pType0)) {  // plq
+         ISA_3_1_PREFIX_CHECK
+            if (dis_int_load_prefix( prefix, theInstr )) goto decode_success;
+      } else if ( !is_prefix) {  // lq
+            if (dis_int_load_prefix( prefix, theInstr )) goto decode_success;
+      }
       goto decode_failure;
 
-      /* Floating Point Load Double Pair Instructions */
+   /* Floating Point Load Double Pair Instructions */
    case 0x39:  // pld, lxsd, lxssp, lfdp
       {
          UInt opc2tmp = ifieldOPC0o2(theInstr);
@@ -34836,50 +35055,49 @@ DisResult disInstr_PPC_WRK (
 
    case 0x3D:
       {
-         UInt opc2tmp = IFIELD( theInstr, 0, 3 );
-
-         /* Note stxssp opc2 field is just bits [30:31], the rest use
-            bits [29:31].  */
-         if ((opc2tmp == 0x1) || (opc2tmp == 0x5)
-             || ((opc2tmp & 0x3) == 0x3) || ((opc2tmp & 0x3) == 0x2)) {
-            // stxsd(2), stxssp(3) masked lower two bits
-            // lxv(1), stxv(5)
-            if (!allow_F) goto decode_noF;
-            if (dis_fp_pair_prefix( prefix, theInstr ))
-               goto decode_success;
+         UInt bits1_0 = IFIELD( theInstr, 0, 2 );
+         UInt bits2_0 = IFIELD( theInstr, 0, 3 );
 
-         } else if (prefix_instruction( prefix )) {
-            //pstd
-            if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+         if (is_prefix && (PrefixType(prefix) == pType0)) { // pstd
             if (dis_int_store_ds_prefix( prefix, theInstr, abiinfo ))
                goto decode_success;
 
-         } else {
-            // stfdp lower two bits = 2
-            if (!allow_F) goto decode_noF;
-            if (dis_fp_pair( prefix, theInstr )) goto decode_success;
+         } else if ( !is_prefix ) {
+            if (bits2_0 == 0x1) {        // lxv    [29:31] = 1
+               if (dis_fp_pair_prefix( prefix, theInstr ))
+                  goto decode_success;
+            } else if (bits2_0 == 0x5) {  // stxv   [29:31] = 5
+               if (dis_fp_pair_prefix( prefix, theInstr ))
+                  goto decode_success;
+            } else if (bits1_0 == 0x0) {  // stfdp   [30:31] = 0
+               if (dis_fp_pair( prefix, theInstr ))
+                  goto decode_success;
+            } else if (bits1_0 == 0x2) {  // stxsd   [30:31] = 2
+               if (dis_fp_pair_prefix( prefix, theInstr ))
+                  goto decode_success;
+            } else if (bits1_0 == 0x3) {  // stxssp  [30:31] = 3
+               if (dis_fp_pair_prefix( prefix, theInstr ))
+                  goto decode_success;
+            }
          }
          goto decode_failure;
       }
 
-   /* 128-bit Integer Load */
-   case 0x38:  // lq
-      ISA_3_1_PREFIX_CHECK
-      if (dis_int_load_prefix( prefix, theInstr )) goto decode_success;
-      goto decode_failure;
-
    /* 64bit Integer Loads */
    case 0x3A:  // word inst: ld, ldu, lwa
-      {
+   {
          UChar   b1_0  = IFIELD(theInstr, 0, 2);
-
          if (!mode64) goto decode_failure;
-         if (prefix_instruction( prefix )) {  // plxvp
-            if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+
+         if (is_prefix && (PrefixType(prefix) == pType0)) {  // plxvp
+            ISA_3_1_PREFIX_CHECK
             if (dis_fp_pair_prefix( prefix, theInstr ))
                goto decode_success;
 
-         } else if ((b1_0 >= 0) && (b1_0 <= 2)) {  // ld, ldu, lwa,
+         } else if ( !is_prefix && ( b1_0 != 0x3 )) {
+            // ld  [30:31] = 0
+            // ldu [30:31] = 1
+            // lwa [30:31] = 2
             /* Note, here we only deal with the non prefix versions
                of the instructions.  Hence do not check for ISA 3.1.  */
             if (dis_int_load_ds_form_prefix( prefix, theInstr ))
@@ -35066,10 +35284,9 @@ DisResult disInstr_PPC_WRK (
 
    case 0x3C: // pstq, VSX instructions (except load/store)
    {
-      if ( prefix_instruction( prefix ) ) {
+      if ( is_prefix && (PrefixType(prefix) == pType0) ) {
          // pstq instruction
-
-         if ( !(allow_isa_3_1) ) goto decode_noIsa3_1;
+         ISA_3_1_PREFIX_CHECK
          if (dis_int_store_ds_prefix( prefix, theInstr, abiinfo ))
             goto decode_success;
          goto decode_failure;
@@ -35296,11 +35513,14 @@ DisResult disInstr_PPC_WRK (
       {
          UChar b1_0 = IFIELD(theInstr, 2, 0);
 
-         if (prefix_instruction( prefix)) {   // pstxvp
+         if (is_prefix && (PrefixType(prefix) == pType0)) {   // pstxvp
             if (dis_fp_pair_prefix( prefix, theInstr ))
                goto decode_success;
 
-         } else if (b1_0 != 3) {   // std, stdu, stq
+         } else if ( !is_prefix && (b1_0 != 3)) {
+            // std  [30:31] = 0
+            // stdu [30:31] = 1
+            // stq  [30:31] = 2
             if (dis_int_store_ds_prefix( prefix, theInstr, abiinfo ))
                goto decode_success;
 
@@ -36583,12 +36803,22 @@ DisResult disInstr_PPC_WRK (
 
    decode_failure:
    /* All decode failures end up here. */
+   opc1 = ifieldOPC(theInstr);
    opc2 = (theInstr) & 0x7FF;
    if (sigill_diag) {
-      vex_printf("disInstr(ppc): unhandled instruction: "
-                 "0x%x\n", theInstr);
-      vex_printf("                 primary %d(0x%x), secondary %u(0x%x)\n", 
-                 opc1, opc1, opc2, opc2);
+
+      if (prefix_instruction( prefix )) {
+         vex_printf("disInstr(ppc): unhandled prefix instruction: "
+                    "prefix = 0x%x, theInstr 0x%x\n", prefix, theInstr);
+         vex_printf("                 primary %d(0x%x), secondary %u(0x%x)\n",
+                    opc1, opc1, opc2, opc2);
+
+      } else {
+         vex_printf("disInstr(ppc): unhandled instruction: "
+                    "0x%x\n", theInstr);
+         vex_printf("                 primary %d(0x%x), secondary %u(0x%x)\n",
+                    opc1, opc1, opc2, opc2);
+      }
    }
 
    not_supported: