]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Enough SSE2 instructions to sink a small ship. And that's not even
authorJulian Seward <jseward@acm.org>
Tue, 10 May 2005 22:42:54 +0000 (22:42 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 10 May 2005 22:42:54 +0000 (22:42 +0000)
half of them.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1178

VEX/priv/guest-amd64/toIR.c
VEX/priv/host-amd64/hdefs.c
VEX/priv/host-amd64/hdefs.h
VEX/priv/host-amd64/isel.c

index 346c86a07edbc8fd35c9df06be6f3bf341348605..7b8400597b2a9ef5605d7c43efd743acefd5b699 100644 (file)
@@ -1419,16 +1419,16 @@ static Int xmmGuestRegOffset ( UInt xmmreg )
    }
 }
 
-//.. /* Lanes of vector registers are always numbered from zero being the
-//..    least significant lane (rightmost in the register).  */
-//.. 
-//.. static Int xmmGuestRegLane16offset ( UInt xmmreg, Int laneno )
-//.. {
-//..    /* Correct for little-endian host only. */
-//..    vassert(!host_is_bigendian);
-//..    vassert(laneno >= 0 && laneno < 8);
-//..    return xmmGuestRegOffset( xmmreg ) + 2 * laneno;
-//.. }
+/* Lanes of vector registers are always numbered from zero being the
+   least significant lane (rightmost in the register).  */
+
+static Int xmmGuestRegLane16offset ( UInt xmmreg, Int laneno )
+{
+   /* Correct for little-endian host only. */
+   vassert(!host_is_bigendian);
+   vassert(laneno >= 0 && laneno < 8);
+   return xmmGuestRegOffset( xmmreg ) + 2 * laneno;
+}
 
 static Int xmmGuestRegLane32offset ( UInt xmmreg, Int laneno )
 {
@@ -1512,11 +1512,11 @@ static void putXMMRegLane32 ( UInt xmmreg, Int laneno, IRExpr* e )
    stmt( IRStmt_Put( xmmGuestRegLane32offset(xmmreg,laneno), e ) );
 }
 
-//.. static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e )
-//.. {
-//..    vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16);
-//..    stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );
-//.. }
+static void putXMMRegLane16 ( UInt xmmreg, Int laneno, IRExpr* e )
+{
+   vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I16);
+   stmt( IRStmt_Put( xmmGuestRegLane16offset(xmmreg,laneno), e ) );
+}
 
 static IRExpr* mkV128 ( UShort mask )
 {
@@ -9301,11 +9301,12 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
       goto decode_success;
    }
 
-//..    /* 66 0F C2 = CMPPD -- 64Fx2 comparison from R/M to R */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC2) {
-//..       delta = dis_SSEcmp_E_to_G( sorb, delta+2, "cmppd", True, 8 );
-//..       goto decode_success;
-//..    }
+   /* 66 0F C2 = CMPPD -- 64Fx2 comparison from R/M to R */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xC2) {
+      delta = dis_SSEcmp_E_to_G( pfx, delta+2, "cmppd", True, 8 );
+      goto decode_success;
+   }
 
    /* F2 0F C2 = CMPSD -- 64F0x2 comparison from R/M to R */
    if (haveF2no66noF3(pfx) && sz == 4
@@ -10018,7 +10019,8 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
    /* 66 0F 6E = MOVD from ireg32/m32 to xmm lo 1/4, zeroing high 3/4 of xmm. */
    /*              or from ireg64/m64 to xmm lo 1/2, zeroing high 1/2 of xmm. */
    if (have66noF2noF3(pfx) && insn[0] == 0x0F && insn[1] == 0x6E) {
-      vassert(sz == 4 || sz == 8);
+      vassert(sz == 2 || sz == 8);
+      if (sz == 2) sz = 4;
       modrm = getUChar(delta+2);
       if (epartIsReg(modrm)) {
          delta += 2+1;
@@ -10444,12 +10446,13 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
       goto decode_success;
    }
 
-//..    /* 66 0F 51 = SQRTPD -- approx sqrt 64Fx2 from R/M to R */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x51) {
-//..       delta = dis_SSE_E_to_G_unary_all( sorb, delta+2, 
-//..                                         "sqrtpd", Iop_Sqrt64Fx2 );
-//..       goto decode_success;
-//..    }
+   /* 66 0F 51 = SQRTPD -- approx sqrt 64Fx2 from R/M to R */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x51) {
+      delta = dis_SSE_E_to_G_unary_all( pfx, delta+2, 
+                                        "sqrtpd", Iop_Sqrt64Fx2 );
+      goto decode_success;
+   }
 
    /* F2 0F 51 = SQRTSD -- approx sqrt 64F0x2 from R/M to R */
    if (haveF2no66noF3(pfx) && insn[0] == 0x0F && insn[1] == 0x51) {
@@ -10522,45 +10525,51 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
    }
 
    /* 66 0F 57 = XORPD -- G = G xor E */
-   if (have66noF2noF3(pfx) && insn[0] == 0x0F && insn[1] == 0x57) {
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x57) {
       delta = dis_SSE_E_to_G_all( pfx, delta+2, "xorpd", Iop_XorV128 );
       goto decode_success;
    }
 
-//..    /* 66 0F 6B = PACKSSDW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6B) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "packssdw", Iop_QNarrow32Sx4, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 63 = PACKSSWB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x63) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "packsswb", Iop_QNarrow16Sx8, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 67 = PACKUSWB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x67) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "packuswb", Iop_QNarrow16Ux8, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F FC = PADDB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xFC) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "paddb", Iop_Add8x16, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F FE = PADDD */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xFE) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "paddd", Iop_Add32x4, False );
-//..       goto decode_success;
-//..    }
+   /* 66 0F 6B = PACKSSDW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x6B) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "packssdw", Iop_QNarrow32Sx4, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 63 = PACKSSWB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x63) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "packsswb", Iop_QNarrow16Sx8, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 67 = PACKUSWB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x67) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "packuswb", Iop_QNarrow16Ux8, True );
+      goto decode_success;
+   }
+
+   /* 66 0F FC = PADDB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xFC) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "paddb", Iop_Add8x16, False );
+      goto decode_success;
+   }
+
+   /* 66 0F FE = PADDD */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xFE) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "paddd", Iop_Add32x4, False );
+      goto decode_success;
+   }
 
    /* ***--- this is an MMX class insn introduced in SSE2 ---*** */
    /* 0F D4 = PADDQ -- add 64x1 */
