]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Move the handling of PSHUFW from the SSE code to the MMX code so that
authorTom Hughes <tom@compton.nu>
Mon, 15 Mar 2004 16:43:58 +0000 (16:43 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 15 Mar 2004 16:43:58 +0000 (16:43 +0000)
it will work on older Athlons which only have MMXEXT support.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2319

cachegrind/cg_main.c
coregrind/vg_from_ucode.c
coregrind/vg_to_ucode.c
coregrind/vg_translate.c
helgrind/hg_main.c
include/vg_skin.h.base
memcheck/mc_translate.c

index 2f83e76f6704f4c66a239a3fbe7916fc8f9a0dc5..a0641dd4cc27c5433d73926fa540f8f203051d77 100644 (file)
@@ -604,6 +604,13 @@ static Int compute_BBCC_array_size(UCodeBlock* cb)
             is_FPU_R = True;
             break;
 
+         case MMX2a1_MemRd:
+            sk_assert(u_in->size == 8);
+            sk_assert(!is_LOAD && !is_STORE && !is_FPU_R && !is_FPU_W);
+            t_read = u_in->val3;
+            is_FPU_R = True;
+            break;
+
          case SSE2a_MemRd:
          case SSE2a1_MemRd:
             sk_assert(u_in->size == 4 || u_in->size == 8 || u_in->size == 16 || u_in->size == 512);
@@ -857,6 +864,18 @@ UCodeBlock* SK_(instrument)(UCodeBlock* cb_in, Addr orig_addr)
                         : MIN_LINE_SIZE);
             VG_(copy_UInstr)(cb, u_in);
             break;
+            break;
+
+         case MMX2a1_MemRd:
+            sk_assert(u_in->size == 8);
+            t_read      = u_in->val3;
+            t_read_addr = newTemp(cb);
+            uInstr2(cb, MOV, 4, TempReg, u_in->val3,  TempReg, t_read_addr);
+            data_size = ( u_in->size <= MIN_LINE_SIZE
+                        ? u_in->size
+                        : MIN_LINE_SIZE);
+            VG_(copy_UInstr)(cb, u_in);
+            break;
 
          case SSE2a_MemRd:
          case SSE2a1_MemRd:
index 859d098a5e77a1f0cb0645ce5a46c45dbc236231..211f58e590b77ec5a3b39ddcc47e920d45910801 100644 (file)
@@ -1497,6 +1497,28 @@ static void emit_MMX2_regmem ( FlagSet uses_sflags,
                   nameIReg(4,ireg) );
 }
 
