Track vex r1573 (introduction of 4-arg IR primops for ppc fmadd/fmsub).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5619 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/lackey/lk_main.c b/lackey/lk_main.c
index d5a0222..a2e513c 100644
--- a/lackey/lk_main.c
+++ b/lackey/lk_main.c
@@ -432,6 +432,8 @@
                      break;
                   case Iex_Unop:
                   case Iex_Binop:
+                  case Iex_Triop:
+                  case Iex_Qop:
                   case Iex_Mux0X:
                      instrument_detail( bb, OpAlu, type );
                      break;
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
index 158b241..0ffe445 100644
--- a/memcheck/mc_translate.c
+++ b/memcheck/mc_translate.c
@@ -1161,6 +1161,61 @@
 }
 
 
+/* 4-arg version of the above. */
+static
+IRAtom* mkLazy4 ( MCEnv* mce, IRType finalVty, 
+                  IRAtom* va1, IRAtom* va2, IRAtom* va3, IRAtom* va4 )
+{
+   IRAtom* at;
+   IRType t1 = typeOfIRExpr(mce->bb->tyenv, va1);
+   IRType t2 = typeOfIRExpr(mce->bb->tyenv, va2);
+   IRType t3 = typeOfIRExpr(mce->bb->tyenv, va3);
+   IRType t4 = typeOfIRExpr(mce->bb->tyenv, va4);
+   tl_assert(isShadowAtom(mce,va1));
+   tl_assert(isShadowAtom(mce,va2));
+   tl_assert(isShadowAtom(mce,va3));
+   tl_assert(isShadowAtom(mce,va4));
+
+   /* The general case is inefficient because PCast is an expensive
+      operation.  Here are some special cases which use PCast only
+      twice rather than three times. */
+
+   /* I32 x I64 x I64 x I64 -> I64 */
+   /* Standard FP idiom: rm x FParg1 x FParg2 x FParg3 -> FPresult */
+   if (t1 == Ity_I32 && t2 == Ity_I64 && t3 == Ity_I64 && t4 == Ity_I64
+       && finalVty == Ity_I64) {
+      if (0) VG_(printf)("mkLazy4: I32 x I64 x I64 x I64 -> I64\n");
+      /* Widen 1st arg to I64.  Since 1st arg is typically a rounding
+         mode indication which is fully defined, this should get
+         folded out later. */
+      at = mkPCastTo(mce, Ity_I64, va1);
+      /* Now fold in 2nd, 3rd, 4th args. */
+      at = mkUifU(mce, Ity_I64, at, va2);
+      at = mkUifU(mce, Ity_I64, at, va3);
+      at = mkUifU(mce, Ity_I64, at, va4);
+      /* and PCast once again. */
+      at = mkPCastTo(mce, Ity_I64, at);
+      return at;
+   }
+
+   if (1) {
+      VG_(printf)("mkLazy4 ");
+      ppIRType(t1);
+      VG_(printf)(" x ");
+      ppIRType(t2);
+      VG_(printf)(" x ");
+      ppIRType(t3);
+      VG_(printf)(" x ");
+      ppIRType(t4);
+      VG_(printf)(" -> ");
+      ppIRType(finalVty);
+      VG_(printf)("\n");
+   }
+
+   tl_assert(0);
+}
+
+
 /* Do the lazy propagation game from a null-terminated vector of
    atoms.  This is presumably the arguments to a helper call, so the
    IRCallee info is also supplied in order that we can know which
@@ -1646,6 +1701,43 @@
 /*------------------------------------------------------------*/
 
 static 
+IRAtom* expr2vbits_Qop ( MCEnv* mce,
+                         IROp op,
+                         IRAtom* atom1, IRAtom* atom2, 
+                         IRAtom* atom3, IRAtom* atom4 )
+{
+   IRAtom* vatom1 = expr2vbits( mce, atom1 );
+   IRAtom* vatom2 = expr2vbits( mce, atom2 );
+   IRAtom* vatom3 = expr2vbits( mce, atom3 );
+   IRAtom* vatom4 = expr2vbits( mce, atom4 );
+
+   tl_assert(isOriginalAtom(mce,atom1));
+   tl_assert(isOriginalAtom(mce,atom2));
+   tl_assert(isOriginalAtom(mce,atom3));
+   tl_assert(isOriginalAtom(mce,atom4));
+   tl_assert(isShadowAtom(mce,vatom1));
+   tl_assert(isShadowAtom(mce,vatom2));
+   tl_assert(isShadowAtom(mce,vatom3));
+   tl_assert(isShadowAtom(mce,vatom4));
+   tl_assert(sameKindedAtoms(atom1,vatom1));
+   tl_assert(sameKindedAtoms(atom2,vatom2));
+   tl_assert(sameKindedAtoms(atom3,vatom3));
+   tl_assert(sameKindedAtoms(atom4,vatom4));
+   switch (op) {
+      case Iop_MAddF64:
+      case Iop_MAddF64r32:
+      case Iop_MSubF64:
+      case Iop_MSubF64r32:
+         /* I32(rm) x F64 x F64 x F64 -> F64 */
+         return mkLazy4(mce, Ity_I64, vatom1, vatom2, vatom3, vatom4);
+      default:
+         ppIROp(op);
+         VG_(tool_panic)("memcheck:expr2vbits_Qop");
+   }
+}
+
+
+static 
 IRAtom* expr2vbits_Triop ( MCEnv* mce,
                            IROp op,
                            IRAtom* atom1, IRAtom* atom2, IRAtom* atom3 )
@@ -2515,6 +2607,14 @@
       case Iex_Const:
          return definedOfType(shadowType(typeOfIRExpr(mce->bb->tyenv, e)));
 
+      case Iex_Qop:
+         return expr2vbits_Qop(
+                   mce,
+                   e->Iex.Qop.op,
+                   e->Iex.Qop.arg1, e->Iex.Qop.arg2,
+		   e->Iex.Qop.arg3, e->Iex.Qop.arg4
+                );
+
       case Iex_Triop:
          return expr2vbits_Triop(
                    mce,
@@ -3029,6 +3129,11 @@
                return isBogusAtom(e->Iex.Triop.arg1)
                       || isBogusAtom(e->Iex.Triop.arg2)
                       || isBogusAtom(e->Iex.Triop.arg3);
+            case Iex_Qop: 
+               return isBogusAtom(e->Iex.Qop.arg1)
+                      || isBogusAtom(e->Iex.Qop.arg2)
+                      || isBogusAtom(e->Iex.Qop.arg3)
+                      || isBogusAtom(e->Iex.Qop.arg4);
             case Iex_Mux0X:
                return isBogusAtom(e->Iex.Mux0X.cond)
                       || isBogusAtom(e->Iex.Mux0X.expr0)