From: Julian Seward Date: Sun, 21 Nov 2004 17:04:50 +0000 (+0000) Subject: Add MMX shift-by-vector (not correct yet). X-Git-Tag: svn/VALGRIND_3_0_1^2~762 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c8b3501cdf551e7ca598bf921a63b7a510ff8c3;p=thirdparty%2Fvalgrind.git Add MMX shift-by-vector (not correct yet). git-svn-id: svn://svn.valgrind.org/vex/trunk@572 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index b859915b33..d5c7483c7a 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -134,6 +134,17 @@ extern ULong calculate_punpcklwd ( ULong, ULong ); extern ULong calculate_punpckhdq ( ULong, ULong ); extern ULong calculate_punpckldq ( ULong, ULong ); +extern ULong calculate_shl16x4 ( ULong, ULong ); +extern ULong calculate_shl32x2 ( ULong, ULong ); +extern ULong calculate_shl64x1 ( ULong, ULong ); + +extern ULong calculate_shr16Ux4 ( ULong, ULong ); +extern ULong calculate_shr32Ux2 ( ULong, ULong ); +extern ULong calculate_shr64Ux1 ( ULong, ULong ); + +extern ULong calculate_shr16Sx4 ( ULong, ULong ); +extern ULong calculate_shr32Sx2 ( ULong, ULong ); + /* --- DIRTY HELPERS --- */ diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index b0f4c16d69..875860180c 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1836,6 +1836,40 @@ static inline UChar qnarrow16Uto8 ( Int xx ) return (UChar)xx; } +static inline UShort shl16 ( UShort v, UShort n ) +{ + return n > 15 ? 0 : v << n; +} + +static inline UShort shr16U ( UShort v, UShort n ) +{ + return n > 15 ? 0 : (((UShort)v) >> n); +} + +static inline UShort shr16S ( UShort v, UShort n ) +{ + if (n <= 15) + return ((Short)v) >> n; + return (v & 0x8000) ? 0xFFFF : 0; +} + +static inline UInt shl32 ( UInt v, UInt n ) +{ + return n > 31 ? 0 : v << n; +} + +static inline UInt shr32U ( UInt v, UInt n ) +{ + return n > 31 ? 0 : (((UInt)v) >> n); +} + +static inline UInt shr32S ( UInt v, UInt n ) +{ + if (n <= 31) + return ((Int)v) >> n; + return (v & 0x80000000) ? 0xFFFFFFFF : 0; +} + /* ------------ Normal addition ------------ */ @@ -2228,6 +2262,77 @@ ULong calculate_punpckldq ( ULong dst, ULong src ) ); } +/* ------------ Shifting ------------ */ + +ULong calculate_shl16x4 ( ULong xx, ULong yy ) +{ + return mk16x4( + shl16( sel16x4_3(xx), sel16x4_3(yy) ), + shl16( sel16x4_2(xx), sel16x4_2(yy) ), + shl16( sel16x4_1(xx), sel16x4_1(yy) ), + shl16( sel16x4_0(xx), sel16x4_0(yy) ) + ); +} + +ULong calculate_shl32x2 ( ULong xx, ULong yy ) +{ + return mk32x2( + shl32( sel32x2_1(xx), sel32x2_1(yy) ), + shl32( sel32x2_0(xx), sel32x2_0(yy) ) + ); +} + + +ULong calculate_shl64x1 ( ULong xx, ULong yy ) +{ + if (yy > 63) return 0; + return xx << yy; +} + +ULong calculate_shr16Ux4 ( ULong xx, ULong yy ) +{ + return mk16x4( + shr16U( sel16x4_3(xx), sel16x4_3(yy) ), + shr16U( sel16x4_2(xx), sel16x4_2(yy) ), + shr16U( sel16x4_1(xx), sel16x4_1(yy) ), + shr16U( sel16x4_0(xx), sel16x4_0(yy) ) + ); +} + +ULong calculate_shr32Ux2 ( ULong xx, ULong yy ) +{ + return mk32x2( + shr32U( sel32x2_1(xx), sel32x2_1(yy) ), + shr32U( sel32x2_0(xx), sel32x2_0(yy) ) + ); +} + +ULong calculate_shr64Ux1 ( ULong xx, ULong yy ) +{ + if (yy > 63) return 0; + return xx >> yy; +} + + +ULong calculate_shr16Sx4 ( ULong xx, ULong yy ) +{ + return mk16x4( + shr16S( sel16x4_3(xx), sel16x4_3(yy) ), + shr16S( sel16x4_2(xx), sel16x4_2(yy) ), + shr16S( sel16x4_1(xx), sel16x4_1(yy) ), + shr16S( sel16x4_0(xx), sel16x4_0(yy) ) + ); +} + +ULong calculate_shr32Sx2 ( ULong xx, ULong yy ) +{ + return mk32x2( + shr32S( sel32x2_1(xx), sel32x2_1(yy) ), + shr32S( sel32x2_0(xx), sel32x2_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 1d4c541b07..a3fbdd2406 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -4692,6 +4692,17 @@ UInt dis_MMXop_regmem_to_reg ( UChar sorb, case 0x61: XXX(calculate_punpcklwd); break; case 0x62: XXX(calculate_punpckldq); break; + case 0xF1: XXX(calculate_shl16x4); break; + case 0xF2: XXX(calculate_shl32x2); break; + case 0xF3: XXX(calculate_shl64x1); break; + + case 0xD1: XXX(calculate_shr16Ux4); break; + case 0xD2: XXX(calculate_shr32Ux2); break; + case 0xD3: XXX(calculate_shr64Ux1); break; + + case 0xE1: XXX(calculate_shr16Sx4); break; + case 0xE2: XXX(calculate_shr32Sx2); break; + case 0xDB: break; /* AND */ case 0xDF: break; /* ANDN */ case 0xEB: break; /* OR */ @@ -4929,6 +4940,26 @@ UInt dis_MMX ( Bool* decode_ok, UChar sorb, Int sz, UInt delta ) delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "pxor", False ); break; + case 0xF1: + case 0xF2: + case 0xF3: /* PSLLgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psll", True ); + break; + + case 0xD1: + case 0xD2: + case 0xD3: /* PSRLgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psrl", True ); + break; + + case 0xE1: + case 0xE2: /* PSRAgg (src)mmxreg-or-mem, (dst)mmxreg */ + vassert(sz == 4); + delta = dis_MMXop_regmem_to_reg ( sorb, delta, opc, "psra", True ); + break; + default: *decode_ok = False; return delta; /* ignored */ @@ -9478,12 +9509,6 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, //-- break; //-- } //-- -//-- case 0x77: /* EMMS */ -//-- vg_assert(sz == 4); -//-- uInstr1(cb, MMX1, 0, Lit16, ((UShort)(opc)) ); -//-- DIP("emms\n"); -//-- break; -//-- //-- case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */ //-- vg_assert(sz == 4); //-- modrm = getUChar(eip); @@ -9589,6 +9614,17 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, case 0xEB: /* POR (src)mmxreg-or-mem, (dst)mmxreg */ case 0xEF: /* PXOR (src)mmxreg-or-mem, (dst)mmxreg */ + case 0xF1: + case 0xF2: + case 0xF3: /* PSLLgg (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0xD1: + case 0xD2: + case 0xD3: /* PSRLgg (src)mmxreg-or-mem, (dst)mmxreg */ + + case 0xE1: + case 0xE2: /* PSRAgg (src)mmxreg-or-mem, (dst)mmxreg */ + case 0x6F: /* MOVQ (src)mmxreg-or-mem, (dst)mmxreg */ { UInt delta0 = delta-1; @@ -9601,6 +9637,12 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, break; } + case 0x77: /* EMMS */ + vassert(sz == 4); + do_EMMS_boilerplate(); + DIP("emms\n"); + break; + //-- case 0x7F: /* MOVQ (src)mmxreg, (dst)mmxreg-or-mem */ //-- case 0xE7: /* MOVNTQ (src)mmxreg, (dst)mmxreg-or-mem */ //-- vg_assert(sz == 4);