1f061d
commit b8fbe1485567fb240404344533c16a82d53b868e
1f061d
Author: carll <carll@8f6e269a-dfd6-0310-a8e1-e2731360e62c>
1f061d
Date:   Mon Nov 7 19:41:30 2016 +0000
1f061d
1f061d
    Fix xxsel parsing error.
1f061d
    
1f061d
    The xxsel instruction uses part of the standard opc2 field to specify
1f061d
    a additional operand or other values.  A subset of the field is used for
1f061d
    the actual opcode.  The masking and array lookup was getting confused by
1f061d
    bits in the the additional operand field.  The arrays were split so only
1f061d
    the opcodes that should be found for a given mask is in the array.  This
1f061d
    also speeds up the search as you are not searching through values that
1f061d
    cannot match.  The small groups of opcodes for a couple of the masks are
1f061d
    now done in a case statement as that is probably faster then doing an array
1f061d
    look up.
1f061d
    
1f061d
    Bugzilla 148000
1f061d
    
1f061d
    
1f061d
    git-svn-id: svn://svn.valgrind.org/vex/trunk@3284 8f6e269a-dfd6-0310-a8e1-e2731360e62c
1f061d
1f061d
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
1f061d
index c393740..c265645 100644
1f061d
--- a/VEX/priv/guest_ppc_toIR.c
1f061d
+++ b/VEX/priv/guest_ppc_toIR.c
1f061d
@@ -18146,7 +18146,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
    assign( vB, getVSReg( XB ) );
1f061d
 