@@ -10683,60 +10692,70 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..                                  "pcmpgtw", Iop_CmpGT16Sx8, False );
 //..       goto decode_success;
 //..    }
-//.. 
-//..    /* 66 0F C5 = PEXTRW -- extract 16-bit field from xmm(E) and put 
-//..       zero-extend of it in ireg(G). */
-//..    if (insn[0] == 0x0F && insn[1] == 0xC5) {
-//..       modrm = insn[2];
-//..       if (sz == 2 && epartIsReg(modrm)) {
-//..          t5 = newTemp(Ity_V128);
-//..          t4 = newTemp(Ity_I16);
-//..          assign(t5, getXMMReg(eregOfRM(modrm)));
-//..          breakup128to32s( t5, &t3, &t2, &t1, &t0 );
-//..          switch (insn[3] & 7) {
-//..             case 0:  assign(t4, unop(Iop_32to16,   mkexpr(t0))); break;
-//..             case 1:  assign(t4, unop(Iop_32HIto16, mkexpr(t0))); break;
-//..             case 2:  assign(t4, unop(Iop_32to16,   mkexpr(t1))); break;
-//..             case 3:  assign(t4, unop(Iop_32HIto16, mkexpr(t1))); break;
-//..             case 4:  assign(t4, unop(Iop_32to16,   mkexpr(t2))); break;
-//..             case 5:  assign(t4, unop(Iop_32HIto16, mkexpr(t2))); break;
-//..             case 6:  assign(t4, unop(Iop_32to16,   mkexpr(t3))); break;
-//..             case 7:  assign(t4, unop(Iop_32HIto16, mkexpr(t3))); break;
-//..             default: vassert(0);
-//..          }
-//..          putIReg(4, gregOfRM(modrm), unop(Iop_16Uto32, mkexpr(t4)));
-//..          DIP("pextrw $%d,%s,%s\n",
-//..              (Int)insn[3], nameXMMReg(eregOfRM(modrm)),
-//..                            nameIReg(4,gregOfRM(modrm)));
-//..          delta += 4;
-//..          goto decode_success;
-//..       } 
-//..       /* else fall through */
-//..    }
-//.. 
-//..    /* 66 0F C4 = PINSRW -- get 16 bits from E(mem or low half ireg) and
-//..       put it into the specified lane of xmm(G). */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC4) {
-//..       Int lane;
-//..       t4 = newTemp(Ity_I16);
-//..       modrm = insn[2];
-//.. 
-//..       if (epartIsReg(modrm)) {
-//..          assign(t4, getIReg(2, eregOfRM(modrm)));
-//..          lane = insn[3];
-//..          delta += 2+2;
-//..          DIP("pinsrw $%d,%s,%s\n", (Int)lane, 
-//..                                    nameIReg(2,eregOfRM(modrm)),
-//..                                    nameXMMReg(gregOfRM(modrm)));
-//..       } else {
-//..          /* awaiting test case */
-//..          goto decode_failure;
-//..       }
-//.. 
-//..       putXMMRegLane16( gregOfRM(modrm), lane & 7, mkexpr(t4) );
-//..       goto decode_success;
-//..    }
-//.. 
+
+   /* 66 0F C5 = PEXTRW -- extract 16-bit field from xmm(E) and put 
+      zero-extend of it in ireg(G). */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xC5) {
+      modrm = insn[2];
+      if (epartIsReg(modrm)) {
+         t5 = newTemp(Ity_V128);
+         t4 = newTemp(Ity_I16);
+         assign(t5, getXMMReg(eregOfRexRM(pfx,modrm)));
+         breakup128to32s( t5, &t3, &t2, &t1, &t0 );
+         switch (insn[3] & 7) {
+            case 0:  assign(t4, unop(Iop_32to16,   mkexpr(t0))); break;
+            case 1:  assign(t4, unop(Iop_32HIto16, mkexpr(t0))); break;
+            case 2:  assign(t4, unop(Iop_32to16,   mkexpr(t1))); break;
+            case 3:  assign(t4, unop(Iop_32HIto16, mkexpr(t1))); break;
+            case 4:  assign(t4, unop(Iop_32to16,   mkexpr(t2))); break;
+            case 5:  assign(t4, unop(Iop_32HIto16, mkexpr(t2))); break;
+            case 6:  assign(t4, unop(Iop_32to16,   mkexpr(t3))); break;
+            case 7:  assign(t4, unop(Iop_32HIto16, mkexpr(t3))); break;
+            default: vassert(0);
+         }
+         putIReg32(gregOfRexRM(pfx,modrm), unop(Iop_16Uto32, mkexpr(t4)));
+         DIP("pextrw $%d,%s,%s\n",
+             (Int)insn[3], nameXMMReg(eregOfRexRM(pfx,modrm)),
+                           nameIReg32(gregOfRexRM(pfx,modrm)));
+         delta += 4;
+         goto decode_success;
+      } 
+      /* else fall through */
+      /* note, if memory case is ever filled in, there is 1 byte after
+         amode */
+   }
+
+   /* 66 0F C4 = PINSRW -- get 16 bits from E(mem or low half ireg) and
+      put it into the specified lane of xmm(G). */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xC4) {
+      Int lane;
+      t4 = newTemp(Ity_I16);
+      modrm = insn[2];
+
+      if (epartIsReg(modrm)) {
+         assign(t4, getIReg16(eregOfRexRM(pfx,modrm)));
+         delta += 3+1;
+         lane = insn[3+1-1];
+         DIP("pinsrw $%d,%s,%s\n", (Int)lane, 
+                                   nameIReg16(eregOfRexRM(pfx,modrm)),
+                                   nameXMMReg(gregOfRexRM(pfx,modrm)));
+      } else {
+         addr = disAMode ( &alen, pfx, delta+2, dis_buf, 
+                           1/*byte after the amode*/ );
+         delta += 3+alen;
+         lane = insn[3+alen-1];
+         assign(t4, loadLE(Ity_I16, mkexpr(addr)));
+         DIP("pinsrw $%d,%s,%s\n", (Int)lane,
+                                   dis_buf,
+                                   nameXMMReg(gregOfRexRM(pfx,modrm)));
+     }
+
+      putXMMRegLane16( gregOfRexRM(pfx,modrm), lane & 7, mkexpr(t4) );
+      goto decode_success;
+   }
+
 //..    /* 66 0F EE = PMAXSW -- 16x8 signed max */
 //..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xEE) {
 //..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
