From: Julian Seward Date: Sat, 6 Nov 2004 12:17:57 +0000 (+0000) Subject: IRCallee: add a mcx_mask field, through which front ends can pass X-Git-Tag: svn/VALGRIND_3_0_1^2~830 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3249babbf35fb610e2c14b26790008c577ed2cec;p=thirdparty%2Fvalgrind.git IRCallee: add a mcx_mask field, through which front ends can pass hints to Memcheck about which arguments in a helper call should be ignored when it comes to computing lazy approximations of definedness through that function. Not sure if this mechanism needs to remain, but for the time being ... git-svn-id: svn://svn.valgrind.org/vex/trunk@504 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 616b1c98eb..f28d5865c2 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -615,47 +615,60 @@ static IRExpr* mk_calculate_eflags_all ( void ) = mkIRExprVec_3( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_RES, Ity_I32), IRExpr_Get(OFFB_CC_AUX, Ity_I32) ); - return mkIRExprCCall( - Ity_I32, - 0/*regparm*/, - "calculate_eflags_all", &calculate_eflags_all, - args - ); + IRExpr* call + = mkIRExprCCall( + Ity_I32, + 0/*regparm*/, + "calculate_eflags_all", &calculate_eflags_all, + args + ); + /* Exclude OP and AUX from definedness checking. We're only + interested in RES. */ + call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<2); + return call; } -/* Build IR to calculate just the carry flag from stored - CC_OP/CC_RES/CC_AUX. Returns an expression :: Ity_I32. */ -static IRExpr* mk_calculate_eflags_c ( void ) +/* Build IR to calculate some particular condition from stored + CC_OP/CC_RES/CC_AUX. Returns an expression :: Ity_Bit. */ +static IRExpr* mk_calculate_condition ( Condcode cond ) { IRExpr** args - = mkIRExprVec_3( IRExpr_Get(OFFB_CC_OP, Ity_I32), + = mkIRExprVec_4( mkU32(cond), + IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_RES, Ity_I32), IRExpr_Get(OFFB_CC_AUX, Ity_I32) ); - return mkIRExprCCall( - Ity_I32, - 0/*regparm*/, - "calculate_eflags_c", &calculate_eflags_c, - args - ); + IRExpr* call + = mkIRExprCCall( + Ity_I32, + 0/*regparm*/, + "calculate_condition", &calculate_condition, + args + ); + /* Exclude the requested condition, OP and AUX from definedness + checking. We're only interested in RES. */ + call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1 << 3); + return unop(Iop_32to1, call); } -/* Build IR to calculate some particular condition from stored - CC_OP/CC_RES/CC_AUX. Returns an expression :: Ity_Bit. */ -static IRExpr* mk_calculate_condition ( Condcode cond ) +/* Build IR to calculate just the carry flag from stored + CC_OP/CC_RES/CC_AUX. Returns an expression :: Ity_I32. */ +static IRExpr* mk_calculate_eflags_c ( void ) { IRExpr** args - = mkIRExprVec_4( mkU32(cond), - IRExpr_Get(OFFB_CC_OP, Ity_I32), + = mkIRExprVec_3( IRExpr_Get(OFFB_CC_OP, Ity_I32), IRExpr_Get(OFFB_CC_RES, Ity_I32), IRExpr_Get(OFFB_CC_AUX, Ity_I32) ); - return unop(Iop_32to1, - mkIRExprCCall( - Ity_I32, - 0/*regparm*/, - "calculate_condition", &calculate_condition, - args - ) - ); + IRExpr* call + = mkIRExprCCall( + Ity_I32, + 0/*regparm*/, + "calculate_eflags_c", &calculate_eflags_c, + args + ); + /* Exclude OP and AUX from definedness checking. We're only + interested in RES. */ + call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<2); + return call; } diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 4969db02a7..9cf5902483 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -52,7 +52,9 @@ void ppIRCallee ( IRCallee* ce ) { vex_printf("%s", ce->name); if (ce->regparms > 0) - vex_printf("[%d]", ce->regparms); + vex_printf("[rp=%d]", ce->regparms); + if (ce->mcx_mask > 0) + vex_printf("[mcx=0x%x]", ce->mcx_mask); vex_printf("{%p}", (void*)ce->addr); } @@ -479,6 +481,7 @@ IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr ) ce->regparms = regparms; ce->name = name; ce->addr = addr; + ce->mcx_mask = 0; vassert(regparms >= 0 && regparms <= 3); vassert(name != NULL); vassert(addr != 0); @@ -762,7 +765,9 @@ IRConst* dopyIRConst ( IRConst* c ) IRCallee* dopyIRCallee ( IRCallee* ce ) { - return mkIRCallee(ce->regparms, ce->name, ce->addr); + IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr); + ce2->mcx_mask = ce->mcx_mask; + return ce2; } IRArray* dopyIRArray ( IRArray* d ) @@ -1441,8 +1446,11 @@ void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy ) sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee"); if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args)) sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args"); - for (i = 0; expr->Iex.CCall.args[i]; i++) + for (i = 0; expr->Iex.CCall.args[i]; i++) { + if (i >= 32) + sanityCheckFail(bb,stmt,"Iex.CCall: > 32 args"); tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy); + } if (expr->Iex.CCall.retty == Ity_Bit) sanityCheckFail(bb,stmt,"Iex.CCall.retty: cannot return :: Ity_Bit"); for (i = 0; expr->Iex.CCall.args[i]; i++) @@ -1535,6 +1543,8 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy ) && typeOfIRTemp(tyenv, d->tmp) == Ity_Bit) sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_Bit"); for (i = 0; d->args[i] != NULL; i++) { + if (i >= 32) + sanityCheckFail(bb,stmt,"IRStmt.Dirty: > 32 args"); if (typeOfIRExpr(tyenv, d->args[i]) == Ity_Bit) sanityCheckFail(bb,stmt,"IRStmt.Dirty.arg[i] :: Ity_Bit"); } diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 9c5e173b94..42a588a83a 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -77,13 +77,21 @@ extern Bool eqIRConst ( IRConst*, IRConst* ); end that the callee has been declared "__attribute__((regparm(n)))". On some targets (x86) the back end will need to construct a non-standard sequence to call a function - declared like this. */ + declared like this. + + mcx_mask is a sop to Memcheck. It indicates which args should be + considered 'always defined' when lazily computing definedness of + the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to + args[1], etc. If a bit is set, the corresponding arg is excluded + (hence "x" in "mcx") from definedness checking. +*/ typedef struct { Int regparms; Char* name; void* addr; + UInt mcx_mask; } IRCallee;