Fix bug 69856; teach Helgrind about all the new SSE-related UOps.
Haven't actually tested races with all those new memory access
instructions though...


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2302 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index ac05374..9b54604 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -2126,24 +2126,46 @@
 	    break;
 	 }
 
+         case MMX2_MemRd:
          case FPU_R: {
             sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size || 
-                      8 == u_in->size || 10 == u_in->size);
+                      8 == u_in->size || 10 == u_in->size || 108 == u_in->size);
 	    
-	       t_size = newTemp(cb);
-	       uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
-	       uLiteral(cb, (UInt)u_in->size);
+	    t_size = newTemp(cb);
+	    uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
+	    uLiteral(cb, (UInt)u_in->size);
 
-	       /* XXX all registers should be flushed to baseblock
-		  here */
-	       uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size);
-	       uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False);
-
-	       VG_(copy_UInstr)(cb, u_in);
-	       t_size = INVALID_TEMPREG;
-	       break;
+	    /* XXX all registers should be flushed to baseblock
+	       here */
+	    uInstr2(cb, CCALL, 0, TempReg, u_in->val2, TempReg, t_size);
+	    uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False);
+	    
+	    VG_(copy_UInstr)(cb, u_in);
+	    t_size = INVALID_TEMPREG;
+	    break;
 	 } 
 
+         case SSE2a_MemRd:
+         case SSE2a1_MemRd:
+         case SSE3a_MemRd:
+         case SSE3a1_MemRd:
+         case SSE3ag_MemRd_RegWr: {
+	    Int addr = (u_in->opcode == SSE3ag_MemRd_RegWr) ? u_in->val1 : u_in->val3;
+
+            sk_assert(u_in->size == 4 || u_in->size == 8 || u_in->size == 16 || u_in->size == 512);
+	    
+	    t_size = newTemp(cb);
+	    uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
+	    uLiteral(cb, (UInt)u_in->size);
+
+	    uInstr2(cb, CCALL, 0, TempReg, addr, TempReg, t_size);
+	    uCCall(cb, (Addr) & eraser_mem_help_read_N, 2, 2, False);
+	    
+	    VG_(copy_UInstr)(cb, u_in);
+	    t_size = INVALID_TEMPREG;
+	    break;
+         }
+
          case STORE: {
 	    void (*help)(Addr, UInt);
             sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size);
@@ -2172,9 +2194,10 @@
 	    break;
 	 }
 
+         case MMX2_MemWr:
          case FPU_W: {
             sk_assert(1 == u_in->size || 2 == u_in->size || 4 == u_in->size || 
-                      8 == u_in->size || 10 == u_in->size);
+                      8 == u_in->size || 10 == u_in->size || 108 == u_in->size);
 
 	    t_size = newTemp(cb);
 	    uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
@@ -2189,12 +2212,23 @@
 	    break;
 	 }
 
-         case MMX1: case MMX2: case MMX3:
-         case MMX2_MemRd: case MMX2_MemWr:
-         case MMX2_ERegRd: case MMX2_ERegWr:
-            VG_(skin_panic)(
-               "I don't know how to instrument MMXish stuff (yet)");
-            break;
+         case SSE2a_MemWr:
+         case SSE3a_MemWr: {
+            sk_assert(4 == u_in->size || 8 == u_in->size || 16 == u_in->size ||
+		      512 == u_in->size);
+
+	    t_size = newTemp(cb);
+	    uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
+	    uLiteral(cb, (UInt)u_in->size);
+	       /* XXX all registers should be flushed to baseblock
+		  here */
+	    uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size);
+	    uCCall(cb, (Addr) & eraser_mem_help_write_N, 2, 2, False);
+
+	    VG_(copy_UInstr)(cb, u_in);
+	    t_size = INVALID_TEMPREG;
+	    break;
+	 }
 
          default:
 	    /* conservative tromping */
@@ -3392,8 +3426,9 @@
    if (LOCKSET_SANITY)
       sanity_check_locksets("SK_(fini)");
 
-   VG_(message)(Vg_UserMsg, "%u possible data races found; %u lock order problems",
-		n_eraser_warnings, n_lockorder_warnings);
+   if (VG_(clo_verbosity) > 0)
+      VG_(message)(Vg_UserMsg, "%u possible data races found; %u lock order problems",
+		   n_eraser_warnings, n_lockorder_warnings);
 
    if (0)
       VG_(printf)("stk_ld:%u+stk_st:%u = %u  nonstk_ld:%u+nonstk_st:%u = %u  %u%%\n",