@@ -11036,64 +11055,69 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..       delta = dis_SSE_shiftG_byE( sorb, delta+2, "pslld", Iop_ShlN32x4 );
 //..       goto decode_success;
 //..    }
-//.. 
-//..    /* 66 0F 73 /7 ib = PSLLDQ by immediate */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x73
-//..        && epartIsReg(insn[2])
-//..        && gregOfRM(insn[2]) == 7) {
-//..       IRTemp sV, dV, hi64, lo64, hi64r, lo64r;
-//..       Int    imm = (Int)insn[3];
-//..       Int    reg = eregOfRM(insn[2]);
-//..       DIP("pslldq $%d,%s\n", imm, nameXMMReg(reg));
-//..       vassert(imm >= 0 && imm <= 255);
-//..       delta += 4;
-//.. 
-//..       sV    = newTemp(Ity_V128);
-//..       dV    = newTemp(Ity_V128);
-//..       hi64  = newTemp(Ity_I64);
-//..       lo64  = newTemp(Ity_I64);
-//..       hi64r = newTemp(Ity_I64);
-//..       lo64r = newTemp(Ity_I64);
-//.. 
-//..       if (imm >= 16) {
-//..          vassert(0); /* awaiting test case */
-//..          putXMMReg(reg, mkV128(0x0000));
-//..          goto decode_success;
-//..       }
-//.. 
-//..       assign( sV, getXMMReg(reg) );
-//..       assign( hi64, unop(Iop_128HIto64, mkexpr(sV)) );
-//..       assign( lo64, unop(Iop_128to64, mkexpr(sV)) );
-//.. 
-//..       if (imm == 8) {
-//..          assign( lo64r, mkU64(0) );
-//..          assign( hi64r, mkexpr(lo64) );
-//..       }
-//..       else
-//..       if (imm > 8) {
-//..          vassert(0); /* awaiting test case */
-//..          assign( lo64r, mkU64(0) );
-//..          assign( hi64r, binop( Iop_Shl64, 
-//..                                mkexpr(lo64),
-//..                                mkU8( 8*(imm-8) ) ));
-//..       } else {
-//..          assign( lo64r, binop( Iop_Shl64, 
-//..                                mkexpr(lo64),
-//..                                mkU8(8 * imm) ));
-//..          assign( hi64r, 
-//..                  binop( Iop_Or64,
-//..                         binop(Iop_Shl64, mkexpr(hi64), 
-//..                                          mkU8(8 * imm)),
-//..                         binop(Iop_Shr64, mkexpr(lo64),
-//..                                          mkU8(8 * (8 - imm)) )
-//..                       )
-//..                );
-//..       }
-//..       assign( dV, binop(Iop_64HLto128, mkexpr(hi64r), mkexpr(lo64r)) );
-//..       putXMMReg(reg, mkexpr(dV));
-//..       goto decode_success;
-//..    }
-//.. 
+
+   /* 66 0F 73 /7 ib = PSLLDQ by immediate */
+   /* note, if mem case ever filled in, 1 byte after amode */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x73
+       && epartIsReg(insn[2])
+       && gregLO3ofRM(insn[2]) == 7) {
+      IRTemp sV, dV, hi64, lo64, hi64r, lo64r;
+      Int    imm = (Int)insn[3];
+      Int    reg = eregOfRexRM(pfx,insn[2]);
+      DIP("pslldq $%d,%s\n", imm, nameXMMReg(reg));
+      vassert(imm >= 0 && imm <= 255);
+      delta += 4;
+
+      sV    = newTemp(Ity_V128);
+      dV    = newTemp(Ity_V128);
+      hi64  = newTemp(Ity_I64);
+      lo64  = newTemp(Ity_I64);
+      hi64r = newTemp(Ity_I64);
+      lo64r = newTemp(Ity_I64);
+
+      if (imm >= 16) {
+         putXMMReg(reg, mkV128(0x0000));
+         goto decode_success;
+      }
+
+      assign( sV, getXMMReg(reg) );
+      assign( hi64, unop(Iop_V128HIto64, mkexpr(sV)) );
+      assign( lo64, unop(Iop_V128to64, mkexpr(sV)) );
+
+      if (imm == 0) {
+         assign( lo64r, mkexpr(lo64) );
+         assign( hi64r, mkexpr(hi64) );
+      }
+      else
+      if (imm == 8) {
+         assign( lo64r, mkU64(0) );
+         assign( hi64r, mkexpr(lo64) );
+      }
+      else
+      if (imm > 8) {
+         assign( lo64r, mkU64(0) );
+         assign( hi64r, binop( Iop_Shl64, 
+                               mkexpr(lo64),
+                               mkU8( 8*(imm-8) ) ));
+      } else {
+         assign( lo64r, binop( Iop_Shl64, 
+                               mkexpr(lo64),
+                               mkU8(8 * imm) ));
+         assign( hi64r, 
+                 binop( Iop_Or64,
+                        binop(Iop_Shl64, mkexpr(hi64), 
+                                         mkU8(8 * imm)),
+                        binop(Iop_Shr64, mkexpr(lo64),
+                                         mkU8(8 * (8 - imm)) )
+                      )
+               );
+      }
+      assign( dV, binop(Iop_64HLtoV128, mkexpr(hi64r), mkexpr(lo64r)) );
+      putXMMReg(reg, mkexpr(dV));
+      goto decode_success;
+   }
+
 //..    /* 66 0F 73 /6 ib = PSLLQ by immediate */
 //..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x73
 //..        && epartIsReg(insn[2])
@@ -11163,64 +11187,69 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..       delta = dis_SSE_shiftG_byE( sorb, delta+2, "psrld", Iop_ShrN32x4 );
 //..       goto decode_success;
 //..    }
