|
From: <sv...@va...> - 2005-05-14 11:17:31
|
Author: sewardj
Date: 2005-05-14 12:17:25 +0100 (Sat, 14 May 2005)
New Revision: 1198
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/guest-x86/toIR.c
Log:
Fix behaviour of MOVQ on amd64.
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-14 02:04:12 UTC (rev 1197)
+++ trunk/priv/guest-amd64/toIR.c 2005-05-14 11:17:25 UTC (rev 1198)
@@ -42,13 +42,6 @@
disInstr for details.
*/
=20
-/* TODO:
-
- MOVQ (sse) is wrong wrt is the upper half zeroed or not?
- It always should be if dst is a reg; not quite the same
- as MOVSD.
-*/
-
//.. /* TODO:
//..=20
//.. check flag settings for cmpxchg
@@ -8081,39 +8074,6 @@
SSE2 as a minimum so there is no point distinguishing SSE1 vs
SSE2. */
=20
- /* There are just so many damn SSE insns, and amongst them are a
- large number of data-move insns, many of which seem almost
- identical. Here's a statement of the behaviour of MOVQ, MOVSD,
- MOVD, MOVSS. It doesn't help that the Intel manuals are less
- than accurate about these. The AMD docs seem OK tho.=20
-
- The following is true for both x86 and amd64. MOVQ and MOVSD
- shunt 64-bit things around. r is an xmm register and m is
- memory.
-
- MOVQ r <- r lo64 moved; hi64 set to zero
- MOVQ m <- r lo64 moved
- MOVQ r <- m lo64 moved; hi64 set to zero
-
- MOVSD r <- r lo64 moved; hi64 unchanged
- MOVSD m <- r lo64 moved
- MOVSD r <- m lo64 moved; hi64 set to zero
-
- MOVD and MOVSS shunt 32-bit things around, and are exactly
- analogous:
-
- MOVD r <- r lo32 moved; hi96 set to zero
- MOVD m <- r lo32 moved
- MOVD r <- m lo32 moved; hi96 set to zero
-
- MOVSS r <- r lo32 moved; hi96 unchanged
- MOVSS m <- r lo32 moved
- MOVSS r <- m lo32 moved; hi96 set to zero
-
- For MOVQ and MOVD, the r <- r rules apply even if the source r
- is instead an integer register.
- */
-
insn =3D (UChar*)&guest_code[delta];
=20
//.. /* Treat fxsave specially. It should be doable even on an SSE0
@@ -10266,6 +10226,7 @@
modrm =3D getUChar(delta+2);
if (epartIsReg(modrm)) {
/* fall through, awaiting test case */
+ /* dst: lo half copied, hi half zeroed */
} else {
addr =3D disAMode ( &alen, pfx, delta+2, dis_buf, 0 );
storeLE( mkexpr(addr),=20
@@ -10296,10 +10257,10 @@
}
=20
/* F3 0F 7E =3D MOVQ -- move 64 bits from E (mem or lo half xmm) to
- G (lo half xmm). If E is mem, upper half of G is zeroed out. */
+ G (lo half xmm). Upper half of G is zeroed out. */
/* F2 0F 10 =3D MOVSD -- move 64 bits from E (mem or lo half xmm) to
G (lo half xmm). If E is mem, upper half of G is zeroed out.
- (original defn) */
+ If E is reg, upper half of G is unchanged. */
if ( (haveF2no66noF3(pfx) && sz =3D=3D 4=20
&& insn[0] =3D=3D 0x0F && insn[1] =3D=3D 0x10)
||=20
@@ -10310,6 +10271,10 @@
if (epartIsReg(modrm)) {
putXMMRegLane64( gregOfRexRM(pfx,modrm), 0,
getXMMRegLane64( eregOfRexRM(pfx,modrm), 0 ));
+ if (insn[1] =3D=3D 0x7E/*MOVQ*/) {
+ /* zero bits 127:64 */
+ putXMMRegLane64( gregOfRexRM(pfx,modrm), 1, mkU64(0) );
+ }
DIP("movsd %s,%s\n", nameXMMReg(eregOfRexRM(pfx,modrm)),
nameXMMReg(gregOfRexRM(pfx,modrm)));
delta +=3D 2+1;
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 2005-05-14 02:04:12 UTC (rev 1197)
+++ trunk/priv/guest-x86/toIR.c 2005-05-14 11:17:25 UTC (rev 1198)
@@ -35,11 +35,6 @@
=20
/* TODO:
=20
- Check the following. It afflicts the amd64 front end, not sure if
- applicable here: MOVQ (sse) is wrong wrt is the upper half zeroed
- or not? It always should be if dst is a reg; not quite the same as
- MOVSD.
-
check flag settings for cmpxchg
FUCOMI(P): what happens to A and S flags? Currently are forced
to zero.
|