x86 front and back ends: track vex r3120, which changed the type of
Iop_Sqrt64Fx2 and Iop_Sqrt32Fx4.


git-svn-id: svn://svn.valgrind.org/vex/trunk@3122 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_x86_toIR.c b/priv/guest_x86_toIR.c
index c614f65..fc402ce 100644
--- a/priv/guest_x86_toIR.c
+++ b/priv/guest_x86_toIR.c
@@ -7134,17 +7134,26 @@
    Int     alen;
    IRTemp  addr;
    UChar   rm = getIByte(delta);
+   // Sqrt32Fx4 and Sqrt64Fx2 take a rounding mode, which is faked
+   // up in the usual way.
+   Bool needsIRRM = op == Iop_Sqrt32Fx4 || op == Iop_Sqrt64Fx2;
    if (epartIsReg(rm)) {
-      putXMMReg( gregOfRM(rm), 
-                 unop(op, getXMMReg(eregOfRM(rm))) );
+      IRExpr* src = getXMMReg(eregOfRM(rm));
+      /* XXXROUNDINGFIXME */
+      IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src)
+                              : unop(op, src);
+      putXMMReg( gregOfRM(rm), res );
       DIP("%s %s,%s\n", opname,
                         nameXMMReg(eregOfRM(rm)),
                         nameXMMReg(gregOfRM(rm)) );
       return delta+1;
    } else {
       addr = disAMode ( &alen, sorb, delta, dis_buf );
-      putXMMReg( gregOfRM(rm), 
-                 unop(op, loadLE(Ity_V128, mkexpr(addr))) );
+      IRExpr* src = loadLE(Ity_V128, mkexpr(addr));
+      /* XXXROUNDINGFIXME */
+      IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src)
+                              : unop(op, src);
+      putXMMReg( gregOfRM(rm), res );
       DIP("%s %s,%s\n", opname,
                         dis_buf,
                         nameXMMReg(gregOfRM(rm)) );
diff --git a/priv/host_x86_isel.c b/priv/host_x86_isel.c
index c51b6f7..011cba5 100644
--- a/priv/host_x86_isel.c
+++ b/priv/host_x86_isel.c
@@ -3415,7 +3415,6 @@
 
       case Iop_RecipEst32Fx4: op = Xsse_RCPF;   goto do_32Fx4_unary;
       case Iop_RSqrtEst32Fx4: op = Xsse_RSQRTF; goto do_32Fx4_unary;
-      case Iop_Sqrt32Fx4:     op = Xsse_SQRTF;  goto do_32Fx4_unary;
       do_32Fx4_unary:
       {
          HReg arg = iselVecExpr(env, e->Iex.Unop.arg);
@@ -3424,16 +3423,6 @@
          return dst;
       }
 
-      case Iop_Sqrt64Fx2:  op = Xsse_SQRTF;  goto do_64Fx2_unary;
-      do_64Fx2_unary:
-      {
-         HReg arg = iselVecExpr(env, e->Iex.Unop.arg);
-         HReg dst = newVRegV(env);
-         REQUIRE_SSE2;
-         addInstr(env, X86Instr_Sse64Fx2(op, arg, dst));
-         return dst;
-      }
-
       case Iop_RecipEst32F0x4: op = Xsse_RCPF;   goto do_32F0x4_unary;
       case Iop_RSqrtEst32F0x4: op = Xsse_RSQRTF; goto do_32F0x4_unary;
       case Iop_Sqrt32F0x4:     op = Xsse_SQRTF;  goto do_32F0x4_unary;
@@ -3499,6 +3488,21 @@
    if (e->tag == Iex_Binop) {
    switch (e->Iex.Binop.op) {
 
+      case Iop_Sqrt64Fx2:
+         REQUIRE_SSE2;
+         /* fallthrough */
+      case Iop_Sqrt32Fx4: {
+         /* :: (rmode, vec) -> vec */
+         HReg arg = iselVecExpr(env, e->Iex.Binop.arg2);
+         HReg dst = newVRegV(env);
+         /* XXXROUNDINGFIXME */
+         /* set roundingmode here */
+         addInstr(env, (e->Iex.Binop.op == Iop_Sqrt64Fx2 
+                           ? X86Instr_Sse64Fx2 : X86Instr_Sse32Fx4)
+                       (Xsse_SQRTF, arg, dst));
+         return dst;
+      }
+
       case Iop_SetV128lo32: {
          HReg dst = newVRegV(env);
          HReg srcV = iselVecExpr(env, e->Iex.Binop.arg1);