-//.. 
-//..    /* 66 0F 73 /3 ib = PSRLDQ by immediate */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x73
-//..        && epartIsReg(insn[2])
-//..        && gregOfRM(insn[2]) == 3) {
-//..       IRTemp sV, dV, hi64, lo64, hi64r, lo64r;
-//..       Int    imm = (Int)insn[3];
-//..       Int    reg = eregOfRM(insn[2]);
-//..       DIP("psrldq $%d,%s\n", imm, nameXMMReg(reg));
-//..       vassert(imm >= 0 && imm <= 255);
-//..       delta += 4;
-//.. 
-//..       sV    = newTemp(Ity_V128);
-//..       dV    = newTemp(Ity_V128);
-//..       hi64  = newTemp(Ity_I64);
-//..       lo64  = newTemp(Ity_I64);
-//..       hi64r = newTemp(Ity_I64);
-//..       lo64r = newTemp(Ity_I64);
-//.. 
-//..       if (imm >= 16) {
-//..          vassert(0); /* awaiting test case */
-//..          putXMMReg(reg, mkV128(0x0000));
-//..          goto decode_success;
-//..       }
-//.. 
-//..       assign( sV, getXMMReg(reg) );
-//..       assign( hi64, unop(Iop_128HIto64, mkexpr(sV)) );
-//..       assign( lo64, unop(Iop_128to64, mkexpr(sV)) );
-//.. 
-//..       if (imm == 8) {
-//..          assign( hi64r, mkU64(0) );
-//..          assign( lo64r, mkexpr(hi64) );
-//..       }
-//..       else 
-//..       if (imm > 8) {
-//..          vassert(0); /* awaiting test case */
-//..          assign( hi64r, mkU64(0) );
-//..          assign( lo64r, binop( Iop_Shr64, 
-//..                                mkexpr(hi64),
-//..                                mkU8( 8*(imm-8) ) ));
-//..       } else {
-//..          assign( hi64r, binop( Iop_Shr64, 
-//..                                mkexpr(hi64),
-//..                                mkU8(8 * imm) ));
-//..          assign( lo64r, 
-//..                  binop( Iop_Or64,
-//..                         binop(Iop_Shr64, mkexpr(lo64), 
-//..                                          mkU8(8 * imm)),
-//..                         binop(Iop_Shl64, mkexpr(hi64),
-//..                                          mkU8(8 * (8 - imm)) )
-//..                       )
-//..                );
-//..       }
-//.. 
-//..       assign( dV, binop(Iop_64HLto128, mkexpr(hi64r), mkexpr(lo64r)) );
-//..       putXMMReg(reg, mkexpr(dV));
-//..       goto decode_success;
-//..    }
+
+   /* 66 0F 73 /3 ib = PSRLDQ by immediate */
+   /* note, if mem case ever filled in, 1 byte after amode */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x73
+       && epartIsReg(insn[2])
+       && gregLO3ofRM(insn[2]) == 3) {
+      IRTemp sV, dV, hi64, lo64, hi64r, lo64r;
+      Int    imm = (Int)insn[3];
+      Int    reg = eregOfRexRM(pfx,insn[2]);
+      DIP("psrldq $%d,%s\n", imm, nameXMMReg(reg));
+      vassert(imm >= 0 && imm <= 255);
+      delta += 4;
+
+      sV    = newTemp(Ity_V128);
+      dV    = newTemp(Ity_V128);
+      hi64  = newTemp(Ity_I64);
+      lo64  = newTemp(Ity_I64);
+      hi64r = newTemp(Ity_I64);
+      lo64r = newTemp(Ity_I64);
+
+      if (imm >= 16) {
+         putXMMReg(reg, mkV128(0x0000));
+         goto decode_success;
+      }
+
+      assign( sV, getXMMReg(reg) );
+      assign( hi64, unop(Iop_V128HIto64, mkexpr(sV)) );
+      assign( lo64, unop(Iop_V128to64, mkexpr(sV)) );
+
+      if (imm == 0) {
+         assign( lo64r, mkexpr(lo64) );
+         assign( hi64r, mkexpr(hi64) );
+      }
+      else
+      if (imm == 8) {
+         assign( hi64r, mkU64(0) );
+         assign( lo64r, mkexpr(hi64) );
+      }
+      else 
+      if (imm > 8) {
+         assign( hi64r, mkU64(0) );
+         assign( lo64r, binop( Iop_Shr64, 
+                               mkexpr(hi64),
+                               mkU8( 8*(imm-8) ) ));
+      } else {
+         assign( hi64r, binop( Iop_Shr64, 
+                               mkexpr(hi64),
+                               mkU8(8 * imm) ));
+         assign( lo64r, 
+                 binop( Iop_Or64,
+                        binop(Iop_Shr64, mkexpr(lo64), 
+                                         mkU8(8 * imm)),
+                        binop(Iop_Shl64, mkexpr(hi64),
+                                         mkU8(8 * (8 - imm)) )
+                      )
+               );
+      }
+
+      assign( dV, binop(Iop_64HLtoV128, mkexpr(hi64r), mkexpr(lo64r)) );
+      putXMMReg(reg, mkexpr(dV));
+      goto decode_success;
+   }
 
    /* 66 0F 73 /2 ib = PSRLQ by immediate */
    if (have66noF2noF3(pfx) && sz == 2 
@@ -11249,22 +11278,24 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
 //..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xD1) {
 //..       delta = dis_SSE_shiftG_byE( sorb, delta+2, "psrlw", Iop_ShrN16x8 );
 //..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F F8 = PSUBB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xF8) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubb", Iop_Sub8x16, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F FA = PSUBD */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xFA) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubd", Iop_Sub32x4, False );
-//..       goto decode_success;
 //..    }
 
+   /* 66 0F F8 = PSUBB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xF8) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubb", Iop_Sub8x16, False );
+      goto decode_success;
+   }
+
+   /* 66 0F FA = PSUBD */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xFA) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubd", Iop_Sub32x4, False );
+      goto decode_success;
+   }
+
    /* ***--- this is an MMX class insn introduced in SSE2 ---*** */
    /* 0F FB = PSUBQ -- sub 64x1 */
    if (haveNo66noF2noF3(pfx) && sz == 4 
@@ -11283,104 +11314,117 @@ DisResult disInstr ( /*IN*/  Bool       resteerOK,
       goto decode_success;
    }
 
-//..    /* 66 0F F9 = PSUBW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xF9) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubw", Iop_Sub16x8, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F E8 = PSUBSB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xE8) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubsb", Iop_QSub8Sx16, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F E9 = PSUBSW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xE9) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubsw", Iop_QSub16Sx8, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F D8 = PSUBSB */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xD8) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubusb", Iop_QSub8Ux16, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F D9 = PSUBSW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xD9) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "psubusw", Iop_QSub16Ux8, False );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 68 = PUNPCKHBW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x68) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpckhbw",
-//..                                  Iop_InterleaveHI8x16, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 6A = PUNPCKHDQ */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6A) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpckhdq",
-//..                                  Iop_InterleaveHI32x4, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 6D = PUNPCKHQDQ */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6D) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpckhqdq",
-//..                                  Iop_InterleaveHI64x2, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 69 = PUNPCKHWD */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x69) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpckhwd",
-//..                                  Iop_InterleaveHI16x8, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 60 = PUNPCKLBW */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x60) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpcklbw",
-//..                                  Iop_InterleaveLO8x16, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 62 = PUNPCKLDQ */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x62) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpckldq",
-//..                                  Iop_InterleaveLO32x4, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 6C = PUNPCKLQDQ */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x6C) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpcklqdq",
-//..                                  Iop_InterleaveLO64x2, True );
-//..       goto decode_success;
-//..    }
-//.. 
-//..    /* 66 0F 61 = PUNPCKLWD */
-//..    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0x61) {
-//..       delta = dis_SSEint_E_to_G( sorb, delta+2, 
-//..                                  "punpcklwd",
-//..                                  Iop_InterleaveLO16x8, True );
-//..       goto decode_success;
-//..    }
+   /* 66 0F F9 = PSUBW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xF9) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubw", Iop_Sub16x8, False );
+      goto decode_success;
+   }
+
+   /* 66 0F E8 = PSUBSB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xE8) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubsb", Iop_QSub8Sx16, False );
+      goto decode_success;
+   }
+
+   /* 66 0F E9 = PSUBSW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xE9) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubsw", Iop_QSub16Sx8, False );
+      goto decode_success;
+   }
+
+   /* 66 0F D8 = PSUBSB */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xD8) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubusb", Iop_QSub8Ux16, False );
+      goto decode_success;
+   }
+
+   /* 66 0F D9 = PSUBSW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0xD9) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "psubusw", Iop_QSub16Ux8, False );
+      goto decode_success;
+   }
+
+   /* 66 0F 68 = PUNPCKHBW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x68) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpckhbw",
+                                 Iop_InterleaveHI8x16, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6A = PUNPCKHDQ */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x6A) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpckhdq",
+                                 Iop_InterleaveHI32x4, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6D = PUNPCKHQDQ */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x6D) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpckhqdq",
+                                 Iop_InterleaveHI64x2, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 69 = PUNPCKHWD */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x69) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpckhwd",
+                                 Iop_InterleaveHI16x8, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 60 = PUNPCKLBW */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x60) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpcklbw",
+                                 Iop_InterleaveLO8x16, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 62 = PUNPCKLDQ */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x62) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpckldq",
+                                 Iop_InterleaveLO32x4, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 6C = PUNPCKLQDQ */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x6C) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpcklqdq",
+                                 Iop_InterleaveLO64x2, True );
+      goto decode_success;
+   }
+
+   /* 66 0F 61 = PUNPCKLWD */
+   if (have66noF2noF3(pfx) && sz == 2 
+       && insn[0] == 0x0F && insn[1] == 0x61) {
+      delta = dis_SSEint_E_to_G( pfx, delta+2, 
+                                 "punpcklwd",
+                                 Iop_InterleaveLO16x8, True );
+      goto decode_success;
+   }
 
    /* 66 0F EF = PXOR */
    if (have66noF2noF3(pfx) && sz == 2 
index c6120eaa3d516477d74a20e90b2c67425c2a5f9e..1505efa51056479252610b1e66974823e7374d10 100644 (file)
@@ -603,22 +603,22 @@ HChar* showAMD64SseOp ( AMD64SseOp op ) {
       case Asse_OR:       return "or";
       case Asse_XOR:      return "xor";
       case Asse_ANDN:     return "andn";
-//..       case Xsse_ADD8:     return "paddb";
-//..       case Xsse_ADD16:    return "paddw";
-//..       case Xsse_ADD32:    return "paddd";
+      case Asse_ADD8:     return "paddb";
+      case Asse_ADD16:    return "paddw";
+      case Asse_ADD32:    return "paddd";
       case Asse_ADD64:    return "paddq";
 //..       case Xsse_QADD8U:   return "paddusb";
 //..       case Xsse_QADD16U:  return "paddusw";
 //..       case Xsse_QADD8S:   return "paddsb";
 //..       case Xsse_QADD16S:  return "paddsw";
-//..       case Xsse_SUB8:     return "psubb";
-//..       case Xsse_SUB16:    return "psubw";
-//..       case Xsse_SUB32:    return "psubd";
+      case Asse_SUB8:     return "psubb";
+      case Asse_SUB16:    return "psubw";
+      case Asse_SUB32:    return "psubd";
       case Asse_SUB64:    return "psubq";
-//..       case Xsse_QSUB8U:   return "psubusb";
-//..       case Xsse_QSUB16U:  return "psubusw";
-//..       case Xsse_QSUB8S:   return "psubsb";
-//..       case Xsse_QSUB16S:  return "psubsw";
+      case Asse_QSUB8U:   return "psubusb";
+      case Asse_QSUB16U:  return "psubusw";
+      case Asse_QSUB8S:   return "psubsb";
+      case Asse_QSUB16S:  return "psubsw";
 //..       case Xsse_MUL16:    return "pmullw";
 //..       case Xsse_MULHI16U: return "pmulhuw";
 //..       case Xsse_MULHI16S: return "pmulhw";
@@ -642,17 +642,17 @@ HChar* showAMD64SseOp ( AMD64SseOp op ) {
       case Asse_SHR64:    return "psrlq";
 //..       case Xsse_SAR16:    return "psraw";
 //..       case Xsse_SAR32:    return "psrad";
-//..       case Xsse_PACKSSD:  return "packssdw";
-//..       case Xsse_PACKSSW:  return "packsswb";
-//..       case Xsse_PACKUSW:  return "packuswb";
-//..       case Xsse_UNPCKHB:  return "punpckhb";
-//..       case Xsse_UNPCKHW:  return "punpckhw";
-//..       case Xsse_UNPCKHD:  return "punpckhd";
-//..       case Xsse_UNPCKHQ:  return "punpckhq";
-//..       case Xsse_UNPCKLB:  return "punpcklb";
-//..       case Xsse_UNPCKLW:  return "punpcklw";
-//..       case Xsse_UNPCKLD:  return "punpckld";
-//..       case Xsse_UNPCKLQ:  return "punpcklq";
+      case Asse_PACKSSD:  return "packssdw";
+      case Asse_PACKSSW:  return "packsswb";
+      case Asse_PACKUSW:  return "packuswb";
+      case Asse_UNPCKHB:  return "punpckhb";
+      case Asse_UNPCKHW:  return "punpckhw";
+      case Asse_UNPCKHD:  return "punpckhd";
+      case Asse_UNPCKHQ:  return "punpckhq";
+      case Asse_UNPCKLB:  return "punpcklb";
+      case Asse_UNPCKLW:  return "punpcklw";
+      case Asse_UNPCKLD:  return "punpckld";
+      case Asse_UNPCKLQ:  return "punpcklq";
       default: vpanic("showAMD64SseOp");
    }
 }
@@ -3228,11 +3228,11 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
          case Asse_MULF:   *p++ = 0x59; break;
 //..          case Xsse_RCPF:   *p++ = 0x53; break;
 //..          case Xsse_RSQRTF: *p++ = 0x52; break;
-//..          case Xsse_SQRTF:  *p++ = 0x51; break;
+         case Asse_SQRTF:  *p++ = 0x51; break;
          case Asse_SUBF:   *p++ = 0x5C; break;
-//..          case Xsse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break;
-//..          case Xsse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break;
-//..          case Xsse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break;
+         case Asse_CMPEQF: *p++ = 0xC2; xtra = 0x100; break;
+         case Asse_CMPLTF: *p++ = 0xC2; xtra = 0x101; break;
+         case Asse_CMPLEF: *p++ = 0xC2; xtra = 0x102; break;
          default: goto bad;
       }
       p = doAMode_R(p, vreg2ireg(i->Ain.Sse64Fx2.dst),
@@ -3310,12 +3310,12 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
          case Asse_XOR:                XX(rex); XX(0x0F); XX(0x57); break;
          case Asse_AND:                XX(rex); XX(0x0F); XX(0x54); break;
          case Asse_ANDN:               XX(rex); XX(0x0F); XX(0x55); break;
-//..          case Xsse_PACKSSD:  XX(0x66); XX(rex); XX(0x0F); XX(0x6B); break;
-//..          case Xsse_PACKSSW:  XX(0x66); XX(rex); XX(0x0F); XX(0x63); break;
-//..          case Xsse_PACKUSW:  XX(0x66); XX(rex); XX(0x0F); XX(0x67); break;
-//..          case Xsse_ADD8:     XX(0x66); XX(rex); XX(0x0F); XX(0xFC); break;
+         case Asse_PACKSSD:  XX(0x66); XX(rex); XX(0x0F); XX(0x6B); break;
+         case Asse_PACKSSW:  XX(0x66); XX(rex); XX(0x0F); XX(0x63); break;
+         case Asse_PACKUSW:  XX(0x66); XX(rex); XX(0x0F); XX(0x67); break;
+         case Asse_ADD8:     XX(0x66); XX(rex); XX(0x0F); XX(0xFC); break;
 //..          case Xsse_ADD16:    XX(0x66); XX(rex); XX(0x0F); XX(0xFD); break;
-//..          case Xsse_ADD32:    XX(0x66); XX(rex); XX(0x0F); XX(0xFE); break;
+         case Asse_ADD32:    XX(0x66); XX(rex); XX(0x0F); XX(0xFE); break;
          case Asse_ADD64:    XX(0x66); XX(rex); XX(0x0F); XX(0xD4); break;
 //..          case Xsse_QADD8S:   XX(0x66); XX(rex); XX(0x0F); XX(0xEC); break;
 //..          case Xsse_QADD16S:  XX(0x66); XX(rex); XX(0x0F); XX(0xED); break;
@@ -3344,22 +3344,22 @@ Int emit_AMD64Instr ( UChar* buf, Int nbuf, AMD64Instr* i )
 //..          case Xsse_SHR16:    XX(0x66); XX(rex); XX(0x0F); XX(0xD1); break;
 //..          case Xsse_SHR32:    XX(0x66); XX(rex); XX(0x0F); XX(0xD2); break;
          case Asse_SHR64:    XX(0x66); XX(rex); XX(0x0F); XX(0xD3); break;
-//..          case Xsse_SUB8:     XX(0x66); XX(rex); XX(0x0F); XX(0xF8); break;
-//..          case Xsse_SUB16:    XX(0x66); XX(rex); XX(0x0F); XX(0xF9); break;
-//..          case Xsse_SUB32:    XX(0x66); XX(rex); XX(0x0F); XX(0xFA); break;
+         case Asse_SUB8:     XX(0x66); XX(rex); XX(0x0F); XX(0xF8); break;
+         case Asse_SUB16:    XX(0x66); XX(rex); XX(0x0F); XX(0xF9); break;
+         case Asse_SUB32:    XX(0x66); XX(rex); XX(0x0F); XX(0xFA); break;
          case Asse_SUB64:    XX(0x66); XX(rex); XX(0x0F); XX(0xFB); break;
-//..          case Xsse_QSUB8S:   XX(0x66); XX(rex); XX(0x0F); XX(0xE8); break;
-//..          case Xsse_QSUB16S:  XX(0x66); XX(rex); XX(0x0F); XX(0xE9); break;
-//..          case Xsse_QSUB8U:   XX(0x66); XX(rex); XX(0x0F); XX(0xD8); break;
-//..          case Xsse_QSUB16U:  XX(0x66); XX(rex); XX(0x0F); XX(0xD9); break;
-//..          case Xsse_UNPCKHB:  XX(0x66); XX(rex); XX(0x0F); XX(0x68); break;
-//..          case Xsse_UNPCKHW:  XX(0x66); XX(rex); XX(0x0F); XX(0x69); break;
-//..          case Xsse_UNPCKHD:  XX(0x66); XX(rex); XX(0x0F); XX(0x6A); break;
-//..          case Xsse_UNPCKHQ:  XX(0x66); XX(rex); XX(0x0F); XX(0x6D); break;
-//..          case Xsse_UNPCKLB:  XX(0x66); XX(rex); XX(0x0F); XX(0x60); break;
-//..          case Xsse_UNPCKLW:  XX(0x66); XX(rex); XX(0x0F); XX(0x61); break;
-//..          case Xsse_UNPCKLD:  XX(0x66); XX(rex); XX(0x0F); XX(0x62); break;
-//..          case Xsse_UNPCKLQ:  XX(0x66); XX(rex); XX(0x0F); XX(0x6C); break;
+         case Asse_QSUB8S:   XX(0x66); XX(rex); XX(0x0F); XX(0xE8); break;
+         case Asse_QSUB16S:  XX(0x66); XX(rex); XX(0x0F); XX(0xE9); break;
+         case Asse_QSUB8U:   XX(0x66); XX(rex); XX(0x0F); XX(0xD8); break;
+         case Asse_QSUB16U:  XX(0x66); XX(rex); XX(0x0F); XX(0xD9); break;
+         case Asse_UNPCKHB:  XX(0x66); XX(rex); XX(0x0F); XX(0x68); break;
+         case Asse_UNPCKHW:  XX(0x66); XX(rex); XX(0x0F); XX(0x69); break;
+         case Asse_UNPCKHD:  XX(0x66); XX(rex); XX(0x0F); XX(0x6A); break;
+         case Asse_UNPCKHQ:  XX(0x66); XX(rex); XX(0x0F); XX(0x6D); break;
+         case Asse_UNPCKLB:  XX(0x66); XX(rex); XX(0x0F); XX(0x60); break;
+         case Asse_UNPCKLW:  XX(0x66); XX(rex); XX(0x0F); XX(0x61); break;
+         case Asse_UNPCKLD:  XX(0x66); XX(rex); XX(0x0F); XX(0x62); break;
+         case Asse_UNPCKLQ:  XX(0x66); XX(rex); XX(0x0F); XX(0x6C); break;
          default: goto bad;
       }
       p = doAMode_R(p, vreg2ireg(i->Ain.SseReRg.dst),
index 9df3f3ea0c13f217ba73397b9f12a0e0906f5e41..ac3bc6f90bac590263351cda4a7e6e2e8d182160 100644 (file)
@@ -323,14 +323,12 @@ typedef
       /* Bitwise */
       Asse_AND, Asse_OR, Asse_XOR, Asse_ANDN,
 //..       /* Integer binary */
-//..       Xsse_ADD8,   Xsse_ADD16,   Xsse_ADD32,
-      Asse_ADD64,
+      Asse_ADD8, Asse_ADD16, Asse_ADD32, Asse_ADD64,
 //..       Xsse_QADD8U, Xsse_QADD16U,
 //..       Xsse_QADD8S, Xsse_QADD16S,
-//..       Xsse_SUB8,   Xsse_SUB16,   Xsse_SUB32,
-      Asse_SUB64,
-//..       Xsse_QSUB8U, Xsse_QSUB16U,
-//..       Xsse_QSUB8S, Xsse_QSUB16S,
+      Asse_SUB8, Asse_SUB16, Asse_SUB32, Asse_SUB64,
+      Asse_QSUB8U, Asse_QSUB16U,
+      Asse_QSUB8S, Asse_QSUB16S,
 //..       Xsse_MUL16,
 //..       Xsse_MULHI16U,
 //..       Xsse_MULHI16S,
@@ -346,9 +344,9 @@ typedef
 //..       Xsse_SHR16, Xsse_SHR32, 
       Asse_SHR64,
 //..       Xsse_SAR16, Xsse_SAR32, 
-//..       Xsse_PACKSSD, Xsse_PACKSSW, Xsse_PACKUSW,
-//..       Xsse_UNPCKHB, Xsse_UNPCKHW, Xsse_UNPCKHD, Xsse_UNPCKHQ,
-//..       Xsse_UNPCKLB, Xsse_UNPCKLW, Xsse_UNPCKLD, Xsse_UNPCKLQ
+      Asse_PACKSSD, Asse_PACKSSW, Asse_PACKUSW,
+      Asse_UNPCKHB, Asse_UNPCKHW, Asse_UNPCKHD, Asse_UNPCKHQ,
+      Asse_UNPCKLB, Asse_UNPCKLW, Asse_UNPCKLD, Asse_UNPCKLQ
    }
    AMD64SseOp;
 
