|
From: <sv...@va...> - 2005-07-07 12:27:35
|
Author: sewardj
Date: 2005-07-07 13:26:36 +0100 (Thu, 07 Jul 2005)
New Revision: 1264
Log:
Tidy up some loose ends in the self-checking-translations machinery,
and unroll the adler32 loop in a not-very-successful attempt to reduce
the overhead of checking.
Modified:
trunk/priv/guest-amd64/ghelpers.c
trunk/priv/guest-generic/bb_to_IR.c
trunk/priv/guest-x86/ghelpers.c
trunk/pub/libvex.h
Modified: trunk/priv/guest-amd64/ghelpers.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/ghelpers.c 2005-07-07 09:56:24 UTC (rev 1263)
+++ trunk/priv/guest-amd64/ghelpers.c 2005-07-07 12:26:36 UTC (rev 1264)
@@ -1729,7 +1729,7 @@
=20
/* Describe any sections to be regarded by Memcheck as
'always-defined'. */
- .n_alwaysDefd =3D 12,
+ .n_alwaysDefd =3D 14,
=20
/* flags thunk: OP and NDEP are always defd, whereas DEP1
and DEP2 have to be tracked. See detailed comment in
@@ -1754,7 +1754,9 @@
// /* */ ALWAYSDEFD(guest_LDT),
// /* */ ALWAYSDEFD(guest_GDT),
/* 10 */ ALWAYSDEFD(guest_EMWARN),
- /* 11 */ ALWAYSDEFD(guest_SSEROUND)
+ /* 11 */ ALWAYSDEFD(guest_SSEROUND),
+ /* 12 */ ALWAYSDEFD(guest_TISTART),
+ /* 13 */ ALWAYSDEFD(guest_TILEN)
}
};
=20
Modified: trunk/priv/guest-generic/bb_to_IR.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-generic/bb_to_IR.c 2005-07-07 09:56:24 UTC (rev 1263=
)
+++ trunk/priv/guest-generic/bb_to_IR.c 2005-07-07 12:26:36 UTC (rev 1264=
)
@@ -42,6 +42,7 @@
=20
=20
/* Forwards .. */
+__attribute((regparm(2)))
static UInt genericg_compute_adler32 ( HWord addr, UInt len );
=20
=20
@@ -119,7 +120,7 @@
delta =3D 0;
n_instrs =3D 0;
=20
- /* If asked to make a self-checking translation, leave a 3 spaces
+ /* If asked to make a self-checking translation, leave a 5 spaces
in which to put the check statements. We'll fill them in later
when we know the length and adler32 of the area to check. */
if (do_self_check) {
@@ -127,6 +128,8 @@
addStmtToIRBB( irbb, IRStmt_NoOp() );
addStmtToIRBB( irbb, IRStmt_NoOp() );
addStmtToIRBB( irbb, IRStmt_NoOp() );
+ addStmtToIRBB( irbb, IRStmt_NoOp() );
+ addStmtToIRBB( irbb, IRStmt_NoOp() );
}
=20
/* Process instructions. */
@@ -285,6 +288,7 @@
=20
UInt len2check, adler32;
IRConst* guest_IP_bbstart_IRConst;
+ IRTemp tistart_tmp, tilen_tmp;
=20
vassert(vge->n_used =3D=3D 1);
len2check =3D vge->len[0];
@@ -295,29 +299,39 @@
=20
guest_IP_bbstart_IRConst
=3D guest_word_type=3D=3DIty_I32=20
- ? IRConst_U32(guest_IP_bbstart)
+ ? IRConst_U32(toUInt(guest_IP_bbstart))
: IRConst_U64(guest_IP_bbstart);
=20
/* Set TISTART and TILEN. These will describe to the despatcher
the area of guest code to invalidate should we exit with a
self-check failure. */
=20
+ tistart_tmp =3D newIRTemp(irbb->tyenv, guest_word_type);
+ tilen_tmp =3D newIRTemp(irbb->tyenv, guest_word_type);
+
irbb->stmts[selfcheck_idx+0]
- =3D IRStmt_Put( offB_TILEN,=20
- guest_word_type=3D=3DIty_I32=20
- ? IRExpr_Const(IRConst_U32(len2check))=20
- : IRExpr_Const(IRConst_U64(len2check)) );
+ =3D IRStmt_Tmp(tistart_tmp, IRExpr_Const(guest_IP_bbstart_IRCons=
t) );
=20
irbb->stmts[selfcheck_idx+1]
- =3D IRStmt_Put( offB_TISTART, IRExpr_Const(guest_IP_bbstart_IRCo=
nst) );
+ =3D IRStmt_Tmp(tilen_tmp,
+ guest_word_type=3D=3DIty_I32=20
+ ? IRExpr_Const(IRConst_U32(len2check))=20
+ : IRExpr_Const(IRConst_U64(len2check))
+ );
=20
irbb->stmts[selfcheck_idx+2]
+ =3D IRStmt_Put( offB_TISTART, IRExpr_Tmp(tistart_tmp) );
+
+ irbb->stmts[selfcheck_idx+3]
+ =3D IRStmt_Put( offB_TILEN, IRExpr_Tmp(tilen_tmp) );
+
+ irbb->stmts[selfcheck_idx+4]
=3D IRStmt_Exit(=20
IRExpr_Binop(=20
Iop_CmpNE32,=20
mkIRExprCCall(=20
Ity_I32,=20
- 0/*regparms*/,=20
+ 2/*regparms*/,=20
"genericg_compute_adler32",
&genericg_compute_adler32,
mkIRExprVec_2(=20
@@ -350,17 +364,12 @@
get anywhere near that many bytes to deal with. This fn is called
once for every use of a self-checking translation, so it needs to
be as fast as possible. */
+__attribute((regparm(2)))
static UInt genericg_compute_adler32 ( HWord addr, UInt len )
{
- UInt i;
UInt s1 =3D 1;
UInt s2 =3D 0;
UChar* buf =3D (UChar*)addr;
- for (i =3D 0; i < len; i++) {
- s1 +=3D (UInt)buf[i];
- s2 +=3D s1;
- }
-#if 0
while (len >=3D 4) {
s1 +=3D buf[0];
s2 +=3D s1;
@@ -379,7 +388,6 @@
len--;
buf++;
}
-#endif
return (s2 << 16) + s1;
}
=20
Modified: trunk/priv/guest-x86/ghelpers.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/ghelpers.c 2005-07-07 09:56:24 UTC (rev 1263)
+++ trunk/priv/guest-x86/ghelpers.c 2005-07-07 12:26:36 UTC (rev 1264)
@@ -2061,7 +2061,7 @@
=20
/* Describe any sections to be regarded by Memcheck as
'always-defined'. */
- .n_alwaysDefd =3D 19,
+ .n_alwaysDefd =3D 21,
=20
/* flags thunk: OP and NDEP are always defd, whereas DEP1
and DEP2 have to be tracked. See detailed comment in
@@ -2085,7 +2085,9 @@
/* 15 */ ALWAYSDEFD(guest_LDT),
/* 16 */ ALWAYSDEFD(guest_GDT),
/* 17 */ ALWAYSDEFD(guest_EMWARN),
- /* 18 */ ALWAYSDEFD(guest_SSEROUND)
+ /* 18 */ ALWAYSDEFD(guest_SSEROUND),
+ /* 19 */ ALWAYSDEFD(guest_TISTART),
+ /* 20 */ ALWAYSDEFD(guest_TILEN)
}
};
=20
Modified: trunk/pub/libvex.h
=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/pub/libvex.h 2005-07-07 09:56:24 UTC (rev 1263)
+++ trunk/pub/libvex.h 2005-07-07 12:26:36 UTC (rev 1264)
@@ -171,7 +171,7 @@
=20
/* The max number of guest state chunks which we can describe as
always defined (for the benefit of Memcheck). */
-#define VEXGLO_N_ALWAYSDEFD 19
+#define VEXGLO_N_ALWAYSDEFD 21
=20
typedef
struct {
|