1f061d
    switch (opc2) {
1f061d
-      case 0x18C: case 0x38C:  // xvcmpeqdp[.] (VSX Vector Compare Equal To Double-Precision [ & Record ])
1f061d
+      case 0x18C:  // xvcmpeqdp[.] (VSX Vector Compare Equal To Double-Precision [ & Record ])
1f061d
       {
1f061d
          DIP("xvcmpeqdp%s crf%d,fr%u,fr%u\n", (flag_rC ? ".":""),
1f061d
              XT, XA, XB);
1f061d
@@ -18154,7 +18154,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
          break;
1f061d
       }
1f061d
 
1f061d
-      case 0x1CC: case 0x3CC: // xvcmpgedp[.] (VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ])
1f061d
+      case 0x1CC:  // xvcmpgedp[.] (VSX Vector Compare Greater Than or Equal To Double-Precision [ & Record ])
1f061d
       {
1f061d
          DIP("xvcmpgedp%s crf%d,fr%u,fr%u\n", (flag_rC ? ".":""),
1f061d
              XT, XA, XB);
1f061d
@@ -18162,7 +18162,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
          break;
1f061d
       }
1f061d
 
1f061d
-      case 0x1AC: case 0x3AC: // xvcmpgtdp[.] (VSX Vector Compare Greater Than Double-Precision [ & Record ])
1f061d
+      case 0x1AC:  // xvcmpgtdp[.] (VSX Vector Compare Greater Than Double-Precision [ & Record ])
1f061d
       {
1f061d
          DIP("xvcmpgtdp%s crf%d,fr%u,fr%u\n", (flag_rC ? ".":""),
1f061d
              XT, XA, XB);
1f061d
@@ -18170,7 +18170,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
          break;
1f061d
       }
1f061d
 
1f061d
-      case 0x10C: case 0x30C: // xvcmpeqsp[.] (VSX Vector Compare Equal To Single-Precision [ & Record ])
1f061d
+      case 0x10C:  // xvcmpeqsp[.] (VSX Vector Compare Equal To Single-Precision [ & Record ])
1f061d
       {
1f061d
          IRTemp vD = newTemp(Ity_V128);
1f061d
 
1f061d
@@ -18184,7 +18184,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
          break;
1f061d
       }
1f061d
 
1f061d
-      case 0x14C: case 0x34C: // xvcmpgesp[.] (VSX Vector Compare Greater Than or Equal To Single-Precision [ & Record ])
1f061d
+      case 0x14C:  // xvcmpgesp[.] (VSX Vector Compare Greater Than or Equal To Single-Precision [ & Record ])
1f061d
       {
1f061d
          IRTemp vD = newTemp(Ity_V128);
1f061d
 
1f061d
@@ -18198,7 +18198,7 @@ dis_vvec_cmp( UInt theInstr, UInt opc2 )
1f061d
          break;
1f061d
       }
1f061d
 
1f061d
-      case 0x12C: case 0x32C: //xvcmpgtsp[.] (VSX Vector Compare Greater Than Single-Precision [ & Record ])
1f061d
+      case 0x12C:  //xvcmpgtsp[.] (VSX Vector Compare Greater Than Single-Precision [ & Record ])
1f061d
       {
1f061d
          IRTemp vD = newTemp(Ity_V128);
1f061d
 
1f061d
@@ -27043,17 +27043,93 @@ struct vsx_insn {
1f061d
 };
1f061d
 
1f061d
 //  ATTENTION:  Keep this array sorted on the opcocde!!!
1f061d
-static struct vsx_insn vsx_all[] = {
1f061d
-      { 0x0, "xsaddsp" },
1f061d
-      { 0x4, "xsmaddasp" },
1f061d
-      { 0x8, "xxsldwi" },
1f061d
+static struct vsx_insn vsx_xx2[] = {
1f061d
       { 0x14, "xsrsqrtesp" },
1f061d
       { 0x16, "xssqrtsp" },
1f061d
       { 0x18, "xxsel" },
1f061d
+      { 0x34, "xsresp" },
1f061d
+      { 0x90, "xscvdpuxws" },
1f061d
+      { 0x92, "xsrdpi" },
1f061d
+      { 0x94, "xsrsqrtedp" },
1f061d
+      { 0x96, "xssqrtdp" },
1f061d
+      { 0xb0, "xscvdpsxws" },
1f061d
+      { 0xb2, "xsrdpiz" },
1f061d
+      { 0xb4, "xsredp" },
1f061d
+      { 0xd2, "xsrdpip" },
1f061d
+      { 0xd4, "xstsqrtdp" },
1f061d
+      { 0xd6, "xsrdpic" },
1f061d
+      { 0xf2, "xsrdpim" },
1f061d
+      { 0x112, "xvrspi" },
1f061d
+      { 0x116, "xvsqrtsp" },
1f061d
+      { 0x130, "xvcvspsxws" },
1f061d
+      { 0x132, "xvrspiz" },
1f061d
+      { 0x134, "xvresp" },
1f061d
+      { 0x148, "xxspltw" },
1f061d
+      { 0x14A, "xxextractuw" },
1f061d
+      { 0x150, "xvcvuxwsp" },
1f061d
+      { 0x152, "xvrspip" },
1f061d
+      { 0x154, "xvtsqrtsp" },
1f061d
+      { 0x156, "xvrspic" },
1f061d
+      { 0x16A, "xxinsertw" },
1f061d
+      { 0x170, "xvcvsxwsp" },
1f061d
+      { 0x172, "xvrspim" },
1f061d
+      { 0x190, "xvcvdpuxws" },
1f061d
+      { 0x192, "xvrdpi" },
1f061d
+      { 0x194, "xvrsqrtedp" },
1f061d
+      { 0x196, "xvsqrtdp" },
1f061d
+      { 0x1b0, "xvcvdpsxws" },
1f061d
+      { 0x1b2, "xvrdpiz" },
1f061d
+      { 0x1b4, "xvredp" },
1f061d
+      { 0x1d0, "xvcvuxwdp" },
1f061d
+      { 0x1d2, "xvrdpip" },
1f061d
+      { 0x1d4, "xvtsqrtdp" },
1f061d
+      { 0x1d6, "xvrdpic" },
1f061d
+      { 0x1f0, "xvcvsxwdp" },
1f061d
+      { 0x1f2, "xvrdpim" },
1f061d
+      { 0x212, "xscvdpsp" },
1f061d
+      { 0x216, "xscvdpspn" },
1f061d
+      { 0x232, "xxrsp" },
1f061d
+      { 0x250, "xscvuxdsp" },
1f061d
+      { 0x254, "xststdcsp" },
1f061d
+      { 0x270, "xscvsxdsp" },
1f061d
+      { 0x290, "xscvdpuxds" },
1f061d
+      { 0x292, "xscvspdp" },
1f061d
+      { 0x296, "xscvspdpn" },
1f061d
+      { 0x2b0, "xscvdpsxds" },
1f061d
+      { 0x2b2, "xsabsdp" },
1f061d
+      { 0x2b6, "xsxexpdp_xsxigdp" },
1f061d
+      { 0x2d0, "xscvuxddp" },
1f061d
+      { 0x2d2, "xsnabsdp" },
1f061d
+      { 0x2d4, "xststdcdp" },
1f061d
+      { 0x2e4, "xsnmsubmdp" },
1f061d
+      { 0x2f0, "xscvsxddp" },
1f061d
+      { 0x2f2, "xsnegdp" },
1f061d
+      { 0x310, "xvcvspuxds" },
1f061d
+      { 0x312, "xvcvdpsp" },
1f061d
+      { 0x330, "xvcvspsxds" },
1f061d
+      { 0x332, "xvabssp" },
1f061d
+      { 0x350, "xvcvuxdsp" },
1f061d
+      { 0x352, "xvnabssp" },
1f061d
+      { 0x370, "xvcvsxdsp" },
1f061d
+      { 0x372, "xvnegsp" },
1f061d
+      { 0x390, "xvcvdpuxds" },
1f061d
+      { 0x392, "xvcvspdp" },
1f061d
+      { 0x3b0, "xvcvdpsxds" },
1f061d
+      { 0x3b2, "xvabsdp" },
1f061d
+      { 0x3b6, "xxbr[h|w|d|q]|xvxexpdp|xvxexpsp|xvxsigdp|xvxsigsp|xvcvhpsp|xvcvsphp|xscvdphp|xscvhpdp" },
1f061d
+      { 0x3d0, "xvcvuxddp" },
1f061d
+      { 0x3d2, "xvnabsdp" },
1f061d
+      { 0x3f2, "xvnegdp" }
1f061d
+};
1f061d
+#define VSX_XX2_LEN (sizeof vsx_xx2 / sizeof *vsx_xx2)
1f061d
+
1f061d
+//  ATTENTION:  Keep this array sorted on the opcocde!!!
1f061d
+static struct vsx_insn vsx_xx3[] = {
1f061d
+      { 0x0,  "xsaddsp" },
1f061d
+      { 0x4,  "xsmaddasp" },
1f061d
+      { 0x9,  "xsmaddmsp" },
1f061d
       { 0x20, "xssubsp" },
1f061d
       { 0x24, "xsmaddmsp" },
1f061d
-      { 0x28, "xxpermdi" },
1f061d
-      { 0x34, "xsresp" },
1f061d
       { 0x3A, "xxpermr" },
1f061d
       { 0x40, "xsmulsp" },
1f061d
       { 0x44, "xsmsubasp" },
1f061d
@@ -27064,174 +27140,112 @@ static struct vsx_insn vsx_all[] = {
1f061d
       { 0x80, "xsadddp" },
1f061d
       { 0x84, "xsmaddadp" },
1f061d
       { 0x8c, "xscmpudp" },
1f061d
-      { 0x90, "xscvdpuxws" },
1f061d
-      { 0x92, "xsrdpi" },
1f061d
-      { 0x94, "xsrsqrtedp" },
1f061d
-      { 0x96, "xssqrtdp" },
1f061d
       { 0xa0, "xssubdp" },
1f061d
       { 0xa4, "xsmaddmdp" },
1f061d
       { 0xac, "xscmpodp" },
1f061d
-      { 0xb0, "xscvdpsxws" },
1f061d
-      { 0xb2, "xsrdpiz" },
1f061d
-      { 0xb4, "xsredp" },
1f061d
       { 0xc0, "xsmuldp" },
1f061d
       { 0xc4, "xsmsubadp" },
1f061d
       { 0xc8, "xxmrglw" },
1f061d
-      { 0xd2, "xsrdpip" },
1f061d
       { 0xd4, "xstsqrtdp" },
1f061d
-      { 0xd6, "xsrdpic" },
1f061d
       { 0xe0, "xsdivdp" },
1f061d
       { 0xe4, "xsmsubmdp" },
1f061d
       { 0xe8, "xxpermr" },
1f061d
       { 0xeC, "xscmpexpdp" },
1f061d
-      { 0xf2, "xsrdpim" },
1f061d
       { 0xf4, "xstdivdp" },
1f061d
       { 0x100, "xvaddsp" },
1f061d
       { 0x104, "xvmaddasp" },
1f061d
-      { 0x10c, "xvcmpeqsp" },
1f061d
+      { 0x10C, "xvcmpeqsp" },
1f061d
       { 0x110, "xvcvspuxws" },
1f061d
-      { 0x112, "xvrspi" },
1f061d
       { 0x114, "xvrsqrtesp" },
1f061d
-      { 0x116, "xvsqrtsp" },
1f061d
       { 0x120, "xvsubsp" },
1f061d
       { 0x124, "xvmaddmsp" },
1f061d
-      { 0x12c, "xvcmpgtsp" },
1f061d
       { 0x130, "xvcvspsxws" },
1f061d
-      { 0x132, "xvrspiz" },
1f061d
-      { 0x134, "xvresp" },
1f061d
       { 0x140, "xvmulsp" },
1f061d
       { 0x144, "xvmsubasp" },
1f061d
-      { 0x148, "xxspltw" },
1f061d
-      { 0x14A, "xxextractuw" },
1f061d
-      { 0x14c, "xvcmpgesp" },
1f061d
-      { 0x150, "xvcvuxwsp" },
1f061d
-      { 0x152, "xvrspip" },
1f061d
-      { 0x154, "xvtsqrtsp" },
1f061d
-      { 0x156, "xvrspic" },
1f061d
+      { 0x14C, "xvcmpgesp", },
1f061d
       { 0x160, "xvdivsp" },
1f061d
       { 0x164, "xvmsubmsp" },
1f061d
-      { 0x16A, "xxinsertw" },
1f061d
-      { 0x170, "xvcvsxwsp" },
1f061d
-      { 0x172, "xvrspim" },
1f061d
       { 0x174, "xvtdivsp" },
1f061d
       { 0x180, "xvadddp" },
1f061d
       { 0x184, "xvmaddadp" },
1f061d
-      { 0x18c, "xvcmpeqdp" },
1f061d
-      { 0x190, "xvcvdpuxws" },
1f061d
-      { 0x192, "xvrdpi" },
1f061d
-      { 0x194, "xvrsqrtedp" },
1f061d
-      { 0x196, "xvsqrtdp" },
1f061d
+      { 0x18C, "xvcmpeqdp" },
1f061d
       { 0x1a0, "xvsubdp" },
1f061d
       { 0x1a4, "xvmaddmdp" },
1f061d
-      { 0x1ac, "xvcmpgtdp" },
1f061d
-      { 0x1b0, "xvcvdpsxws" },
1f061d
-      { 0x1b2, "xvrdpiz" },
1f061d
-      { 0x1b4, "xvredp" },
1f061d
+      { 0x1aC, "xvcmpgtdp" },
1f061d
       { 0x1c0, "xvmuldp" },
1f061d
       { 0x1c4, "xvmsubadp" },
1f061d
       { 0x1cc, "xvcmpgedp" },
1f061d
-      { 0x1d0, "xvcvuxwdp" },
1f061d
-      { 0x1d2, "xvrdpip" },
1f061d
-      { 0x1d4, "xvtsqrtdp" },
1f061d
-      { 0x1d6, "xvrdpic" },
1f061d
       { 0x1e0, "xvdivdp" },
1f061d
       { 0x1e4, "xvmsubmdp" },
1f061d
-      { 0x1f0, "xvcvsxwdp" },
1f061d
-      { 0x1f2, "xvrdpim" },
1f061d
       { 0x1f4, "xvtdivdp" },
1f061d
       { 0x204, "xsnmaddasp" },
1f061d
       { 0x208, "xxland" },
1f061d
-      { 0x212, "xscvdpsp" },
1f061d
-      { 0x216, "xscvdpspn" },
1f061d
       { 0x224, "xsnmaddmsp" },
1f061d
       { 0x228, "xxlandc" },
1f061d
-      { 0x232, "xxrsp" },
1f061d
       { 0x244, "xsnmsubasp" },
1f061d
       { 0x248, "xxlor" },
1f061d
-      { 0x250, "xscvuxdsp" },
1f061d
-      { 0x254, "xststdcsp" },
1f061d
       { 0x264, "xsnmsubmsp" },
1f061d
       { 0x268, "xxlxor" },
1f061d
-      { 0x270, "xscvsxdsp" },
1f061d
       { 0x280, "xsmaxdp" },
1f061d
       { 0x284, "xsnmaddadp" },
1f061d
       { 0x288, "xxlnor" },
1f061d
-      { 0x290, "xscvdpuxds" },
1f061d
-      { 0x292, "xscvspdp" },
1f061d
-      { 0x296, "xscvspdpn" },
1f061d
       { 0x2a0, "xsmindp" },
1f061d
       { 0x2a4, "xsnmaddmdp" },
1f061d
       { 0x2a8, "xxlorc" },
1f061d
-      { 0x2b0, "xscvdpsxds" },
1f061d
-      { 0x2b2, "xsabsdp" },
1f061d
-      { 0x2b6, "xsxexpdp_xsxigdp" },
1f061d
       { 0x2c0, "xscpsgndp" },
1f061d
       { 0x2c4, "xsnmsubadp" },
1f061d
       { 0x2c8, "xxlnand" },
1f061d
-      { 0x2d0, "xscvuxddp" },
1f061d
-      { 0x2d2, "xsnabsdp" },
1f061d
-      { 0x2d4, "xststdcdp" },
1f061d
       { 0x2e4, "xsnmsubmdp" },
1f061d
       { 0x2e8, "xxleqv" },
1f061d
-      { 0x2f0, "xscvsxddp" },
1f061d
-      { 0x2f2, "xsnegdp" },
1f061d
       { 0x300, "xvmaxsp" },
1f061d
       { 0x304, "xvnmaddasp" },
1f061d
-      { 0x30c, "xvcmpeqsp." },
1f061d
-      { 0x310, "xvcvspuxds" },
1f061d
-      { 0x312, "xvcvdpsp" },
1f061d
       { 0x320, "xvminsp" },
1f061d
       { 0x324, "xvnmaddmsp" },
1f061d
-      { 0x32c, "xvcmpgtsp." },
1f061d
-      { 0x330, "xvcvspsxds" },
1f061d
-      { 0x332, "xvabssp" },
1f061d
       { 0x340, "xvcpsgnsp" },
1f061d
       { 0x344, "xvnmsubasp" },
1f061d
-      { 0x34c, "xvcmpgesp." },
1f061d
-      { 0x350, "xvcvuxdsp" },
1f061d
-      { 0x352, "xvnabssp" },
1f061d
-      { 0x354, "xvtstdcsp" },
1f061d
       { 0x360, "xviexpsp" },
1f061d
       { 0x364, "xvnmsubmsp" },
1f061d
-      { 0x370, "xvcvsxdsp" },
1f061d
-      { 0x372, "xvnegsp" },
1f061d
       { 0x380, "xvmaxdp" },
1f061d
       { 0x384, "xvnmaddadp" },
1f061d
-      { 0x38c, "xvcmpeqdp." },
1f061d
-      { 0x390, "xvcvdpuxds" },
1f061d
-      { 0x392, "xvcvspdp" },
1f061d
-      { 0x396, "xsiexpdp" },
1f061d
       { 0x3a0, "xvmindp" },
1f061d
       { 0x3a4, "xvnmaddmdp" },
1f061d
-      { 0x3ac, "xvcmpgtdp." },
1f061d
-      { 0x3b0, "xvcvdpsxds" },
1f061d
-      { 0x3b2, "xvabsdp" },
1f061d
-      { 0x3b6, "xxbr[h|w|d|q]|xvxexpdp|xvxexpsp|xvxsigdp|xvxsigsp|xvcvhpsp|xvcvsphp|xscvdphp|xscvhpdp" },
1f061d
       { 0x3c0, "xvcpsgndp" },
1f061d
       { 0x3c4, "xvnmsubadp" },
1f061d
-      { 0x3cc, "xvcmpgedp." },
1f061d
-      { 0x3d0, "xvcvuxddp" },
1f061d
-      { 0x3d2, "xvnabsdp" },
1f061d
-      { 0x3d4, "xvtstdcdp" },
1f061d
       { 0x3e0, "xviexpdp" },
1f061d
       { 0x3e4, "xvnmsubmdp" },
1f061d
       { 0x3f0, "xvcvsxddp" },
1f061d
-      { 0x3f2, "xvnegdp" }
1f061d
 };
1f061d
-#define VSX_ALL_LEN (sizeof vsx_all / sizeof *vsx_all)
1f061d
+#define VSX_XX3_LEN (sizeof vsx_xx3 / sizeof *vsx_xx3)
1f061d
 
1f061d
 
1f061d
-// ATTENTION: This search function assumes vsx_all array is sorted.
1f061d
-static Int findVSXextOpCode(UInt opcode)
1f061d
+// ATTENTION: This search functions assumes vsx_all array is sorted.
1f061d
+static Int findVSXextOpCode_xx2(UInt opcode)
1f061d
 {
1f061d
    Int low, mid, high;
1f061d
    low = 0;
1f061d
-   high = VSX_ALL_LEN - 1;
1f061d
+   high = VSX_XX2_LEN - 1;
1f061d
    while (low <= high) {
1f061d
       mid = (low + high)/2;
1f061d
-      if (opcode < vsx_all[mid].opcode)
1f061d
+      if (opcode < vsx_xx2[mid].opcode)
1f061d
          high = mid - 1;
1f061d
-      else if (opcode > vsx_all[mid].opcode)
1f061d
+      else if (opcode > vsx_xx2[mid].opcode)
1f061d
+         low = mid + 1;
1f061d
+      else
1f061d
+         return mid;
1f061d
+   }
1f061d
+   return -1;
1f061d
+}
1f061d
+
1f061d
+static Int findVSXextOpCode_xx3(UInt opcode)
1f061d
+{
1f061d
+   Int low, mid, high;
1f061d
+   low = 0;
1f061d
+   high = VSX_XX3_LEN - 1;
1f061d
+   while (low <= high) {
1f061d
+      mid = (low + high)/2;
1f061d
+      if (opcode < vsx_xx3[mid].opcode)
1f061d
+         high = mid - 1;
1f061d
+      else if (opcode > vsx_xx3[mid].opcode)
1f061d
          low = mid + 1;
1f061d
       else
1f061d
          return mid;
1f061d
@@ -27244,31 +27258,68 @@ static Int findVSXextOpCode(UInt opcode)
1f061d
  * passed, and we then try to match it up with one of the VSX forms
1f061d
  * below.
1f061d
  */
1f061d
-static UInt get_VSX60_opc2(UInt opc2_full)
1f061d
+static UInt get_VSX60_opc2(UInt opc2_full, UInt theInstr)
1f061d
 {
1f061d
-#define XX2_MASK 0x000003FE
1f061d
+#define XX2_1_MASK 0x000003FF    // xsiexpdp specific
1f061d
+#define XX2_2_MASK 0x000003FE
1f061d
 #define XX3_1_MASK 0x000003FC
1f061d
 #define XX3_2_MASK 0x000001FC
1f061d
-#define XX3_3_MASK 0x0000007C
1f061d
-#define XX4_MASK 0x00000018
1f061d
-#define VDCMX_MASK 0x000003B8
1f061d
+#define XX3_4_MASK 0x0000027C
1f061d
+#define XX3_5_MASK 0x000003DC
1f061d
+#define XX4_MASK   0x00000018
1f061d
+
1f061d
    Int ret;
1f061d
    UInt vsxExtOpcode = 0;
1f061d
 
1f061d
-   if (( ret = findVSXextOpCode(opc2_full & XX2_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
-   else if (( ret = findVSXextOpCode(opc2_full & XX3_1_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
-   else if (( ret = findVSXextOpCode(opc2_full & VDCMX_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
-   else if (( ret = findVSXextOpCode(opc2_full & XX3_2_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
-   else if (( ret = findVSXextOpCode(opc2_full & XX3_3_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
-   else if (( ret = findVSXextOpCode(opc2_full & XX4_MASK)) >= 0)
1f061d
-      vsxExtOpcode = vsx_all[ret].opcode;
1f061d
+   if (( ret = findVSXextOpCode_xx2(opc2_full & XX2_2_MASK)) >= 0)
1f061d
+      return vsx_xx2[ret].opcode;
1f061d
+   else if ((opc2_full & XX2_1_MASK) == 0x396 )   // xsiexpdp
1f061d
+      return 0x396;
1f061d
+   else if (( ret = findVSXextOpCode_xx3(opc2_full & XX3_1_MASK)) >= 0)
1f061d
+      return vsx_xx3[ret].opcode;
1f061d
+   else {
1f061d
+
1f061d
+      /* There are only a few codes in each of these cases it is
1f061d
+       * probably faster to check for the codes then do the array lookups.
1f061d
+       */
1f061d
+      vsxExtOpcode = opc2_full & XX3_2_MASK;
1f061d
+
1f061d
+      switch (vsxExtOpcode) {
1f061d
+      case 0x10C: return vsxExtOpcode;   // xvcmpeqsp
1f061d
+      case 0x12C: return vsxExtOpcode;   // xvcmpgtsp, xvcmpgtsp.
1f061d
+      case 0x14C: return vsxExtOpcode;   // xvcmpgesp, xvcmpgesp.
1f061d
+      case 0x18C: return vsxExtOpcode;   // xvcmpeqdp, xvcmpeqdp.
1f061d
+      case 0x1AC: return vsxExtOpcode;   // xvcmpgtdp, xvcmpgtdp.
1f061d
+      case 0x1CC: return vsxExtOpcode;   // xvcmpgedp, xvcmpgedp.
1f061d
+      default:  break;
1f061d
+      }
1f061d
 
1f061d
-   return vsxExtOpcode;
1f061d
+      vsxExtOpcode = opc2_full & XX3_4_MASK;
1f061d
+
1f061d
+      switch (vsxExtOpcode) {
1f061d
+      case 0x8:   return vsxExtOpcode;   // xxsldwi
1f061d
+      case 0x28:  return vsxExtOpcode;   // xxpermdi
1f061d
+      default:  break;
1f061d
+      }
1f061d
+
1f061d
+      vsxExtOpcode = opc2_full & XX3_5_MASK;
1f061d
+
1f061d
+      switch (vsxExtOpcode) {
1f061d
+      case 0x354:  return vsxExtOpcode;   // xvtstdcsp
1f061d
+      case 0x3D4:  return vsxExtOpcode;   // xvtstdcdp
1f061d
+      default:  break;
1f061d
+      }
1f061d
+
1f061d
+      if (( opc2_full & XX4_MASK ) == XX4_MASK ) {   // xxsel
1f061d
+         vsxExtOpcode = 0x18;
1f061d
+         return vsxExtOpcode;
1f061d
+      }
1f061d
+   }
1f061d
+
1f061d
+   vex_printf( "Error: undefined opcode 0x %x, the instruction = 0x %x\n",
1f061d
+               opc2_full, theInstr );
1f061d
+   vpanic( "ERROR: get_VSX60_opc2()\n" );
1f061d
+   return 0;
1f061d
 }
1f061d
 
1f061d
 /*------------------------------------------------------------*/
1f061d
@@ -27718,7 +27769,7 @@ DisResult disInstr_PPC_WRK (
1f061d
       opc2 = ifieldOPClo10(theInstr);
1f061d
       UInt opc2hi = IFIELD(theInstr, 7, 4);
1f061d
       UInt opc2lo = IFIELD(theInstr, 3, 3);
1f061d
-      UInt vsxOpc2 = get_VSX60_opc2(opc2);
1f061d
+      UInt vsxOpc2;
1f061d
 
1f061d
       if (( opc2hi == 13 ) && ( opc2lo == 5)) { //xvtstdcsp
1f061d
          if (dis_vxs_misc(theInstr, 0x354, allow_isa_3_0))
1f061d
@@ -27747,6 +27798,8 @@ DisResult disInstr_PPC_WRK (
1f061d
          goto decode_failure;
1f061d
       }
1f061d
 
1f061d
+      vsxOpc2 = get_VSX60_opc2(opc2, theInstr);
1f061d
+
1f061d
       switch (vsxOpc2) {
1f061d
          case 0x8: case 0x28: case 0x48: case 0xc8: // xxsldwi, xxpermdi, xxmrghw, xxmrglw
1f061d
          case 0x068: case 0xE8:  // xxperm, xxpermr
1f061d
@@ -27851,12 +27904,12 @@ DisResult disInstr_PPC_WRK (
1f061d
             if (dis_vx_conv(theInstr, vsxOpc2)) goto decode_success;
1f061d
             goto decode_failure;
1f061d
 
1f061d
-         case 0x18C: case 0x38C: // xvcmpeqdp[.]
1f061d
-         case 0x10C: case 0x30C: // xvcmpeqsp[.]
1f061d
-         case 0x14C: case 0x34C: // xvcmpgesp[.]
1f061d
-         case 0x12C: case 0x32C: // xvcmpgtsp[.]
1f061d
-         case 0x1CC: case 0x3CC: // xvcmpgedp[.]
1f061d
-         case 0x1AC: case 0x3AC: // xvcmpgtdp[.]
1f061d
+         case 0x18C:             // xvcmpeqdp[.]
1f061d
+         case 0x10C:             // xvcmpeqsp[.]
1f061d
+         case 0x14C:             // xvcmpgesp[.]
1f061d
+         case 0x12C:             // xvcmpgtsp[.]
1f061d
+         case 0x1CC:             // xvcmpgedp[.]
1f061d
+         case 0x1AC:             // xvcmpgtdp[.]
1f061d
              if (dis_vvec_cmp(theInstr, vsxOpc2)) goto decode_success;
1f061d
              goto decode_failure;
1f061d