index b760e6ac9e408a62c156a97d868fcf19c9d53b65..72e74a345ed0b7d4c630d05bd1ee81fed82cb876 100644 (file)
@@ -3191,16 +3191,15 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       }
 
 //..       case Iop_Recip64Fx2: op = Xsse_RCPF;   goto do_64Fx2_unary;
-//..       case Iop_RSqrt64Fx2: op = Xsse_RSQRTF; goto do_64Fx2_unary;
-//..       case Iop_Sqrt64Fx2:  op = Xsse_SQRTF;  goto do_64Fx2_unary;
-//..       do_64Fx2_unary:
-//..       {
-//..          HReg arg = iselVecExpr(env, e->Iex.Unop.arg);
-//..          HReg dst = newVRegV(env);
-//..          REQUIRE_SSE2;
-//..          addInstr(env, X86Instr_Sse64Fx2(op, arg, dst));
-//..          return dst;
-//..       }
+//..       case Iop_RSqrt64Fx2: op = Asse_RSQRTF; goto do_64Fx2_unary;
+      case Iop_Sqrt64Fx2:  op = Asse_SQRTF;  goto do_64Fx2_unary;
+      do_64Fx2_unary:
+      {
+         HReg arg = iselVecExpr(env, e->Iex.Unop.arg);
+         HReg dst = newVRegV(env);
+         addInstr(env, AMD64Instr_Sse64Fx2(op, arg, dst));
+         return dst;
+      }
 
       case Iop_Recip32F0x4: op = Asse_RCPF;   goto do_32F0x4_unary;
       case Iop_RSqrt32F0x4: op = Asse_RSQRTF; goto do_32F0x4_unary;