+static void emit_MMX2a1 ( FlagSet uses_sflags, 
+                          FlagSet sets_sflags,
+                         UChar first_byte, 
+                          UChar second_byte, 
+                          UChar third_byte, 
+                          Int ireg )
+{
+   VG_(new_emit)(True, uses_sflags, sets_sflags);
+
+   boundscheck();
+
+   VG_(emitB) ( 0x0F );
+   VG_(emitB) ( first_byte );
+   second_byte &= 0x38; /* mask out mod and rm fields */
+   emit_amode_regmem_reg ( ireg, second_byte >> 3 );
+   VG_(emitB) ( third_byte );
+   if (dis)
+      VG_(printf)("\n\t\tmmx2a1-0x%x:0x%x:0x%x-(%s)\n", 
+                  (UInt)first_byte, (UInt)second_byte, (UInt)third_byte,
+                  nameIReg(4,ireg) );
+}
+
 static void emit_SSE2a ( FlagSet uses_sflags, 
                          FlagSet sets_sflags,
                          UChar first_byte, 
@@ -3273,6 +3295,17 @@ static void synth_MMX2_regmem ( Bool uses_flags, Bool sets_flags,
 }
 
 
+static void synth_MMX2a1 ( Bool uses_flags, Bool sets_flags,
+                          UChar first_byte,
+                           UChar second_byte, 
+                           UChar third_byte, 
+                           Int ireg )
+{
+   emit_MMX2a1 ( uses_flags, sets_flags, 
+                 first_byte, second_byte, third_byte, ireg );
+}
+
+
 static void synth_MMX2_reg_to_mmxreg ( Bool uses_flags, Bool sets_flags,
                                        UChar first_byte,
                                        UChar second_byte, 
@@ -4076,6 +4109,23 @@ static void emitUInstr ( UCodeBlock* cb, Int i,
                              u->val2 );
          break;
 
+      case MMX2a1_MemRd:
+         vg_assert(u->size == 8);
+         vg_assert(u->tag1 == Lit16);
+         vg_assert(u->tag2 == Lit16);
+         vg_assert(u->tag3 == RealReg);
+         vg_assert(!anyFlagUse(u));
+         if (!(*sselive)) {
+            emit_get_sse_state();
+            *sselive = True;
+         }
+         synth_MMX2a1 ( u->flags_r, u->flags_w,
+                        (u->val1 >> 8) & 0xFF,
+                        u->val1 & 0xFF,
+                        u->val2 & 0xFF,
+                        u->val3 );
+         break;
+
       case MMX2_ERegRd:
          vg_assert(u->tag1 == Lit16);
          vg_assert(u->tag2 == RealReg);
index a63a4a52bf47c1dc11cf3fad52271d580c500f45..41ea9c22f8dd7125ad7093a75829404ef28d6511 100644 (file)
@@ -3289,6 +3289,57 @@ Addr dis_MMXop_regmem_to_reg ( UCodeBlock* cb,
 }
 
 
+/* Simple MMX operations, either 
+       op   (src)mmxreg, (dst)mmxreg
+   or
+       op   (src)address, (dst)mmxreg
+   opc is the byte following the 0x0F prefix.
+*/
+static 
+Addr dis_MMXop_regmem_to_reg_Imm8 ( UCodeBlock* cb, 
+                                    UChar sorb,
+                                    Addr eip,
+                                    UChar opc,
+                                    Char* name,
+                                    Bool show_granularity )
+{
+    Char dis_buf[50];
+   UChar modrm = getUChar(eip);
+   UChar imm8;
+   Bool  isReg = epartIsReg(modrm);
+
+   if (isReg) {
+      eip++;
+      imm8 = getUChar(eip);
+      eip++;
+      uInstr2(cb, MMX3, 0, 
+                  Lit16, 
+                  (((UShort)(opc)) << 8) | ((UShort)modrm),
+                  Lit16,
+                  ((UShort)imm8));
+   } else {
+      UInt pair = disAMode ( cb, sorb, eip, dis_buf );
+      Int  tmpa = LOW24(pair);
+      eip += HI8(pair);
+      imm8 = getUChar(eip);
+      eip++;
+      uInstr3(cb, MMX2a1_MemRd, 8, 
+                  Lit16, 
+                  (((UShort)(opc)) << 8) | ((UShort)modrm),
+                  Lit16,
+                  ((UShort)imm8),
+                  TempReg, tmpa);
+   }
+
+   DIP("%s%s %s, %s, $%d\n", 
+       name, show_granularity ? nameMMXGran(opc & 3) : (Char*)"",
+       ( isReg ? nameMMXReg(eregOfRM(modrm)) : dis_buf ),
+       nameMMXReg(gregOfRM(modrm)), (Int)imm8 );
+
+   return eip;
+}
+
+
 
 /* Simple SSE operations, either 
        op   (src)xmmreg, (dst)xmmreg
@@ -4217,15 +4268,6 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
       goto decode_success;
    }
 
-   /* PSHUFW */
-   if (sz == 4
-       && insn[0] == 0x0F && insn[1] == 0x70) {
-      eip = dis_SSE2_reg_or_mem_Imm8 ( cb, sorb, eip+2, 8, 
-                                           "pshufw",
-                                           insn[0], insn[1] );
-      goto decode_success;
-   }
-
    /* SHUFPD */
    if (sz == 2 && insn[0] == 0x0F && insn[1] == 0xC6) {
       eip = dis_SSE3_reg_or_mem_Imm8 ( cb, sorb, eip+2, 16, "shufpd",
@@ -7143,6 +7185,12 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
          eip = dis_MMXop_regmem_to_reg ( cb, sorb, eip, opc, "psadbw", False );
          break;
 
+      case 0x70:
+         /* PSHUFW imm8, (src)mmxreg-or-mem, (dst)mmxreg */
+         vg_assert(sz == 4);
+         eip = dis_MMXop_regmem_to_reg_Imm8 ( cb, sorb, eip, opc, "pshufw", False );
+         break;
+
       case 0xD7:
          /* PMOVMSKB (src)mmxreg, (dst)ireg */
          vg_assert(sz == 4);
index faaf8776ba614b1c09909dd7d13e495e6de7a34e..738c5f70d540fb324d39b1722735a521c9d2f386 100644 (file)
@@ -555,14 +555,15 @@ Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u )
                        (u->argc > 1                   ? TR2 : N2) && 
                        (u->argc > 2 || u->has_ret_val ? TR3 : N3) &&
                        u->regparms_n <= u->argc && XCCALL;
-   /* Fields checked:     lit32   size  flags_r/w tag1   tag2   tag3    (rest) */
+   /* Fields checked:       lit32   size  flags_r/w tag1   tag2   tag3    (rest) */
    case MMX1:
-   case MMX2:        return LIT0 && SZ0  && CC0 &&  Ls1 &&  N2 &&  N3 && XOTHER;
-   case MMX3:        return LIT0 && SZ0  && CC0 &&  Ls1 && Ls2 &&  N3 && XOTHER;
-   case MMX2_MemRd:  return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
-   case MMX2_MemWr:  return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
-   case MMX2_ERegRd: return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
-   case MMX2_ERegWr: return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2:         return LIT0 && SZ0  && CC0 &&  Ls1 &&  N2 &&  N3 && XOTHER;
+   case MMX3:         return LIT0 && SZ0  && CC0 &&  Ls1 && Ls2 &&  N3 && XOTHER;
+   case MMX2_MemRd:   return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2_MemWr:   return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2a1_MemRd: return LIT0 && SZ8  && CC0 &&  Ls1 && Ls2 && TR3 && XOTHER;
+   case MMX2_ERegRd:  return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2_ERegWr:  return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
 
    /* Fields checked:        lit32   size  flags_r/w tag1   tag2   tag3    (rest) */
    case SSE2a_MemWr:  return LIT0 && SZsse2 && CC0  && Ls1 && Ls2 && TR3 && XOTHER;
@@ -897,6 +898,7 @@ Char* VG_(name_UOpcode) ( Bool upper, Opcode opc )
       case MMX3:       return "MMX3" ;
       case MMX2_MemRd: return "MMX2_MRd" ;
       case MMX2_MemWr: return "MMX2_MWr" ;
+      case MMX2a1_MemRd: return "MMX2a1_MRd" ;
       case MMX2_ERegRd: return "MMX2_eRRd" ;
       case MMX2_ERegWr: return "MMX2_eRWr" ;
       case SSE2a_MemWr: return "SSE2a_MWr";
@@ -1067,6 +1069,12 @@ void pp_UInstrWorker ( Int instrNo, UInstr* u, Bool ppRegsLiveness )
          VG_(pp_UOperand)(u, 2, 4, True);
          break;
 
+      case MMX2a1_MemRd:
+          VG_(printf)("0x%x:0x%x:0x%x",
+                     (u->val1 >> 8) & 0xFF, u->val1 & 0xFF, u->val2 & 0xFF );
+         VG_(pp_UOperand)(u, 3, 4, True);
+         break;
+
       case SSE2a_MemWr:
       case SSE2a_MemRd:
       case SSE2g_RegWr:
@@ -1296,6 +1304,7 @@ Int VG_(get_reg_usage) ( UInstr* u, Tag tag, Int* regs, Bool* isWrites )
 
       case SSE3ag_MemRd_RegWr: RD(1); WR(2); break;
 
+      case MMX2a1_MemRd: RD(3); break;
       case MMX2_ERegRd: RD(2); break;
       case MMX2_ERegWr: WR(2); break;
 
@@ -1451,7 +1460,7 @@ Int maybe_uinstrReadsArchReg ( UInstr* u )
       case JIFZ:
       case FPU: case FPU_R: case FPU_W:
       case MMX1: case MMX2: case MMX3:
-      case MMX2_MemRd: case MMX2_MemWr:
+      case MMX2_MemRd: case MMX2_MemWr: case MMX2a1_MemRd:
       case MMX2_ERegRd: case MMX2_ERegWr:
       case SSE2a_MemWr: case SSE2a_MemRd: case SSE2a1_MemRd:
       case SSE2g_RegWr: case SSE2g1_RegWr: case SSE2e1_RegRd:
index 9b54604932f979d3187cf2aefa53364b8dbd0015..a3516cfbec2535204956cc3f17c1def67661b383 100644 (file)
@@ -2145,6 +2145,23 @@ UCodeBlock* SK_(instrument) ( UCodeBlock* cb_in, Addr not_used )
            break;
         } 
 
+         case MMX2a1_MemRd: {
+            sk_assert(8 == 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_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:
index 70704799e3e7e138a286789abae4cbeb10443b16..d31622931805273b3dcc50bfc0f80feafa0a5140 100644 (file)
@@ -665,6 +665,15 @@ typedef
       MMX2_MemRd,
       MMX2_MemWr,
 
+      /* 3 bytes, reads/writes mem.  Insns of the form
+         bbbbbbbb:mod mmxreg r/m:bbbbbbbb
+         Held in val1[15:0] and val2[7:0], and mod and rm are to be
+         replaced at codegen time by a reference to the Temp/RealReg
+         holding the address.  Arg2 holds this Temp/Real Reg.
+         Transfer is always at size 8.
+      */
+      MMX2a1_MemRd,
+
       /* 2 bytes, reads/writes an integer ("E") register.  Insns of the form
          bbbbbbbb:11 mmxreg ireg.
          Held in val1[15:0], and ireg is to be replaced
index fc62ba91e1f6cd3ce64329493ba30216f4c0fa3f..7a2e05b2a18f2f8e0799272f7b9f1e25ec393e55 100644 (file)
@@ -1075,6 +1075,25 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
             break;
          }
 
+         case MMX2a1_MemRd: {
+            Int t_size = INVALID_TEMPREG;
+
+            sk_assert(u_in->size == 8);
+
+            sk_assert(u_in->tag3 == TempReg);
+            uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val3));
+            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val3));
+
+            t_size = newTemp(cb);
+            uInstr2(cb, MOV,   4, Literal, 0, TempReg, t_size);
+            uLiteral(cb, u_in->size);
+            uInstr2(cb, CCALL, 0, TempReg, u_in->val3, TempReg, t_size);
+            uCCall(cb, (Addr) & MC_(fpu_read_check), 2, 2, False);
+            
+            VG_(copy_UInstr)(cb, u_in);
+            break;
+         }
+
         /* SSE ins referencing scalar integer registers */
          case SSE2g_RegWr:
          case SSE2g1_RegWr: