From: Julian Seward Date: Sun, 21 Nov 2004 12:30:18 +0000 (+0000) Subject: Implement a bunch more MMX insns. X-Git-Tag: svn/VALGRIND_3_0_1^2~764 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d74671c7d3bd13776c26eae3f7dca692cf78d268;p=thirdparty%2Fvalgrind.git Implement a bunch more MMX insns. git-svn-id: svn://svn.valgrind.org/vex/trunk@570 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 4dd73b3bdf..b859915b33 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -91,37 +91,48 @@ extern ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ); /* --- Clean helpers for MMX --- */ -extern ULong calculate_vadd32x2 ( ULong, ULong ); -extern ULong calculate_vadd16x4 ( ULong, ULong ); -extern ULong calculate_vadd8x8 ( ULong, ULong ); +extern ULong calculate_add32x2 ( ULong, ULong ); +extern ULong calculate_add16x4 ( ULong, ULong ); +extern ULong calculate_add8x8 ( ULong, ULong ); -extern ULong calculate_vqadd16Sx4 ( ULong, ULong ); -extern ULong calculate_vqadd8Sx8 ( ULong, ULong ); +extern ULong calculate_qadd16Sx4 ( ULong, ULong ); +extern ULong calculate_qadd8Sx8 ( ULong, ULong ); -extern ULong calculate_vqadd16Ux4 ( ULong, ULong ); -extern ULong calculate_vqadd8Ux8 ( ULong, ULong ); +extern ULong calculate_qadd16Ux4 ( ULong, ULong ); +extern ULong calculate_qadd8Ux8 ( ULong, ULong ); -extern ULong calculate_vsub32x2 ( ULong, ULong ); -extern ULong calculate_vsub16x4 ( ULong, ULong ); -extern ULong calculate_vsub8x8 ( ULong, ULong ); +extern ULong calculate_sub32x2 ( ULong, ULong ); +extern ULong calculate_sub16x4 ( ULong, ULong ); +extern ULong calculate_sub8x8 ( ULong, ULong ); -extern ULong calculate_vqsub16Sx4 ( ULong, ULong ); -extern ULong calculate_vqsub8Sx8 ( ULong, ULong ); +extern ULong calculate_qsub16Sx4 ( ULong, ULong ); +extern ULong calculate_qsub8Sx8 ( ULong, ULong ); -extern ULong calculate_vqsub16Ux4 ( ULong, ULong ); -extern ULong calculate_vqsub8Ux8 ( ULong, ULong ); +extern ULong calculate_qsub16Ux4 ( ULong, ULong ); +extern ULong calculate_qsub8Ux8 ( ULong, ULong ); -extern ULong calculate_vmulhi16x4 ( ULong, ULong ); -extern ULong calculate_vmullo16x4 ( ULong, ULong ); +extern ULong calculate_mulhi16x4 ( ULong, ULong ); +extern ULong calculate_mullo16x4 ( ULong, ULong ); extern ULong calculate_pmaddwd ( ULong, ULong ); -extern ULong calculate_vcmpeq32x2 ( ULong, ULong ); -extern ULong calculate_vcmpeq16x4 ( ULong, ULong ); -extern ULong calculate_vcmpeq8x8 ( ULong, ULong ); -extern ULong calculate_vcmpge32Sx2 ( ULong, ULong ); -extern ULong calculate_vcmpge16Sx4 ( ULong, ULong ); -extern ULong calculate_vcmpge8Sx8 ( ULong, ULong ); +extern ULong calculate_cmpeq32x2 ( ULong, ULong ); +extern ULong calculate_cmpeq16x4 ( ULong, ULong ); +extern ULong calculate_cmpeq8x8 ( ULong, ULong ); +extern ULong calculate_cmpge32Sx2 ( ULong, ULong ); +extern ULong calculate_cmpge16Sx4 ( ULong, ULong ); +extern ULong calculate_cmpge8Sx8 ( ULong, ULong ); + +extern ULong calculate_packssdw ( ULong, ULong ); +extern ULong calculate_packsswb ( ULong, ULong ); +extern ULong calculate_packuswb ( ULong, ULong ); + +extern ULong calculate_punpckhbw ( ULong, ULong ); +extern ULong calculate_punpcklbw ( ULong, ULong ); +extern ULong calculate_punpckhwd ( ULong, ULong ); +extern ULong calculate_punpcklwd ( ULong, ULong ); +extern ULong calculate_punpckhdq ( ULong, ULong ); +extern ULong calculate_punpckldq ( ULong, ULong ); /* --- DIRTY HELPERS --- */ diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 7d9f817d5c..b0f4c16d69 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1643,7 +1643,7 @@ static inline UShort sel16x4_2 ( ULong w64 ) static inline UShort sel16x4_1 ( ULong w64 ) { UInt lo32 = (UInt)w64; - return 0xFFFF & (UInt)(lo32 >> 16); + return 0xFFFF & (UShort)(lo32 >> 16); } static inline UShort sel16x4_0 ( ULong w64 ) { @@ -1815,13 +1815,31 @@ static inline UChar cmpge8S ( SChar xx, SChar yy ) return xx>yy ? 0xFF : 0; } +static inline Short qnarrow32Sto16 ( Int xx ) +{ + if (xx < -32768) xx = -32768; + if (xx > 32767) xx = 32767; + return (Short)xx; +} +static inline SChar qnarrow16Sto8 ( Int xx ) +{ + if (xx < -128) xx = -128; + if (xx > 127) xx = 127; + return (SChar)xx; +} + +static inline UChar qnarrow16Uto8 ( Int xx ) +{ + if (xx < 0) xx = 0; + if (xx > 255) xx = 255; + return (UChar)xx; +} -/* Actually do something interesting! */ -/* Normal adds. */ +/* ------------ Normal addition ------------ */ -ULong calculate_vadd32x2 ( ULong xx, ULong yy ) +ULong calculate_add32x2 ( ULong xx, ULong yy ) { return mk32x2( sel32x2_1(xx) + sel32x2_1(yy), @@ -1829,7 +1847,7 @@ ULong calculate_vadd32x2 ( ULong xx, ULong yy ) ); } -ULong calculate_vadd16x4 ( ULong xx, ULong yy ) +ULong calculate_add16x4 ( ULong xx, ULong yy ) { return mk16x4( sel16x4_3(xx) + sel16x4_3(yy), @@ -1839,7 +1857,7 @@ ULong calculate_vadd16x4 ( ULong xx, ULong yy ) ); } -ULong calculate_vadd8x8 ( ULong xx, ULong yy ) +ULong calculate_add8x8 ( ULong xx, ULong yy ) { return mk8x8( sel8x8_7(xx) + sel8x8_7(yy), @@ -1853,9 +1871,9 @@ ULong calculate_vadd8x8 ( ULong xx, ULong yy ) ); } -/* Saturated adds. */ +/* ------------ Saturating addition ------------ */ -ULong calculate_vqadd16Sx4 ( ULong xx, ULong yy ) +ULong calculate_qadd16Sx4 ( ULong xx, ULong yy ) { return mk16x4( qadd16S( sel16x4_3(xx), sel16x4_3(yy) ), @@ -1865,7 +1883,7 @@ ULong calculate_vqadd16Sx4 ( ULong xx, ULong yy ) ); } -ULong calculate_vqadd8Sx8 ( ULong xx, ULong yy ) +ULong calculate_qadd8Sx8 ( ULong xx, ULong yy ) { return mk8x8( qadd8S( sel8x8_7(xx), sel8x8_7(yy) ), @@ -1879,7 +1897,7 @@ ULong calculate_vqadd8Sx8 ( ULong xx, ULong yy ) ); } -ULong calculate_vqadd16Ux4 ( ULong xx, ULong yy ) +ULong calculate_qadd16Ux4 ( ULong xx, ULong yy ) { return mk16x4( qadd16U( sel16x4_3(xx), sel16x4_3(yy) ), @@ -1889,7 +1907,7 @@ ULong calculate_vqadd16Ux4 ( ULong xx, ULong yy ) ); } -ULong calculate_vqadd8Ux8 ( ULong xx, ULong yy ) +ULong calculate_qadd8Ux8 ( ULong xx, ULong yy ) { return mk8x8( qadd8U( sel8x8_7(xx), sel8x8_7(yy) ), @@ -1903,9 +1921,9 @@ ULong calculate_vqadd8Ux8 ( ULong xx, ULong yy ) ); } -/* Normal subtracts. */ +/* ------------ Normal subtraction ------------ */ -ULong calculate_vsub32x2 ( ULong xx, ULong yy ) +ULong calculate_sub32x2 ( ULong xx, ULong yy ) { return mk32x2( sel32x2_1(xx) - sel32x2_1(yy), @@ -1913,7 +1931,7 @@ ULong calculate_vsub32x2 ( ULong xx, ULong yy ) ); } -ULong calculate_vsub16x4 ( ULong xx, ULong yy ) +ULong calculate_sub16x4 ( ULong xx, ULong yy ) { return mk16x4( sel16x4_3(xx) - sel16x4_3(yy), @@ -1923,7 +1941,7 @@ ULong calculate_vsub16x4 ( ULong xx, ULong yy ) ); } -ULong calculate_vsub8x8 ( ULong xx, ULong yy ) +ULong calculate_sub8x8 ( ULong xx, ULong yy ) { return mk8x8( sel8x8_7(xx) - sel8x8_7(yy), @@ -1937,9 +1955,9 @@ ULong calculate_vsub8x8 ( ULong xx, ULong yy ) ); } -/* Saturated subtracts. */ +/* ------------ Saturating subtraction ------------ */ -ULong calculate_vqsub16Sx4 ( ULong xx, ULong yy ) +ULong calculate_qsub16Sx4 ( ULong xx, ULong yy ) { return mk16x4( qsub16S( sel16x4_3(xx), sel16x4_3(yy) ), @@ -1949,7 +1967,7 @@ ULong calculate_vqsub16Sx4 ( ULong xx, ULong yy ) ); } -ULong calculate_vqsub8Sx8 ( ULong xx, ULong yy ) +ULong calculate_qsub8Sx8 ( ULong xx, ULong yy ) { return mk8x8( qsub8S( sel8x8_7(xx), sel8x8_7(yy) ), @@ -1963,7 +1981,7 @@ ULong calculate_vqsub8Sx8 ( ULong xx, ULong yy ) ); } -ULong calculate_vqsub16Ux4 ( ULong xx, ULong yy ) +ULong calculate_qsub16Ux4 ( ULong xx, ULong yy ) { return mk16x4( qsub16U( sel16x4_3(xx), sel16x4_3(yy) ), @@ -1973,7 +1991,7 @@ ULong calculate_vqsub16Ux4 ( ULong xx, ULong yy ) ); } -ULong calculate_vqsub8Ux8 ( ULong xx, ULong yy ) +ULong calculate_qsub8Ux8 ( ULong xx, ULong yy ) { return mk8x8( qsub8U( sel8x8_7(xx), sel8x8_7(yy) ), @@ -1987,9 +2005,9 @@ ULong calculate_vqsub8Ux8 ( ULong xx, ULong yy ) ); } -/* Multiplication. */ +/* ------------ Multiplication ------------ */ -ULong calculate_vmulhi16x4 ( ULong xx, ULong yy ) +ULong calculate_mulhi16x4 ( ULong xx, ULong yy ) { return mk16x4( mulhi16S( sel16x4_3(xx), sel16x4_3(yy) ), @@ -1999,7 +2017,7 @@ ULong calculate_vmulhi16x4 ( ULong xx, ULong yy ) ); } -ULong calculate_vmullo16x4 ( ULong xx, ULong yy ) +ULong calculate_mullo16x4 ( ULong xx, ULong yy ) { return mk16x4( mullo16S( sel16x4_3(xx), sel16x4_3(yy) ), @@ -2020,9 +2038,9 @@ ULong calculate_pmaddwd ( ULong xx, ULong yy ) ); } -/* Comparison. */ +/* ------------ Comparison ------------ */ -ULong calculate_vcmpeq32x2 ( ULong xx, ULong yy ) +ULong calculate_cmpeq32x2 ( ULong xx, ULong yy ) { return mk32x2( cmpeq32( sel32x2_1(xx), sel32x2_1(yy) ), @@ -2030,7 +2048,7 @@ ULong calculate_vcmpeq32x2 ( ULong xx, ULong yy ) ); } -ULong calculate_vcmpeq16x4 ( ULong xx, ULong yy ) +ULong calculate_cmpeq16x4 ( ULong xx, ULong yy ) { return mk16x4( cmpeq16( sel16x4_3(xx), sel16x4_3(yy) ), @@ -2040,7 +2058,7 @@ ULong calculate_vcmpeq16x4 ( ULong xx, ULong yy ) ); } -ULong calculate_vcmpeq8x8 ( ULong xx, ULong yy ) +ULong calculate_cmpeq8x8 ( ULong xx, ULong yy ) { return mk8x8( cmpeq8( sel8x8_7(xx), sel8x8_7(yy) ), @@ -2054,7 +2072,7 @@ ULong calculate_vcmpeq8x8 ( ULong xx, ULong yy ) ); } -ULong calculate_vcmpge32Sx2 ( ULong xx, ULong yy ) +ULong calculate_cmpge32Sx2 ( ULong xx, ULong yy ) { return mk32x2( cmpge32S( sel32x2_1(xx), sel32x2_1(yy) ), @@ -2062,7 +2080,7 @@ ULong calculate_vcmpge32Sx2 ( ULong xx, ULong yy ) ); } -ULong calculate_vcmpge16Sx4 ( ULong xx, ULong yy ) +ULong calculate_cmpge16Sx4 ( ULong xx, ULong yy ) { return mk16x4( cmpge16S( sel16x4_3(xx), sel16x4_3(yy) ), @@ -2072,7 +2090,7 @@ ULong calculate_vcmpge16Sx4 ( ULong xx, ULong yy ) ); } -ULong calculate_vcmpge8Sx8 ( ULong xx, ULong yy ) +ULong calculate_cmpge8Sx8 ( ULong xx, ULong yy ) { return mk8x8( cmpge8S( sel8x8_7(xx), sel8x8_7(yy) ), @@ -2086,6 +2104,129 @@ ULong calculate_vcmpge8Sx8 ( ULong xx, ULong yy ) ); } +/* ------------ Pack / unpack ------------ */ + +ULong calculate_packssdw ( ULong dst, ULong src ) +{ + Int d = sel32x2_1(dst); + Int c = sel32x2_0(dst); + Int b = sel32x2_1(src); + Int a = sel32x2_0(src); + return mk16x4( + qnarrow32Sto16(d), + qnarrow32Sto16(c), + qnarrow32Sto16(b), + qnarrow32Sto16(a) + ); +} + +ULong calculate_packsswb ( ULong dst, ULong src ) +{ + Int h = sel16x4_3(dst); + Int g = sel16x4_2(dst); + Int f = sel16x4_1(dst); + Int e = sel16x4_0(dst); + Int d = sel16x4_3(src); + Int c = sel16x4_2(src); + Int b = sel16x4_1(src); + Int a = sel16x4_0(src); + return mk8x8( + qnarrow16Sto8(h), + qnarrow16Sto8(g), + qnarrow16Sto8(f), + qnarrow16Sto8(e), + qnarrow16Sto8(d), + qnarrow16Sto8(c), + qnarrow16Sto8(b), + qnarrow16Sto8(a) + ); +} + +ULong calculate_packuswb ( ULong dst, ULong src ) +{ + Int h = sel16x4_3(dst); + Int g = sel16x4_2(dst); + Int f = sel16x4_1(dst); + Int e = sel16x4_0(dst); + Int d = sel16x4_3(src); + Int c = sel16x4_2(src); + Int b = sel16x4_1(src); + Int a = sel16x4_0(src); + return mk8x8( + qnarrow16Uto8(h), + qnarrow16Uto8(g), + qnarrow16Uto8(f), + qnarrow16Uto8(e), + qnarrow16Uto8(d), + qnarrow16Uto8(c), + qnarrow16Uto8(b), + qnarrow16Uto8(a) + ); +} + +ULong calculate_punpckhbw ( ULong dst, ULong src ) +{ + return mk8x8( + sel8x8_7(src), + sel8x8_7(dst), + sel8x8_6(src), + sel8x8_6(dst), + sel8x8_5(src), + sel8x8_5(dst), + sel8x8_4(src), + sel8x8_4(dst) + ); +} + +ULong calculate_punpcklbw ( ULong dst, ULong src ) +{ + return mk8x8( + sel8x8_3(src), + sel8x8_3(dst), + sel8x8_2(src), + sel8x8_2(dst), + sel8x8_1(src), + sel8x8_1(dst), + sel8x8_0(src), + sel8x8_0(dst) + ); +} + +ULong calculate_punpckhwd ( ULong dst, ULong src ) +{ + return mk16x4( + sel16x4_3(src), + sel16x4_3(dst), + sel16x4_2(src), + sel16x4_2(dst) + ); +} + +ULong calculate_punpcklwd ( ULong dst, ULong src ) +{ + return mk16x4( + sel16x4_1(src), + sel16x4_1(dst), + sel16x4_0(src), + sel16x4_0(dst) + ); +} + +ULong calculate_punpckhdq ( ULong dst, ULong src ) +{ + return mk32x2( + sel32x2_1(src), + sel32x2_1(dst) + ); +} + +ULong calculate_punpckldq ( ULong dst, ULong src ) +{ + return mk32x2( + sel32x2_0(src), + sel32x2_0(dst) + ); +} /*-----------------------------------------------------------*/ diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index bb32060144..6bed793054 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -4636,46 +4636,66 @@ UInt dis_MMXop_regmem_to_reg ( UChar sorb, Char* name, Bool show_granularity ) { - Char dis_buf[50]; - UChar modrm = getIByte(delta); - Bool isReg = epartIsReg(modrm); + Char dis_buf[50]; + UChar modrm = getIByte(delta); + Bool isReg = epartIsReg(modrm); + IRExpr* argL = NULL; + IRExpr* argR = NULL; + IRTemp res = newTemp(Ity_I64); # define XXX(_name) hAddr = &_name; hName = #_name; void* hAddr = NULL; Char* hName = NULL; switch (opc) { - case 0xFC: XXX(calculate_vadd8x8); break; - case 0xFD: XXX(calculate_vadd16x4); break; - case 0xFE: XXX(calculate_vadd32x2); break; + case 0xFC: XXX(calculate_add8x8); break; + case 0xFD: XXX(calculate_add16x4); break; + case 0xFE: XXX(calculate_add32x2); break; - case 0xEC: XXX(calculate_vqadd8Sx8); break; - case 0xED: XXX(calculate_vqadd16Sx4); break; + case 0xEC: XXX(calculate_qadd8Sx8); break; + case 0xED: XXX(calculate_qadd16Sx4); break; - case 0xDC: XXX(calculate_vqadd8Ux8); break; - case 0xDD: XXX(calculate_vqadd16Ux4); break; + case 0xDC: XXX(calculate_qadd8Ux8); break; + case 0xDD: XXX(calculate_qadd16Ux4); break; - case 0xF8: XXX(calculate_vsub8x8); break; - case 0xF9: XXX(calculate_vsub16x4); break; - case 0xFA: XXX(calculate_vsub32x2); break; + case 0xF8: XXX(calculate_sub8x8); break; + case 0xF9: XXX(calculate_sub16x4); break; + case 0xFA: XXX(calculate_sub32x2); break; - case 0xE8: XXX(calculate_vqsub8Sx8); break; - case 0xE9: XXX(calculate_vqsub16Sx4); break; + case 0xE8: XXX(calculate_qsub8Sx8); break; + case 0xE9: XXX(calculate_qsub16Sx4); break; - case 0xD8: XXX(calculate_vqsub8Ux8); break; - case 0xD9: XXX(calculate_vqsub16Ux4); break; + case 0xD8: XXX(calculate_qsub8Ux8); break; + case 0xD9: XXX(calculate_qsub16Ux4); break; - case 0xE5: XXX(calculate_vmulhi16x4); break; - case 0xD5: XXX(calculate_vmullo16x4); break; + case 0xE5: XXX(calculate_mulhi16x4); break; + case 0xD5: XXX(calculate_mullo16x4); break; case 0xF5: XXX(calculate_pmaddwd); break; - case 0x74: XXX(calculate_vcmpeq8x8); break; - case 0x75: XXX(calculate_vcmpeq16x4); break; - case 0x76: XXX(calculate_vcmpeq32x2); break; + case 0x74: XXX(calculate_cmpeq8x8); break; + case 0x75: XXX(calculate_cmpeq16x4); break; + case 0x76: XXX(calculate_cmpeq32x2); break; - case 0x64: XXX(calculate_vcmpge8Sx8); break; - case 0x65: XXX(calculate_vcmpge16Sx4); break; - case 0x66: XXX(calculate_vcmpge32Sx2); break; + case 0x64: XXX(calculate_cmpge8Sx8); break; + case 0x65: XXX(calculate_cmpge16Sx4); break; + case 0x66: XXX(calculate_cmpge32Sx2); break; + + case 0x6B: XXX(calculate_packssdw); break; + case 0x63: XXX(calculate_packsswb); break; + case 0x67: XXX(calculate_packuswb); break; + + case 0x68: XXX(calculate_punpckhbw); break; + case 0x69: XXX(calculate_punpckhwd); break; + case 0x6A: XXX(calculate_punpckhdq); break; + + case 0x60: XXX(calculate_punpcklbw); break; + case 0x61: XXX(calculate_punpcklwd); break; + case 0x62: XXX(calculate_punpckldq); break; + + case 0xDB: break; /* AND */ + case 0xDF: break; /* ANDN */ + case 0xEB: break; /* OR */ + case 0xEF: break; /* XOR */ default: vex_printf("\n0x%x\n", (Int)opc); @@ -4684,33 +4704,48 @@ UInt dis_MMXop_regmem_to_reg ( UChar sorb, # undef XXX + argL = getMMXReg(gregOfRM(modrm)); + if (isReg) { -vassert(0); + vassert(0); delta++; - putMMXReg( - gregOfRM(modrm), - mkIRExprCCall( - Ity_I64, - 0/*regparms*/, hName, hAddr, - mkIRExprVec_2( getMMXReg(gregOfRM(modrm)), - getMMXReg(eregOfRM(modrm)) ) - ) - ); + argR = getMMXReg(eregOfRM(modrm)); } else { Int len; IRTemp addr = disAMode( &len, sorb, delta, dis_buf ); delta += len; - putMMXReg( - gregOfRM(modrm), - mkIRExprCCall( - Ity_I64, - 0/*regparms*/, hName, hAddr, - mkIRExprVec_2( getMMXReg(gregOfRM(modrm)), - loadLE(Ity_I64, mkexpr(addr)) ) - ) - ); + argR = loadLE(Ity_I64, mkexpr(addr)); + } + + switch (opc) { + case 0xDB: + assign(res, binop(Iop_And64, argL, argR) ); + break; + case 0xDF: + assign(res, binop(Iop_And64, argL, unop(Iop_Not64, argR)) ); + break; + case 0xEB: + assign(res, binop(Iop_Or64, argL, argR) ); + break; + case 0xEF: + /* Possibly do better here if argL and argR are the same reg */ + assign(res, binop(Iop_Xor64, argL, argR) ); + break; + default: + vassert(hAddr); + vassert(hName); + assign( res, + mkIRExprCCall( + Ity_I64, + 0/*regparms*/, hName, hAddr, + mkIRExprVec_2( argL, argR ) + ) + ); + break; } + putMMXReg( gregOfRM(modrm), mkexpr(res) ); + DIP("%s%s %s, %s\n", name, show_granularity ? nameMMXGran(opc & 3) : (Char*)"", ( isReg ? nameMMXReg(eregOfRM(modrm)) : dis_buf ), @@ -4760,7 +4795,7 @@ UInt dis_MMX ( Bool* decode_ok, UChar sorb, Int sz, UInt delta ) vassert(sz == 4); modrm = getIByte(delta); if (epartIsReg(modrm)) { -vassert(0); + vassert(0); #if 0 eip++; uInstr1(cb, MMX2, 0, @@ -4845,6 +4880,55 @@ vassert(0); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pcmpgt", True ); break; + case 0x6B: /* PACKSSDW (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "packssdw", False ); + break; + + case 0x63: /* PACKSSWB (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "packsswb", False ); + break; + + case 0x67: /* PACKUSWB (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "packuswb", False ); + break; + + case 0x68: + case 0x69: + case 0x6A: /* PUNPCKHgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "punpckh", True ); + break; + + case 0x60: + case 0x61: + case 0x62: /* PUNPCKLgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "punpckl", True ); + break; + + case 0xDB: /* PAND (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pand", False ); + break; + + case 0xDF: /* PANDN (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pandn", False ); + break; + + case 0xEB: /* POR (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "por", False ); + break; + + case 0xEF: /* PXOR (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pxor", False ); + break; + default: *decode_ok = False; return delta; /* ignored */ @@ -9488,6 +9572,23 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, case 0x65: case 0x66: /* PCMPGTgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x6B: /* PACKSSDW (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x63: /* PACKSSWB (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x67: /* PACKUSWB (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0x68: + case 0x69: + case 0x6A: /* PUNPCKHgg (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0x60: + case 0x61: + case 0x62: /* PUNPCKLgg (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0xDB: /* PAND (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xDF: /* PANDN (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xEB: /* POR (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xEF: /* PXOR (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x6F: /* MOVQ (src)mmxreg-or-mem, (dst)mmxreg */ { UInt delta0 = delta-1;