@@ -3317,9 +3316,9 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          return dst;
       }
 
-//..       case Iop_CmpEQ64Fx2: op = Xsse_CMPEQF; goto do_64Fx2;
-//..       case Iop_CmpLT64Fx2: op = Xsse_CMPLTF; goto do_64Fx2;
-//..       case Iop_CmpLE64Fx2: op = Xsse_CMPLEF; goto do_64Fx2;
+      case Iop_CmpEQ64Fx2: op = Asse_CMPEQF; goto do_64Fx2;
+      case Iop_CmpLT64Fx2: op = Asse_CMPLTF; goto do_64Fx2;
+      case Iop_CmpLE64Fx2: op = Asse_CMPLEF; goto do_64Fx2;
       case Iop_Add64Fx2:   op = Asse_ADDF;   goto do_64Fx2;
 //..       case Iop_Div64Fx2:   op = Xsse_DIVF;   goto do_64Fx2;
 //..       case Iop_Max64Fx2:   op = Xsse_MAXF;   goto do_64Fx2;
@@ -3372,37 +3371,37 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          return dst;
       }
 
-//..       case Iop_QNarrow32Sx4: 
-//..          op = Xsse_PACKSSD; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_QNarrow16Sx8: 
-//..          op = Xsse_PACKSSW; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_QNarrow16Ux8: 
-//..          op = Xsse_PACKUSW; arg1isEReg = True; goto do_SseReRg;
-//.. 
-//..       case Iop_InterleaveHI8x16: 
-//..          op = Xsse_UNPCKHB; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveHI16x8: 
-//..          op = Xsse_UNPCKHW; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveHI32x4: 
-//..          op = Xsse_UNPCKHD; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveHI64x2: 
-//..          op = Xsse_UNPCKHQ; arg1isEReg = True; goto do_SseReRg;
-//.. 
-//..       case Iop_InterleaveLO8x16: 
-//..          op = Xsse_UNPCKLB; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveLO16x8: 
-//..          op = Xsse_UNPCKLW; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveLO32x4: 
-//..          op = Xsse_UNPCKLD; arg1isEReg = True; goto do_SseReRg;
-//..       case Iop_InterleaveLO64x2: 
-//..          op = Xsse_UNPCKLQ; arg1isEReg = True; goto do_SseReRg;
-//.. 
+      case Iop_QNarrow32Sx4: 
+         op = Asse_PACKSSD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_QNarrow16Sx8: 
+         op = Asse_PACKSSW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_QNarrow16Ux8: 
+         op = Asse_PACKUSW; arg1isEReg = True; goto do_SseReRg;
+
+      case Iop_InterleaveHI8x16: 
+         op = Asse_UNPCKHB; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI16x8: 
+         op = Asse_UNPCKHW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI32x4: 
+         op = Asse_UNPCKHD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveHI64x2: 
+         op = Asse_UNPCKHQ; arg1isEReg = True; goto do_SseReRg;
+
+      case Iop_InterleaveLO8x16: 
+         op = Asse_UNPCKLB; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO16x8: 
+         op = Asse_UNPCKLW; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO32x4: 
+         op = Asse_UNPCKLD; arg1isEReg = True; goto do_SseReRg;
+      case Iop_InterleaveLO64x2: 
+         op = Asse_UNPCKLQ; arg1isEReg = True; goto do_SseReRg;
+
       case Iop_AndV128:    op = Asse_AND;      goto do_SseReRg;
       case Iop_OrV128:     op = Asse_OR;       goto do_SseReRg;
       case Iop_XorV128:    op = Asse_XOR;      goto do_SseReRg;
