]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Start adding floating point stuff to memcheck.
authorJulian Seward <jseward@acm.org>
Fri, 5 Nov 2004 01:56:14 +0000 (01:56 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 5 Nov 2004 01:56:14 +0000 (01:56 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@495

VEX/head20041019/coregrind/valgrind.vs
VEX/head20041019/memcheck/mc_translate.c

index 76ebb190c15afc8abfd3f7ba7a957f05069abb47..6d54d63fbeae326244cccee1def43451d43bf7fb 100644 (file)
@@ -14,6 +14,7 @@ VALGRIND_2.1 {
                *IRTemp*;
                *IRConst*;
                *IRCallee*;
+               *IRArray*;
                LibVEX_Alloc;
 
        local:
index 3f44f9fc1f40bfeade6e1a5474645baa45223042..d2f5bca9dae9d3e68157f1a26336e77652e7e2b4 100644 (file)
@@ -1721,6 +1721,8 @@ static IRType shadowType ( IRType ty )
       case Ity_I16:
       case Ity_I32: 
       case Ity_I64: return ty;
+      case Ity_F32: return Ity_I32;
+      case Ity_F64: return Ity_I64;
       default: ppIRType(ty); 
                VG_(skin_panic)("memcheck:shadowType");
    }
@@ -1819,9 +1821,16 @@ static IRAtom* mkUifU32 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
    sk_assert(isShadowAtom(mce,a2));
    return assignNew(mce, Ity_I32, binop(Iop_Or32, a1, a2));
 }
+static IRAtom* mkUifU64 ( MCEnv* mce, IRAtom* a1, IRAtom* a2 ) {
+   sk_assert(isShadowAtom(mce,a1));
+   sk_assert(isShadowAtom(mce,a2));
+   return assignNew(mce, Ity_I64, binop(Iop_Or64, a1, a2));
+}
+
 static IRAtom* mkUifU ( MCEnv* mce, IRType vty,  IRAtom* a1, IRAtom* a2 ) {
    switch (vty) {
       case Ity_I32: return mkUifU32(mce, a1, a2);
+      case Ity_I64: return mkUifU64(mce, a1, a2);
       default:
          VG_(printf)("\n"); ppIRType(vty); VG_(printf)("\n");
          VG_(skin_panic)("memcheck:mkUifU");
@@ -1924,7 +1933,7 @@ static void setHelperAnns ( MCEnv* mce, IRDirty* di ) {
 }
 
 /* Note, dst_ty is a V-bits type, not an original type. */
-static IRAtom* mkPCastTo( MCEnv* mce, IRAtom* vbits, IRType dst_ty ) {
+static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) {
    /* First of all, collapse vbits down to a single bit. */
    sk_assert(isShadowAtom(mce,vbits));
    IRType  ty   = typeOfIRExpr(mce->bb->tyenv, vbits);
@@ -1953,6 +1962,8 @@ static IRAtom* mkPCastTo( MCEnv* mce, IRAtom* vbits, IRType dst_ty ) {
    switch (dst_ty) {
       case Ity_Bit:
          return tmp1;
+      case Ity_I16: 
+         return assignNew(mce, Ity_I16, unop(Iop_1Sto16, tmp1));
       case Ity_I32: 
          return assignNew(mce, Ity_I32, unop(Iop_1Sto32, tmp1));
       case Ity_I64: 
@@ -2012,7 +2023,7 @@ void complainIfUndefined ( MCEnv* mce, IRAtom* atom )
    /* sz is only used for constructing the error message */
    Int    sz = ty==Ity_Bit ? 0 : sizeofIRType(ty);
 
-   IRAtom* cond = mkPCastTo( mce, vatom, Ity_Bit );
+   IRAtom* cond = mkPCastTo( mce, Ity_Bit, vatom );
    /* cond will be 0 if all defined, and 1 if any not defined. */
 
    IRDirty* di 
@@ -2048,10 +2059,10 @@ IRAtom* doLazyApproximation ( MCEnv* mce,
    IRAtom* curr = definedOfType(Ity_I32);
    for (i = 0; exprvec[i]; i++) {
       sk_assert(isOriginalAtom(mce, exprvec[i]));
-      here = mkPCastTo( mce, expr2vbits(mce, exprvec[i]), Ity_I32 );
+      here = mkPCastTo( mce, Ity_I32, expr2vbits(mce, exprvec[i]) );
       curr = mkUifU32(mce, here, curr);
    }
-   return mkPCastTo(mce, curr, finalVtype );
+   return mkPCastTo(mce, finalVtype, curr );
 }
 
 /* Generate into bb suitable actions to shadow this Put.  If the state
@@ -2078,6 +2089,34 @@ void do_shadow_PUT ( MCEnv* mce, Int offset, IRAtom* atom )
 }
 
 
+/* Return an expression which contains the V bits corresponding to the
+   given GETI (passed in in pieces). 
+*/
+static
+void do_shadow_PUTI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias, IRAtom* atom )
+{
+   sk_assert(isOriginalAtom(mce,atom));
+   IRAtom* vatom = expr2vbits( mce, atom );
+   sk_assert(sameKindedAtoms(atom, vatom));
+   IRType ty   = descr->elemTy;
+   IRType tyS  = shadowType(ty);
+   Int arrSize = descr->nElems * sizeofIRType(ty);
+   sk_assert(ty != Ity_Bit);
+   sk_assert(isOriginalAtom(mce,ix));
+   complainIfUndefined(mce,ix);
+   if (isAlwaysDefd(mce, descr->base, arrSize)) {
+      /* emit code to emit a complaint if any of the vbits are 1. */
+      complainIfUndefined(mce, atom);
+   } else {
+      /* Do a cloned version of the Put that refers to the shadow
+         area. */
+      IRArray* new_descr 
+         = mkIRArray( descr->base + mce->layout->total_sizeB, 
+                      tyS, descr->nElems);
+      stmt( mce->bb, IRStmt_PutI( new_descr, ix, bias, vatom ));
+   }
+}
+
 /* Return an expression which contains the V bits corresponding to the
    given GET (passed in in pieces). 
 */
@@ -2108,6 +2147,7 @@ IRExpr* shadow_GETI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias )
    Int arrSize = descr->nElems * sizeofIRType(ty);
    sk_assert(ty != Ity_Bit);
    sk_assert(isOriginalAtom(mce,ix));
+   complainIfUndefined(mce,ix);
    if (isAlwaysDefd(mce, descr->base, arrSize)) {
       /* Always defined, return all zeroes of the relevant type */
       return definedOfType(tyS);
@@ -2123,13 +2163,15 @@ IRExpr* shadow_GETI ( MCEnv* mce, IRArray* descr, IRAtom* ix, Int bias )
 
 
 static
-IRAtom* lazy2 ( MCEnv* mce, IRType finalVty, IRAtom* a1, IRAtom* a2 )
+IRAtom* lazy2 ( MCEnv* mce, IRType finalVty, IRAtom* va1, IRAtom* va2 )
 {
    /* force everything via 32-bit intermediaries. */
    IRAtom* at;
-   at = mkPCastTo(mce, a1, Ity_I32);
-   at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, a2, Ity_I32));
-   at = mkPCastTo(mce, at, finalVty);
+   sk_assert(isShadowAtom(mce,va1));
+   sk_assert(isShadowAtom(mce,va2));
+   at = mkPCastTo(mce, Ity_I32, va1);
+   at = mkUifU(mce, Ity_I32, at, mkPCastTo(mce, Ity_I32, va2));
+   at = mkPCastTo(mce, finalVty, at);
    return at;
 }
 
@@ -2152,6 +2194,19 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
    sk_assert(sameKindedAtoms(atom2,vatom2));
    switch (op) {
 
+      case Iop_F64toI32:
+         /* First arg is I32 (rounding mode), second is F64 (data). */
+         return lazy2(mce, Ity_I32, vatom1, vatom2);
+
+      case Iop_F64toI16:
+         /* First arg is I32 (rounding mode), second is F64 (data). */
+         return lazy2(mce, Ity_I16, vatom1, vatom2);
+
+      case Iop_MulF64:
+         return lazy2(mce, Ity_I64, vatom1, vatom2);
+
+      /* non-FP after here */
+
       case Iop_DivModU64to32:
       case Iop_DivModS64to32:
          return lazy2(mce, Ity_I64, vatom1, vatom2);
@@ -2163,7 +2218,7 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
       case Iop_MullS32:
       case Iop_MullU32: {
          IRAtom* vLo32 = mkLeft32(mce, mkUifU32(mce, vatom1,vatom2));
-         IRAtom* vHi32 = mkPCastTo(mce, vLo32, Ity_I32);
+         IRAtom* vHi32 = mkPCastTo(mce, Ity_I32, vLo32);
          return assignNew(mce, Ity_I64, binop(Iop_32HLto64, vHi32, vLo32));
       }
 
@@ -2182,13 +2237,13 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
       case Iop_CmpLE32S: case Iop_CmpLE32U: 
       case Iop_CmpLT32U: case Iop_CmpLT32S:
       case Iop_CmpEQ32: case Iop_CmpNE32:
-         return mkPCastTo(mce, mkUifU32(mce, vatom1,vatom2), Ity_Bit);
+         return mkPCastTo(mce, Ity_Bit, mkUifU32(mce, vatom1,vatom2));
 
       case Iop_CmpEQ16:
-         return mkPCastTo(mce, mkUifU16(mce, vatom1,vatom2), Ity_Bit);
+         return mkPCastTo(mce, Ity_Bit, mkUifU16(mce, vatom1,vatom2));
 
       case Iop_CmpEQ8: case Iop_CmpNE8:
-         return mkPCastTo(mce, mkUifU8(mce, vatom1,vatom2), Ity_Bit);
+         return mkPCastTo(mce, Ity_Bit, mkUifU8(mce, vatom1,vatom2));
 
       case Iop_Shl32: case Iop_Shr32: case Iop_Sar32:
          /* Complain if the shift amount is undefined.  Then simply
@@ -2258,6 +2313,11 @@ IRExpr* expr2vbits_Unop ( MCEnv* mce,
    sk_assert(isShadowAtom(mce,vatom));
    sk_assert(sameKindedAtoms(atom,vatom));
    switch (op) {
+
+      case Iop_F32toF64: 
+      case Iop_I32toF64: 
+         return mkPCastTo(mce, Ity_I64, vatom);
+
       case Iop_64to32:
       case Iop_64HIto32:
       case Iop_1Uto32:
@@ -2304,6 +2364,7 @@ IRAtom* expr2vbits_LDle ( MCEnv* mce, IRType ty, IRAtom* addr )
 
    /* Now cook up a call to the relevant helper function, to read the
       data V bits from shadow memory. */
+   ty = shadowType(ty);
    switch (ty) {
       case Ity_I32: helper = &MC_(helperc_LOADV4);
                     hname = "MC_(helperc_LOADV4)";
@@ -2314,7 +2375,8 @@ IRAtom* expr2vbits_LDle ( MCEnv* mce, IRType ty, IRAtom* addr )
       case Ity_I8:  helper = &MC_(helperc_LOADV1);
                     hname = "MC_(helperc_LOADV1)";
                     break;
-      default:      VG_(skin_panic)("memcheck:do_shadow_LDle");
+      default:      ppIRType(ty);
+                    VG_(skin_panic)("memcheck:do_shadow_LDle");
    }
 
    /* We need to have a place to park the V bits we're just about to
@@ -2351,7 +2413,7 @@ IRAtom* expr2vbits_Mux0X ( MCEnv* mce,
 
    return
       mkUifU(mce, ty, assignNew(mce, ty, IRExpr_Mux0X(cond, vbits0, vbitsX)),
-                      mkPCastTo(mce, vbitsC, ty) );
+                      mkPCastTo(mce, ty, vbitsC) );
 }      
 
 
@@ -2364,6 +2426,10 @@ IRExpr* expr2vbits ( MCEnv* mce, IRExpr* e )
       case Iex_Get:
          return shadow_GET( mce, e->Iex.Get.offset, e->Iex.Get.ty );
 
+      case Iex_GetI:
+         return shadow_GETI( mce, e->Iex.GetI.descr, 
+                                  e->Iex.GetI.ix, e->Iex.GetI.bias );
+
       case Iex_Tmp:
          return IRExpr_Tmp( findShadowTmp(mce, e->Iex.Tmp.tmp) );
 
@@ -2532,6 +2598,14 @@ IRBB* SK_(instrument) ( IRBB* bb_in, VexGuestLayout* layout, IRType hWordTy )
                            st->Ist.Put.data );
             break;
 
+         case Ist_PutI:
+            do_shadow_PUTI( &mce, 
+                            st->Ist.PutI.descr,
+                            st->Ist.PutI.ix,
+                            st->Ist.PutI.bias,
+                            st->Ist.PutI.data );
+            break;
+
          case Ist_STle:
             do_shadow_STle( &mce, st->Ist.STle.addr, st->Ist.STle.data );
             break;