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 --- */
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 ------------ */
);
}
+/* ------------ 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 ---*/
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 */
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 */
//-- 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);
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;
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);