|
From: <sv...@va...> - 2005-05-09 22:23:45
|
Author: sewardj
Date: 2005-05-09 23:23:38 +0100 (Mon, 09 May 2005)
New Revision: 1175
Modified:
trunk/priv/guest-amd64/toIR.c
Log:
Finish off amd64 MMX instructions before they finish me off (it's
either them or me). Honestly, the amd64 insn set has the most complex
encoding I have ever seen.
Modified: trunk/priv/guest-amd64/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/toIR.c 2005-05-09 18:15:21 UTC (rev 1174)
+++ trunk/priv/guest-amd64/toIR.c 2005-05-09 22:23:38 UTC (rev 1175)
@@ -6085,62 +6085,62 @@
}
=20
=20
-//.. /* Vector by scalar shift of E by an immediate byte. This is a
-//.. straight copy of dis_SSE_shiftE_imm. */
-//..=20
-//.. static=20
-//.. UInt dis_MMX_shiftE_imm ( ULong delta, HChar* opname, IROp op )
-//.. {
-//.. Bool shl, shr, sar;
-//.. UChar rm =3D getUChar(delta);
-//.. IRTemp e0 =3D newTemp(Ity_I64);
-//.. IRTemp e1 =3D newTemp(Ity_I64);
-//.. UChar amt, size;
-//.. vassert(epartIsReg(rm));
-//.. vassert(gregOfRM(rm) =3D=3D 2=20
-//.. || gregOfRM(rm) =3D=3D 4 || gregOfRM(rm) =3D=3D 6);
-//.. amt =3D (Int)(getUChar(delta+1));
-//.. delta +=3D 2;
-//.. DIP("%s $%d,%s\n", opname,
-//.. (Int)amt,
-//.. nameMMXReg(eregOfRM(rm)) );
-//..=20
-//.. assign( e0, getMMXReg(eregOfRM(rm)) );
-//..=20
-//.. shl =3D shr =3D sar =3D False;
-//.. size =3D 0;
-//.. switch (op) {
-//.. case Iop_ShlN16x4: shl =3D True; size =3D 16; break;
-//.. case Iop_ShlN32x2: shl =3D True; size =3D 32; break;
-//.. case Iop_Shl64: shl =3D True; size =3D 64; break;
-//.. case Iop_SarN16x4: sar =3D True; size =3D 16; break;
-//.. case Iop_SarN32x2: sar =3D True; size =3D 32; break;
-//.. case Iop_ShrN16x4: shr =3D True; size =3D 16; break;
-//.. case Iop_ShrN32x2: shr =3D True; size =3D 32; break;
-//.. case Iop_Shr64: shr =3D True; size =3D 64; break;
-//.. default: vassert(0);
-//.. }
-//..=20
-//.. if (shl || shr) {
-//.. assign( e1, amt >=3D size=20
-//.. ? mkU64(0)
-//.. : binop(op, mkexpr(e0), mkU8(amt))
-//.. );
-//.. } else=20
-//.. if (sar) {
-//.. assign( e1, amt >=3D size=20
-//.. ? binop(op, mkexpr(e0), mkU8(size-1))
-//.. : binop(op, mkexpr(e0), mkU8(amt))
-//.. );
-//.. } else {
-//.. vassert(0);
-//.. }
-//..=20
-//.. putMMXReg( eregOfRM(rm), mkexpr(e1) );
-//.. return delta;
-//.. }
+/* Vector by scalar shift of E by an immediate byte. This is a
+ straight copy of dis_SSE_shiftE_imm. */
=20
+static=20
+ULong dis_MMX_shiftE_imm ( ULong delta, HChar* opname, IROp op )
+{
+ Bool shl, shr, sar;
+ UChar rm =3D getUChar(delta);
+ IRTemp e0 =3D newTemp(Ity_I64);
+ IRTemp e1 =3D newTemp(Ity_I64);
+ UChar amt, size;
+ vassert(epartIsReg(rm));
+ vassert(gregLO3ofRM(rm) =3D=3D 2=20
+ || gregLO3ofRM(rm) =3D=3D 4 || gregLO3ofRM(rm) =3D=3D 6);
+ amt =3D (Int)(getUChar(delta+1));
+ delta +=3D 2;
+ DIP("%s $%d,%s\n", opname,
+ (Int)amt,
+ nameMMXReg(eregLO3ofRM(rm)) );
=20
+ assign( e0, getMMXReg(eregLO3ofRM(rm)) );
+
+ shl =3D shr =3D sar =3D False;
+ size =3D 0;
+ switch (op) {
+ case Iop_ShlN16x4: shl =3D True; size =3D 16; break;
+ case Iop_ShlN32x2: shl =3D True; size =3D 32; break;
+ case Iop_Shl64: shl =3D True; size =3D 64; break;
+ case Iop_SarN16x4: sar =3D True; size =3D 16; break;
+ case Iop_SarN32x2: sar =3D True; size =3D 32; break;
+ case Iop_ShrN16x4: shr =3D True; size =3D 16; break;
+ case Iop_ShrN32x2: shr =3D True; size =3D 32; break;
+ case Iop_Shr64: shr =3D True; size =3D 64; break;
+ default: vassert(0);
+ }
+
+ if (shl || shr) {
+ assign( e1, amt >=3D size=20
+ ? mkU64(0)
+ : binop(op, mkexpr(e0), mkU8(amt))
+ );
+ } else=20
+ if (sar) {
+ assign( e1, amt >=3D size=20
+ ? binop(op, mkexpr(e0), mkU8(size-1))
+ : binop(op, mkexpr(e0), mkU8(amt))
+ );
+ } else {
+ vassert(0);
+ }
+
+ putMMXReg( eregLO3ofRM(rm), mkexpr(e1) );
+ return delta;
+}
+
+
/* Completely handle all MMX instructions except emms. */
=20
static
@@ -6157,51 +6157,97 @@
=20
switch (opc) {
=20
-//.. case 0x6E:=20
-//.. /* MOVD (src)ireg-or-mem (E), (dst)mmxreg (G)*/
-//.. if (sz !=3D 4)=20
-//.. goto mmx_decode_failure;
-//.. modrm =3D getUChar(delta);
-//.. if (epartIsReg(modrm)) {
-//.. delta++;
-//.. putMMXReg(
-//.. gregOfRM(modrm),
-//.. binop( Iop_32HLto64,
-//.. mkU32(0),
-//.. getIReg(4, eregOfRM(modrm)) ) );
-//.. DIP("movd %s, %s\n",=20
-//.. nameIReg(4,eregOfRM(modrm)), nameMMXReg(gregOfRM(mo=
drm)));
-//.. } else {
-//.. IRTemp addr =3D disAMode( &len, sorb, delta, dis_buf );
-//.. delta +=3D len;
-//.. putMMXReg(
-//.. gregOfRM(modrm),
-//.. binop( Iop_32HLto64,
-//.. mkU32(0),
-//.. loadLE(Ity_I32, mkexpr(addr)) ) );
-//.. DIP("movd %s, %s\n", dis_buf, nameMMXReg(gregOfRM(modrm=
)));
-//.. }
-//.. break;
-//..=20
-//.. case 0x7E: /* MOVD (src)mmxreg (G), (dst)ireg-or-mem (E) */
-//.. if (sz !=3D 4)=20
-//.. goto mmx_decode_failure;
-//.. modrm =3D getUChar(delta);
-//.. if (epartIsReg(modrm)) {
-//.. delta++;
-//.. putIReg( 4, eregOfRM(modrm),
-//.. unop(Iop_64to32, getMMXReg(gregOfRM(modrm)) ) =
);
-//.. DIP("movd %s, %s\n",=20
-//.. nameMMXReg(gregOfRM(modrm)), nameIReg(4,eregOfRM(mo=
drm)));
-//.. } else {
-//.. IRTemp addr =3D disAMode( &len, sorb, delta, dis_buf );
-//.. delta +=3D len;
-//.. storeLE( mkexpr(addr),
-//.. unop(Iop_64to32, getMMXReg(gregOfRM(modrm)) ) =
);
-//.. DIP("movd %s, %s\n", nameMMXReg(gregOfRM(modrm)), dis_b=
uf);
-//.. }
-//.. break;
+ case 0x6E:=20
+ if (sz =3D=3D 4) {
+ /* MOVD (src)ireg32-or-mem32 (E), (dst)mmxreg (G)*/
+ modrm =3D getUChar(delta);
+ if (epartIsReg(modrm)) {
+ delta++;
+ putMMXReg(
+ gregLO3ofRM(modrm),
+ binop( Iop_32HLto64,
+ mkU32(0),
+ getIReg32(eregOfRexRM(pfx,modrm)) ) );
+ DIP("movd %s, %s\n",=20
+ nameIReg32(eregOfRexRM(pfx,modrm)),=20
+ nameMMXReg(gregLO3ofRM(modrm)));
+ } else {
+ IRTemp addr =3D disAMode( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ putMMXReg(
+ gregLO3ofRM(modrm),
+ binop( Iop_32HLto64,
+ mkU32(0),
+ loadLE(Ity_I32, mkexpr(addr)) ) );
+ DIP("movd %s, %s\n", dis_buf, nameMMXReg(gregLO3ofRM(modr=
m)));
+ }
+ }=20
+ else
+ if (sz =3D=3D 8) {
+ /* MOVD (src)ireg64-or-mem64 (E), (dst)mmxreg (G)*/
+ modrm =3D getUChar(delta);
+ if (epartIsReg(modrm)) {
+ delta++;
+ putMMXReg( gregLO3ofRM(modrm),
+ getIReg64(eregOfRexRM(pfx,modrm)) );
+ DIP("movd %s, %s\n",=20
+ nameIReg64(eregOfRexRM(pfx,modrm)),=20
+ nameMMXReg(gregLO3ofRM(modrm)));
+ } else {
+ IRTemp addr =3D disAMode( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ putMMXReg( gregLO3ofRM(modrm),
+ loadLE(Ity_I64, mkexpr(addr)) );
+ DIP("movd{64} %s, %s\n", dis_buf, nameMMXReg(gregLO3ofRM(=
modrm)));
+ }
+ }
+ else {
+ goto mmx_decode_failure;
+ }
+ break;
=20
+ case 0x7E:
+ if (sz =3D=3D 4) {
+ /* MOVD (src)mmxreg (G), (dst)ireg32-or-mem32 (E) */
+ modrm =3D getUChar(delta);
+ if (epartIsReg(modrm)) {
+ delta++;
+ putIReg32( eregOfRexRM(pfx,modrm),
+ unop(Iop_64to32, getMMXReg(gregLO3ofRM(modrm))=
) );
+ DIP("movd %s, %s\n",=20
+ nameMMXReg(gregLO3ofRM(modrm)),=20
+ nameIReg32(eregOfRexRM(pfx,modrm)));
+ } else {
+ IRTemp addr =3D disAMode( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ storeLE( mkexpr(addr),
+ unop(Iop_64to32, getMMXReg(gregLO3ofRM(modrm)) )=
);
+ DIP("movd %s, %s\n", nameMMXReg(gregLO3ofRM(modrm)), dis_=
buf);
+ }
+ }
+ else
+ if (sz =3D=3D 8) {
+ /* MOVD (src)mmxreg (G), (dst)ireg64-or-mem64 (E) */
+ modrm =3D getUChar(delta);
+ if (epartIsReg(modrm)) {
+ delta++;
+ putIReg64( eregOfRexRM(pfx,modrm),
+ getMMXReg(gregLO3ofRM(modrm)) );
+ DIP("movd %s, %s\n",=20
+ nameMMXReg(gregLO3ofRM(modrm)),=20
+ nameIReg64(eregOfRexRM(pfx,modrm)));
+ } else {
+ IRTemp addr =3D disAMode( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ storeLE( mkexpr(addr),
+ getMMXReg(gregLO3ofRM(modrm)) );
+ DIP("movd{64} %s, %s\n", nameMMXReg(gregLO3ofRM(modrm)), =
dis_buf);
+ }
+ } else {
+ goto mmx_decode_failure;
+ }
+ break;
+
case 0x6F:
/* MOVQ (src)mmxreg-or-mem, (dst)mmxreg */
if (sz !=3D 4)=20
@@ -6394,54 +6440,47 @@
case 0xE2: SHIFT_BY_REG("psrad", Iop_SarN32x2);
=20
# undef SHIFT_BY_REG
-//..=20
-//.. case 0x71:=20
-//.. case 0x72:=20
-//.. case 0x73: {
-//.. /* (sz=3D=3D4): PSLLgg/PSRAgg/PSRLgg mmxreg by imm8 */
-//.. UChar byte1, byte2, subopc;
-//.. void* hAddr;
-//.. Char* hName;
-//.. if (sz !=3D 4)=20
-//.. goto mmx_decode_failure;
-//.. byte1 =3D opc; /* 0x71/72/73 */
-//.. byte2 =3D getUChar(delta); /* amode / sub-opcod=
e */
-//.. subopc =3D (byte2 >> 3) & 7;
-//..=20
-#if 0 /* stop gcc multi-line comment warning */
-/.. # define SHIFT_BY_IMM(_name,_op) \
-/.. do { delta =3D dis_MMX_shiftE_imm(delta,_name,_op); \
-/.. } while (0)
-#endif /* stop gcc multi-line comment warning */
-//..=20
-//.. hAddr =3D NULL;
-//.. hName =3D NULL;
-//..=20
-//.. if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x71)=20
-//.. SHIFT_BY_IMM("psrlw", Iop_ShrN16x4);
-//.. else if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x72)=20
-//.. SHIFT_BY_IMM("psrld", Iop_ShrN32x2);
-//.. else if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x73)=20
-//.. SHIFT_BY_IMM("psrlq", Iop_Shr64);
-//..=20
-//.. else if (subopc =3D=3D 4 /*SAR*/ && opc =3D=3D 0x71)=20
-//.. SHIFT_BY_IMM("psraw", Iop_SarN16x4);
-//.. else if (subopc =3D=3D 4 /*SAR*/ && opc =3D=3D 0x72)=20
-//.. SHIFT_BY_IMM("psrad", Iop_SarN32x2);
-//..=20
-//.. else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x71)=20
-//.. SHIFT_BY_IMM("psllw", Iop_ShlN16x4);
-//.. else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x72)=20
-//.. SHIFT_BY_IMM("pslld", Iop_ShlN32x2);
-//.. else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x73)=20
-//.. SHIFT_BY_IMM("psllq", Iop_Shl64);
-//..=20
-//.. else goto mmx_decode_failure;
-//..=20
-//.. # undef SHIFT_BY_IMM
-//.. break;
-//.. }
=20
+ case 0x71:=20
+ case 0x72:=20
+ case 0x73: {
+ /* (sz=3D=3D4): PSLLgg/PSRAgg/PSRLgg mmxreg by imm8 */
+ UChar byte1, byte2, subopc;
+ if (sz !=3D 4)=20
+ goto mmx_decode_failure;
+ byte1 =3D opc; /* 0x71/72/73 */
+ byte2 =3D getUChar(delta); /* amode / sub-opcode */
+ subopc =3D (byte2 >> 3) & 7;
+
+# define SHIFT_BY_IMM(_name,_op) \
+ do { delta =3D dis_MMX_shiftE_imm(delta,_name,_op); \
+ } while (0)
+
+ if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x71)=20
+ SHIFT_BY_IMM("psrlw", Iop_ShrN16x4);
+ else if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x72)=20
+ SHIFT_BY_IMM("psrld", Iop_ShrN32x2);
+ else if (subopc =3D=3D 2 /*SRL*/ && opc =3D=3D 0x73)=20
+ SHIFT_BY_IMM("psrlq", Iop_Shr64);
+
+ else if (subopc =3D=3D 4 /*SAR*/ && opc =3D=3D 0x71)=20
+ SHIFT_BY_IMM("psraw", Iop_SarN16x4);
+ else if (subopc =3D=3D 4 /*SAR*/ && opc =3D=3D 0x72)=20
+ SHIFT_BY_IMM("psrad", Iop_SarN32x2);
+
+ else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x71)=20
+ SHIFT_BY_IMM("psllw", Iop_ShlN16x4);
+ else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x72)=20
+ SHIFT_BY_IMM("pslld", Iop_ShlN32x2);
+ else if (subopc =3D=3D 6 /*SHL*/ && opc =3D=3D 0x73)=20
+ SHIFT_BY_IMM("psllq", Iop_Shl64);
+
+ else goto mmx_decode_failure;
+
+# undef SHIFT_BY_IMM
+ break;
+ }
+
/* --- MMX decode failure --- */
default:
mmx_decode_failure:
@@ -13277,12 +13316,12 @@
=20
/* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- MMXery =3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D-=3D-=3D-=3D */
=20
-//.. case 0x71:=20
-//.. case 0x72:=20
-//.. case 0x73: /* PSLLgg/PSRAgg/PSRLgg mmxreg by imm8 */
-//..=20
-//.. case 0x6E: /* MOVD (src)ireg-or-mem, (dst)mmxreg */
-//.. case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */
+ case 0x71:=20
+ case 0x72:=20
+ case 0x73: /* PSLLgg/PSRAgg/PSRLgg mmxreg by imm8 */
+
+ case 0x6E: /* MOVD (src)ireg-or-mem, (dst)mmxreg */
+ case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */
case 0x7F: /* MOVQ (src)mmxreg, (dst)mmxreg-or-mem */
case 0x6F: /* MOVQ (src)mmxreg-or-mem, (dst)mmxreg */
=20
@@ -13352,7 +13391,7 @@
=20
/* If sz=3D=3D2 this is SSE, and we assume sse idec has
already spotted those cases by now. */
- if (sz !=3D 4)
+ if (sz !=3D 4 && sz !=3D 8)
goto decode_failure;
if (have66orF2orF3(pfx))
goto decode_failure;
|