]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
IRCallee: add a mcx_mask field, through which front ends can pass
authorJulian Seward <jseward@acm.org>
Sat, 6 Nov 2004 12:17:57 +0000 (12:17 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 6 Nov 2004 12:17:57 +0000 (12:17 +0000)
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

VEX/priv/guest-x86/toIR.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_ir.h

index 616b1c98ebd6a79f5d23bde15f773ac2856b4030..f28d5865c23644ef9d8136a4e45e2326154f069d 100644 (file)
@@ -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;
 }
 
 
index 4969db02a7b0a686940171d015c45f6c1a665d91..9cf590248368ae32b3300bc98fee6a629fe7095e 100644 (file)
@@ -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");
          }
index 9c5e173b94448d55ace941a0bf829c557832e223..42a588a83a70217582aa4c068e68f6b421eddce0 100644 (file)
@@ -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;