-//..       case Iop_Add8x16:    op = Xsse_ADD8;     goto do_SseReRg;
+      case Iop_Add8x16:    op = Asse_ADD8;     goto do_SseReRg;
 //..       case Iop_Add16x8:    op = Xsse_ADD16;    goto do_SseReRg;
-//..       case Iop_Add32x4:    op = Xsse_ADD32;    goto do_SseReRg;
+      case Iop_Add32x4:    op = Asse_ADD32;    goto do_SseReRg;
       case Iop_Add64x2:    op = Asse_ADD64;    goto do_SseReRg;
 //..       case Iop_QAdd8Sx16:  op = Xsse_QADD8S;   goto do_SseReRg;
 //..       case Iop_QAdd16Sx8:  op = Xsse_QADD16S;  goto do_SseReRg;
@@ -3423,20 +3422,19 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
 //..       case Iop_MulHi16Ux8: op = Xsse_MULHI16U; goto do_SseReRg;
 //..       case Iop_MulHi16Sx8: op = Xsse_MULHI16S; goto do_SseReRg;
 //..       case Iop_Mul16x8:    op = Xsse_MUL16;    goto do_SseReRg;
-//..       case Iop_Sub8x16:    op = Xsse_SUB8;     goto do_SseReRg;
-//..       case Iop_Sub16x8:    op = Xsse_SUB16;    goto do_SseReRg;
-//..       case Iop_Sub32x4:    op = Xsse_SUB32;    goto do_SseReRg;
+      case Iop_Sub8x16:    op = Asse_SUB8;     goto do_SseReRg;
+      case Iop_Sub16x8:    op = Asse_SUB16;    goto do_SseReRg;
+      case Iop_Sub32x4:    op = Asse_SUB32;    goto do_SseReRg;
       case Iop_Sub64x2:    op = Asse_SUB64;    goto do_SseReRg;
-//..       case Iop_QSub8Sx16:  op = Xsse_QSUB8S;   goto do_SseReRg;
-//..       case Iop_QSub16Sx8:  op = Xsse_QSUB16S;  goto do_SseReRg;
-//..       case Iop_QSub8Ux16:  op = Xsse_QSUB8U;   goto do_SseReRg;
-//..       case Iop_QSub16Ux8:  op = Xsse_QSUB16U;  goto do_SseReRg;
+      case Iop_QSub8Sx16:  op = Asse_QSUB8S;   goto do_SseReRg;
+      case Iop_QSub16Sx8:  op = Asse_QSUB16S;  goto do_SseReRg;
+      case Iop_QSub8Ux16:  op = Asse_QSUB8U;   goto do_SseReRg;
+      case Iop_QSub16Ux8:  op = Asse_QSUB16U;  goto do_SseReRg;
       do_SseReRg: {
          HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
          HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);
          HReg dst = newVRegV(env);
          if (arg1isEReg) {
-            goto vec_fail; /* awaiting test case */
             addInstr(env, mk_vMOVsd_RR(arg2, dst));
             addInstr(env, AMD64Instr_SseReRg(op, arg1, dst));
          } else {