From: Julian Seward Date: Tue, 10 May 2005 22:42:54 +0000 (+0000) Subject: Enough SSE2 instructions to sink a small ship. And that's not even X-Git-Tag: svn/VALGRIND_3_0_1^2~156 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51b17c8c742eb6d8470a6a910574def2d9853ed7;p=thirdparty%2Fvalgrind.git Enough SSE2 instructions to sink a small ship. And that's not even half of them. git-svn-id: svn://svn.valgrind.org/vex/trunk@1178 --- diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 346c86a07e..7b8400597b 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -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 diff --git a/VEX/priv/host-amd64/hdefs.c b/VEX/priv/host-amd64/hdefs.c index c6120eaa3d..1505efa510 100644 --- a/VEX/priv/host-amd64/hdefs.c +++ b/VEX/priv/host-amd64/hdefs.c @@ -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), diff --git a/VEX/priv/host-amd64/hdefs.h b/VEX/priv/host-amd64/hdefs.h index 9df3f3ea0c..ac3bc6f90b 100644 --- a/VEX/priv/host-amd64/hdefs.h +++ b/VEX/priv/host-amd64/hdefs.h @@ -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; diff --git a/VEX/priv/host-amd64/isel.c b/VEX/priv/host-amd64/isel.c index b760e6ac9e..72e74a345e 100644 --- a/VEX/priv/host-amd64/isel.c +++ b/VEX/priv/host-amd64/isel.c @@ -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 {