From: Julian Seward Date: Sat, 20 Nov 2004 13:17:04 +0000 (+0000) Subject: Some more MMX insns. X-Git-Tag: svn/VALGRIND_3_0_1^2~765 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ab7ff28c2281cbfcfda24a7683fa47e379840c65;p=thirdparty%2Fvalgrind.git Some more MMX insns. git-svn-id: svn://svn.valgrind.org/vex/trunk@569 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 80144bfd9d..4dd73b3bdf 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -114,6 +114,16 @@ extern ULong calculate_vqsub8Ux8 ( ULong, ULong ); extern ULong calculate_vmulhi16x4 ( ULong, ULong ); extern ULong calculate_vmullo16x4 ( 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 ); + + /* --- DIRTY HELPERS --- */ extern ULong loadF80le ( UInt ); diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 95ff692314..7d9f817d5c 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1785,16 +1785,47 @@ static inline Short mullo16S ( Short xx, Short yy ) return (Short)t; } +static inline UInt cmpeq32 ( UInt xx, UInt yy ) +{ + return xx==yy ? 0xFFFFFFFF : 0; +} + +static inline UShort cmpeq16 ( UShort xx, UShort yy ) +{ + return xx==yy ? 0xFFFF : 0; +} + +static inline UChar cmpeq8 ( UChar xx, UChar yy ) +{ + return xx==yy ? 0xFF : 0; +} + +static inline UInt cmpge32S ( Int xx, Int yy ) +{ + return xx>yy ? 0xFFFFFFFF : 0; +} + +static inline UShort cmpge16S ( Short xx, Short yy ) +{ + return xx>yy ? 0xFFFF : 0; +} + +static inline UChar cmpge8S ( SChar xx, SChar yy ) +{ + return xx>yy ? 0xFF : 0; +} + + /* Actually do something interesting! */ /* Normal adds. */ -ULong calculate_vadd32x2 ( ULong xxL, ULong yyL ) +ULong calculate_vadd32x2 ( ULong xx, ULong yy ) { return mk32x2( - sel32x2_1(xxL) + sel32x2_1(yyL), - sel32x2_0(xxL) + sel32x2_0(yyL) + sel32x2_1(xx) + sel32x2_1(yy), + sel32x2_0(xx) + sel32x2_0(yy) ); } @@ -1874,11 +1905,11 @@ ULong calculate_vqadd8Ux8 ( ULong xx, ULong yy ) /* Normal subtracts. */ -ULong calculate_vsub32x2 ( ULong xxL, ULong yyL ) +ULong calculate_vsub32x2 ( ULong xx, ULong yy ) { return mk32x2( - sel32x2_1(xxL) - sel32x2_1(yyL), - sel32x2_0(xxL) - sel32x2_0(yyL) + sel32x2_1(xx) - sel32x2_1(yy), + sel32x2_0(xx) - sel32x2_0(yy) ); } @@ -1978,6 +2009,84 @@ ULong calculate_vmullo16x4 ( ULong xx, ULong yy ) ); } +ULong calculate_pmaddwd ( ULong xx, ULong yy ) +{ + return + mk32x2( + (((Int)(Short)sel16x4_3(xx)) * ((Int)(Short)sel16x4_3(yy))) + + (((Int)(Short)sel16x4_2(xx)) * ((Int)(Short)sel16x4_2(yy))), + (((Int)(Short)sel16x4_1(xx)) * ((Int)(Short)sel16x4_1(yy))) + + (((Int)(Short)sel16x4_0(xx)) * ((Int)(Short)sel16x4_0(yy))) + ); +} + +/* Comparison. */ + +ULong calculate_vcmpeq32x2 ( ULong xx, ULong yy ) +{ + return mk32x2( + cmpeq32( sel32x2_1(xx), sel32x2_1(yy) ), + cmpeq32( sel32x2_0(xx), sel32x2_0(yy) ) + ); +} + +ULong calculate_vcmpeq16x4 ( ULong xx, ULong yy ) +{ + return mk16x4( + cmpeq16( sel16x4_3(xx), sel16x4_3(yy) ), + cmpeq16( sel16x4_2(xx), sel16x4_2(yy) ), + cmpeq16( sel16x4_1(xx), sel16x4_1(yy) ), + cmpeq16( sel16x4_0(xx), sel16x4_0(yy) ) + ); +} + +ULong calculate_vcmpeq8x8 ( ULong xx, ULong yy ) +{ + return mk8x8( + cmpeq8( sel8x8_7(xx), sel8x8_7(yy) ), + cmpeq8( sel8x8_6(xx), sel8x8_6(yy) ), + cmpeq8( sel8x8_5(xx), sel8x8_5(yy) ), + cmpeq8( sel8x8_4(xx), sel8x8_4(yy) ), + cmpeq8( sel8x8_3(xx), sel8x8_3(yy) ), + cmpeq8( sel8x8_2(xx), sel8x8_2(yy) ), + cmpeq8( sel8x8_1(xx), sel8x8_1(yy) ), + cmpeq8( sel8x8_0(xx), sel8x8_0(yy) ) + ); +} + +ULong calculate_vcmpge32Sx2 ( ULong xx, ULong yy ) +{ + return mk32x2( + cmpge32S( sel32x2_1(xx), sel32x2_1(yy) ), + cmpge32S( sel32x2_0(xx), sel32x2_0(yy) ) + ); +} + +ULong calculate_vcmpge16Sx4 ( ULong xx, ULong yy ) +{ + return mk16x4( + cmpge16S( sel16x4_3(xx), sel16x4_3(yy) ), + cmpge16S( sel16x4_2(xx), sel16x4_2(yy) ), + cmpge16S( sel16x4_1(xx), sel16x4_1(yy) ), + cmpge16S( sel16x4_0(xx), sel16x4_0(yy) ) + ); +} + +ULong calculate_vcmpge8Sx8 ( ULong xx, ULong yy ) +{ + return mk8x8( + cmpge8S( sel8x8_7(xx), sel8x8_7(yy) ), + cmpge8S( sel8x8_6(xx), sel8x8_6(yy) ), + cmpge8S( sel8x8_5(xx), sel8x8_5(yy) ), + cmpge8S( sel8x8_4(xx), sel8x8_4(yy) ), + cmpge8S( sel8x8_3(xx), sel8x8_3(yy) ), + cmpge8S( sel8x8_2(xx), sel8x8_2(yy) ), + cmpge8S( sel8x8_1(xx), sel8x8_1(yy) ), + cmpge8S( sel8x8_0(xx), sel8x8_0(yy) ) + ); +} + + /*-----------------------------------------------------------*/ /*--- Describing the x86 guest state, for the benefit ---*/ diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 1e506a816d..bb32060144 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -4667,6 +4667,15 @@ UInt dis_MMXop_regmem_to_reg ( UChar sorb, case 0xE5: XXX(calculate_vmulhi16x4); break; case 0xD5: XXX(calculate_vmullo16x4); 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 0x64: XXX(calculate_vcmpge8Sx8); break; + case 0x65: XXX(calculate_vcmpge16Sx4); break; + case 0x66: XXX(calculate_vcmpge32Sx2); break; default: vex_printf("\n0x%x\n", (Int)opc); @@ -4769,38 +4778,40 @@ vassert(0); } break; - case 0xFC: case 0xFD: case 0xFE: - /* PADDgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xFC: + case 0xFD: + case 0xFE: /* PADDgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "padd", True ); break; - case 0xEC: case 0xED: - /* PADDSgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xEC: + case 0xED: /* PADDSgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "padds", True ); break; - case 0xDC: case 0xDD: - /* PADDUSgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xDC: + case 0xDD: /* PADDUSgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "paddus", True ); break; - case 0xF8: case 0xF9: case 0xFA: - /* PSUBgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xF8: + case 0xF9: + case 0xFA: /* PSUBgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psub", True ); break; - case 0xE8: case 0xE9: - /* PSUBSgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xE8: + case 0xE9: /* PSUBSgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psubs", True ); break; - case 0xD8: case 0xD9: - /* PSUBUSgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xD8: + case 0xD9: /* PSUBUSgg (src)mmxreg-or-mem, (dst)mmxreg */ vassert(sz == 4); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psubus", True ); break; @@ -4815,6 +4826,25 @@ vassert(0); delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pmullw", False ); break; + case 0xF5: /* PMADDWD (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pmaddwd", False ); + break; + + case 0x74: + case 0x75: + case 0x76: /* PCMPEQgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pcmpeq", True ); + break; + + case 0x64: + case 0x65: + case 0x66: /* PCMPGTgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pcmpgt", True ); + break; + default: *decode_ok = False; return delta; /* ignored */ @@ -9448,6 +9478,16 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, case 0xE5: /* PMULHW (src)mmxreg-or-mem, (dst)mmxreg */ case 0xD5: /* PMULLW (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xF5: /* PMADDWD (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0x74: + case 0x75: + case 0x76: /* PCMPEQgg (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0x64: + case 0x65: + case 0x66: /* PCMPGTgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x6F: /* MOVQ (src)mmxreg-or-mem, (dst)mmxreg */ { UInt delta0 = delta-1;