|
From: <sv...@va...> - 2005-12-23 00:16:29
|
Author: sewardj
Date: 2005-12-23 00:16:24 +0000 (Fri, 23 Dec 2005)
New Revision: 5415
Log:
Handle CmpORD64{U,S} as ppc64 requires those.
Modified:
trunk/memcheck/mc_translate.c
Modified: trunk/memcheck/mc_translate.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/memcheck/mc_translate.c 2005-12-22 23:13:27 UTC (rev 5414)
+++ trunk/memcheck/mc_translate.c 2005-12-23 00:16:24 UTC (rev 5415)
@@ -682,7 +682,7 @@
and similarly the unsigned variant. The default interpretation is:
=20
CmpORD32{S,U}#(x,y,x#,y#) =3D PCast(x# `UifU` y#) =20
- & (7<<1)
+ & (7<<1)
=20
The "& (7<<1)" reflects the fact that all result bits except 3,2,1
are zero and therefore defined (viz, zero).
@@ -695,9 +695,10 @@
will be defined even if the rest of x isn't. In which case we do:
=20
CmpORD32S#(x,x#,0,{impliedly 0}#)
- =3D PCast(x#) & (3<<1) -- standard interp for GT,EQ
- | (x# >> 31) << 3 -- LT =3D x#[31]
+ =3D PCast(x#) & (3<<1) -- standard interp for GT#,EQ#
+ | (x# >>u 31) << 3 -- LT# =3D x#[31]
=20
+ Analogous handling for CmpORD64{S,U}.
*/
static Bool isZeroU32 ( IRAtom* e )
{
@@ -707,56 +708,81 @@
&& e->Iex.Const.con->Ico.U32 =3D=3D 0 );
}
=20
-static IRAtom* doCmpORD32 ( MCEnv* mce,
- IROp cmp_op,
- IRAtom* xxhash, IRAtom* yyhash,=20
- IRAtom* xx, IRAtom* yy )
+static Bool isZeroU64 ( IRAtom* e )
{
+ return
+ toBool( e->tag =3D=3D Iex_Const
+ && e->Iex.Const.con->tag =3D=3D Ico_U64
+ && e->Iex.Const.con->Ico.U64 =3D=3D 0 );
+}
+
+static IRAtom* doCmpORD ( MCEnv* mce,
+ IROp cmp_op,
+ IRAtom* xxhash, IRAtom* yyhash,=20
+ IRAtom* xx, IRAtom* yy )
+{
+ Bool m64 =3D cmp_op =3D=3D Iop_CmpORD64S || cmp_op =3D=3D Iop_Cm=
pORD64U;
+ Bool syned =3D cmp_op =3D=3D Iop_CmpORD64S || cmp_op =3D=3D Iop_Cm=
pORD32S;
+ IROp opOR =3D m64 ? Iop_Or64 : Iop_Or32;
+ IROp opAND =3D m64 ? Iop_And64 : Iop_And32;
+ IROp opSHL =3D m64 ? Iop_Shl64 : Iop_Shl32;
+ IROp opSHR =3D m64 ? Iop_Shr64 : Iop_Shr32;
+ IRType ty =3D m64 ? Ity_I64 : Ity_I32;
+ Int width =3D m64 ? 64 : 32;
+
+ Bool (*isZero)(IRAtom*) =3D m64 ? isZeroU64 : isZeroU32;
+
+ IRAtom* threeLeft1 =3D NULL;
+ IRAtom* sevenLeft1 =3D NULL;
+
tl_assert(isShadowAtom(mce,xxhash));
tl_assert(isShadowAtom(mce,yyhash));
tl_assert(isOriginalAtom(mce,xx));
tl_assert(isOriginalAtom(mce,yy));
tl_assert(sameKindedAtoms(xxhash,xx));
tl_assert(sameKindedAtoms(yyhash,yy));
- tl_assert(cmp_op =3D=3D Iop_CmpORD32S || cmp_op =3D=3D Iop_CmpORD32U)=
;
+ tl_assert(cmp_op =3D=3D Iop_CmpORD32S || cmp_op =3D=3D Iop_CmpORD32U
+ || cmp_op =3D=3D Iop_CmpORD64S || cmp_op =3D=3D Iop_CmpORD6=
4U);
=20
if (0) {
ppIROp(cmp_op); VG_(printf)(" ");=20
ppIRExpr(xx); VG_(printf)(" "); ppIRExpr( yy ); VG_(printf)("\n");
}
=20
- if (isZeroU32(yy)) {
+ if (syned && isZero(yy)) {
/* fancy interpretation */
/* if yy is zero, then it must be fully defined (zero#). */
- tl_assert(isZeroU32(yyhash));
+ tl_assert(isZero(yyhash));
+ threeLeft1 =3D m64 ? mkU64(3<<1) : mkU32(3<<1);
return
binop(
- Iop_Or32,
+ opOR,
assignNew(
- mce,Ity_I32,
+ mce,ty,
binop(
- Iop_And32,
- mkPCastTo(mce,Ity_I32, xxhash),=20
- mkU32(3<<1)
+ opAND,
+ mkPCastTo(mce,ty, xxhash),=20
+ threeLeft1
)),
assignNew(
- mce,Ity_I32,
+ mce,ty,
binop(
- Iop_Shl32,
+ opSHL,
assignNew(
- mce,Ity_I32,
- binop(Iop_Shr32, xxhash, mkU8(31))),
+ mce,ty,
+ binop(opSHR, xxhash, mkU8(width-1))),
mkU8(3)
))
);
} else {
/* standard interpretation */
+ sevenLeft1 =3D m64 ? mkU64(7<<1) : mkU32(7<<1);
return=20
binop(=20
- Iop_And32,=20
- mkPCastTo( mce,Ity_I32,
- mkUifU32(mce, xxhash,yyhash)),
- mkU32(7<<1)
+ opAND,=20
+ mkPCastTo( mce,ty,
+ mkUifU(mce,ty, xxhash,yyhash)),
+ sevenLeft1
);
}
}
@@ -1973,7 +1999,9 @@
=20
case Iop_CmpORD32S:
case Iop_CmpORD32U:
- return doCmpORD32(mce, op, vatom1,vatom2, atom1,atom2);
+ case Iop_CmpORD64S:
+ case Iop_CmpORD64U:
+ return doCmpORD(mce, op, vatom1,vatom2, atom1,atom2);
=20
case Iop_Add64:
if (mce->bogusLiterals)
|