}
}
-//.. /* 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 )
{
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 )
{
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
/* 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;
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) {
}
/* 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 */
//.. "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,
//.. 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])
//.. 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
//.. 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
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
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";
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");
}
}
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),
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;
//.. 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),