|
From: <sv...@va...> - 2006-08-03 15:03:23
|
Author: sewardj
Date: 2006-08-03 16:03:19 +0100 (Thu, 03 Aug 2006)
New Revision: 1635
Log:
Handle all SSE3 instructions except monitor and mwait. 64-bit
equivalents to follow soon.
Modified:
trunk/priv/guest-x86/toIR.c
Modified: trunk/priv/guest-x86/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-x86/toIR.c 2006-08-01 18:36:25 UTC (rev 1634)
+++ trunk/priv/guest-x86/toIR.c 2006-08-03 15:03:19 UTC (rev 1635)
@@ -4274,6 +4274,13 @@
loadLE(Ity_I32, mkexpr(addr))));
break;
=20
+ case 1: /* FISTTPL m32 (SSE3) */
+ DIP("fisttpl %s\n", dis_buf);
+ storeLE( mkexpr(addr),=20
+ binop(Iop_F64toI32, mkU32(Irrm_ZERO), get_ST(0))=
);
+ fp_pop();
+ break;
+
case 2: /* FIST m32 */
DIP("fistl %s\n", dis_buf);
storeLE( mkexpr(addr),=20
@@ -4576,6 +4583,13 @@
put_ST(0, loadLE(Ity_F64, mkexpr(addr)));
break;
=20
+ case 1: /* FISTTPQ m64 (SSE3) */
+ DIP("fistppll %s\n", dis_buf);
+ storeLE( mkexpr(addr),=20
+ binop(Iop_F64toI64, mkU32(Irrm_ZERO), get_ST(0))=
);
+ fp_pop();
+ break;
+
case 2: /* FST double-real */
DIP("fstl %s\n", dis_buf);
storeLE(mkexpr(addr), get_ST(0));
@@ -4939,6 +4953,13 @@
loadLE(Ity_I16, mkexpr(addr)))));
break;
=20
+ case 1: /* FISTTPS m16 (SSE3) */
+ DIP("fisttps %s\n", dis_buf);
+ storeLE( mkexpr(addr),=20
+ binop(Iop_F64toI16, mkU32(Irrm_ZERO), get_ST(0))=
);
+ fp_pop();
+ break;
+
case 2: /* FIST m16 */
DIP("fistp %s\n", dis_buf);
storeLE( mkexpr(addr),=20
@@ -10603,6 +10624,31 @@
goto decode_success;
}
=20
+ /* F2 0F 12 =3D MOVDDUP -- move from E (mem or xmm) to G (xmm),
+ duplicating some lanes (0:1:0:1). */
+ if (sz =3D=3D 4 && insn[0] =3D=3D 0xF2 && insn[1] =3D=3D 0x0F && insn=
[2] =3D=3D 0x12) {
+ IRTemp sV =3D newTemp(Ity_V128);
+ IRTemp d0 =3D newTemp(Ity_I64);
+
+ modrm =3D insn[3];
+ if (epartIsReg(modrm)) {
+ assign( sV, getXMMReg( eregOfRM(modrm)) );
+ DIP("movddup %s,%s\n", nameXMMReg(eregOfRM(modrm)),
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 3+1;
+ assign ( d0, unop(Iop_V128to64, mkexpr(sV)) );
+ } else {
+ addr =3D disAMode ( &alen, sorb, delta+3, dis_buf );
+ assign( d0, loadLE(Ity_I64, mkexpr(addr)) );
+ DIP("movddup %s,%s\n", dis_buf,
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 3+alen;
+ }
+
+ putXMMReg( gregOfRM(modrm), binop(Iop_64HLtoV128,mkexpr(d0),mkexpr=
(d0)) );
+ goto decode_success;
+ }
+
/* F2 0F D0 =3D ADDSUBPS -- 32x4 +/-/+/- from E (mem or xmm) to G (xm=
m). */
if (sz =3D=3D 4 && insn[0] =3D=3D 0xF2 && insn[1] =3D=3D 0x0F && insn=
[2] =3D=3D 0xD0) {
IRTemp a3, a2, a1, a0, s3, s2, s1, s0;
@@ -10638,6 +10684,143 @@
goto decode_success;
}
=20
+ /* 66 0F D0 =3D ADDSUBPD -- 64x4 +/- from E (mem or xmm) to G (xmm). =
*/
+ if (sz =3D=3D 2 && insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0xD0) {
+ IRTemp eV =3D newTemp(Ity_V128);
+ IRTemp gV =3D newTemp(Ity_V128);
+ IRTemp addV =3D newTemp(Ity_V128);
+ IRTemp subV =3D newTemp(Ity_V128);
+ IRTemp a1 =3D newTemp(Ity_I64);
+ IRTemp s0 =3D newTemp(Ity_I64);
+
+ modrm =3D insn[2];
+ if (epartIsReg(modrm)) {
+ assign( eV, getXMMReg( eregOfRM(modrm)) );
+ DIP("addsubpd %s,%s\n", nameXMMReg(eregOfRM(modrm)),
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 2+1;
+ } else {
+ addr =3D disAMode ( &alen, sorb, delta+2, dis_buf );
+ assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
+ DIP("addsubpd %s,%s\n", dis_buf,
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 2+alen;
+ }
+
+ assign( gV, getXMMReg(gregOfRM(modrm)) );
+
+ assign( addV, binop(Iop_Add64Fx2, mkexpr(gV), mkexpr(eV)) );
+ assign( subV, binop(Iop_Sub64Fx2, mkexpr(gV), mkexpr(eV)) );
+
+ assign( a1, unop(Iop_V128HIto64, mkexpr(addV) ));
+ assign( s0, unop(Iop_V128to64, mkexpr(subV) ));
+
+ putXMMReg( gregOfRM(modrm),=20
+ binop(Iop_64HLtoV128, mkexpr(a1), mkexpr(s0)) );
+ goto decode_success;
+ }
+
+ /* F2 0F 7D =3D HSUBPS -- 32x4 sub across from E (mem or xmm) to G (x=
mm). */
+ /* F2 0F 7C =3D HADDPS -- 32x4 add across from E (mem or xmm) to G (x=
mm). */
+ if (sz =3D=3D 4 && insn[0] =3D=3D 0xF2 && insn[1] =3D=3D 0x0F=20
+ && (insn[2] =3D=3D 0x7C || insn[2] =3D=3D 0x7D)) {
+ IRTemp e3, e2, e1, e0, g3, g2, g1, g0;
+ IRTemp eV =3D newTemp(Ity_V128);
+ IRTemp gV =3D newTemp(Ity_V128);
+ IRTemp leftV =3D newTemp(Ity_V128);
+ IRTemp rightV =3D newTemp(Ity_V128);
+ Bool isAdd =3D insn[2] =3D=3D 0x7C;
+ HChar* str =3D isAdd ? "add" : "sub";
+ e3 =3D e2 =3D e1 =3D e0 =3D g3 =3D g2 =3D g1 =3D g0 =3D IRTemp_INV=
ALID;
+
+ modrm =3D insn[3];
+ if (epartIsReg(modrm)) {
+ assign( eV, getXMMReg( eregOfRM(modrm)) );
+ DIP("h%sps %s,%s\n", str, nameXMMReg(eregOfRM(modrm)),
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 3+1;
+ } else {
+ addr =3D disAMode ( &alen, sorb, delta+3, dis_buf );
+ assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
+ DIP("h%sps %s,%s\n", str, dis_buf,
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 3+alen;
+ }
+
+ assign( gV, getXMMReg(gregOfRM(modrm)) );
+
+ breakup128to32s( eV, &e3, &e2, &e1, &e0 );
+ breakup128to32s( gV, &g3, &g2, &g1, &g0 );
+
+ assign( leftV, mk128from32s( e2, e0, g2, g0 ) );
+ assign( rightV, mk128from32s( e3, e1, g3, g1 ) );
+
+ putXMMReg( gregOfRM(modrm),=20
+ binop(isAdd ? Iop_Add32Fx4 : Iop_Sub32Fx4,=20
+ mkexpr(leftV), mkexpr(rightV) ) );
+ goto decode_success;
+ }
+
+ /* 66 0F 7D =3D HSUBPD -- 64x2 sub across from E (mem or xmm) to G (x=
mm). */
+ /* 66 0F 7C =3D HADDPD -- 64x2 add across from E (mem or xmm) to G (x=
mm). */
+ if (sz =3D=3D 2 && insn[0] =3D=3D 0x0F && (insn[1] =3D=3D 0x7C || ins=
n[1] =3D=3D 0x7D)) {
+ IRTemp e1 =3D newTemp(Ity_I64);
+ IRTemp e0 =3D newTemp(Ity_I64);
+ IRTemp g1 =3D newTemp(Ity_I64);
+ IRTemp g0 =3D newTemp(Ity_I64);
+ IRTemp eV =3D newTemp(Ity_V128);
+ IRTemp gV =3D newTemp(Ity_V128);
+ IRTemp leftV =3D newTemp(Ity_V128);
+ IRTemp rightV =3D newTemp(Ity_V128);
+ Bool isAdd =3D insn[1] =3D=3D 0x7C;
+ HChar* str =3D isAdd ? "add" : "sub";
+
+ modrm =3D insn[2];
+ if (epartIsReg(modrm)) {
+ assign( eV, getXMMReg( eregOfRM(modrm)) );
+ DIP("h%spd %s,%s\n", str, nameXMMReg(eregOfRM(modrm)),
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 2+1;
+ } else {
+ addr =3D disAMode ( &alen, sorb, delta+2, dis_buf );
+ assign( eV, loadLE(Ity_V128, mkexpr(addr)) );
+ DIP("h%spd %s,%s\n", str, dis_buf,
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 2+alen;
+ }
+
+ assign( gV, getXMMReg(gregOfRM(modrm)) );
+
+ assign( e1, unop(Iop_V128HIto64, mkexpr(eV) ));
+ assign( e0, unop(Iop_V128to64, mkexpr(eV) ));
+ assign( g1, unop(Iop_V128HIto64, mkexpr(gV) ));
+ assign( g0, unop(Iop_V128to64, mkexpr(gV) ));
+
+ assign( leftV, binop(Iop_64HLtoV128, mkexpr(e0),mkexpr(g0)) );
+ assign( rightV, binop(Iop_64HLtoV128, mkexpr(e1),mkexpr(g1)) );
+
+ putXMMReg( gregOfRM(modrm),=20
+ binop(isAdd ? Iop_Add64Fx2 : Iop_Sub64Fx2,=20
+ mkexpr(leftV), mkexpr(rightV) ) );
+ goto decode_success;
+ }
+
+ /* F2 0F F0 =3D LDDQU -- move from E (mem or xmm) to G (xmm). */
+ if (sz =3D=3D 4 && insn[0] =3D=3D 0xF2 && insn[1] =3D=3D 0x0F && insn=
[2] =3D=3D 0xF0) {
+ modrm =3D getIByte(delta+3);
+ if (epartIsReg(modrm)) {
+ goto decode_failure;
+ } else {
+ addr =3D disAMode ( &alen, sorb, delta+3, dis_buf );
+ putXMMReg( gregOfRM(modrm),=20
+ loadLE(Ity_V128, mkexpr(addr)) );
+ DIP("lddqu %s,%s\n", dis_buf,
+ nameXMMReg(gregOfRM(modrm)));
+ delta +=3D 3+alen;
+ }
+ goto decode_success;
+ }
+
/* ---------------------------------------------------- */
/* --- end of the SSE3 decoder. --- */
/* ---------------------------------------------------- */
|
|
From: Nicholas N. <nj...@cs...> - 2006-08-04 00:02:55
|
On Thu, 3 Aug 2006 sv...@va... wrote: > Log: > Handle all SSE3 instructions except monitor and mwait. 64-bit > equivalents to follow soon. Are you planning to merge this to the stable branch? I think it's a good idea, it's not strictly a bug-fix but it seems like it would be good to get it out there sooner in 3.2.1 rather than waiting for a 3.3.0 release. Nick |
|
From: Julian S. <js...@ac...> - 2006-08-04 00:13:06
|
> Are you planning to merge this to the stable branch? Yes, definitely. Yes, I'd like to ship 3.2.1 in the next three weeks or so. 3.2.0 seems pretty stable but there have been a couple of things cropped up, not least that the latest binutils completely breaks 3.2.0 by using a new previously unheard-of (at least by me :) form on no-ops on x86 and amd64. Any other specific bugs you think we should try to fix for 3.2.1 ? J |
|
From: Nicholas N. <nj...@cs...> - 2006-08-04 03:41:27
|
On Fri, 4 Aug 2006, Julian Seward wrote: >> Are you planning to merge this to the stable branch? > > Yes, definitely. Yes, I'd like to ship 3.2.1 in the next three weeks > or so. 3.2.0 seems pretty stable but there have been a couple of things > cropped up, not least that the latest binutils completely breaks 3.2.0 > by using a new previously unheard-of (at least by me :) form on no-ops > on x86 and amd64. Good. > Any other specific bugs you think we should try to fix for 3.2.1 ? Nope. Nick |