]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement MMX movd where the src is an mmxreg and the dst is an ireg or
authorJulian Seward <jseward@acm.org>
Fri, 4 Apr 2003 20:40:34 +0000 (20:40 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 4 Apr 2003 20:40:34 +0000 (20:40 +0000)
memory.

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

coregrind/vg_from_ucode.c
coregrind/vg_to_ucode.c
coregrind/vg_translate.c
memcheck/mc_translate.c

index 1a1fc120f8c66a10d79c163779d819e66d88b111..8621d7996efed80ac77ba65aa0f86f2ec0ff354e 100644 (file)
@@ -1413,7 +1413,26 @@ static void emit_MMX2_reg_to_mmxreg ( FlagSet uses_sflags,
    second_byte |= (ireg & 7); /* patch in our ireg */
    VG_(emitB) ( second_byte );
    if (dis)
-      VG_(printf)("\n\t\tmmx2reg-to-mmxreg--0x%x:0x%x-(%s)\n", 
+      VG_(printf)("\n\t\tmmx2:reg-to-mmxreg--0x%x:0x%x-(%s)\n", 
+                  (UInt)first_byte, (UInt)second_byte,
+                  nameIReg(4,ireg) );
+}
+
+static void emit_MMX2_mmxreg_to_reg ( FlagSet uses_sflags, 
+                                      FlagSet sets_sflags,
+                                     UChar first_byte, 
+                                      UChar second_byte, 
+                                      Int ireg )
+{
+   VG_(new_emit)(True, uses_sflags, sets_sflags);
+   VG_(emitB) ( 0x0F );
+   VG_(emitB) ( first_byte );
+   second_byte &= 0x38; /* mask out mod and rm fields */
+   second_byte |= 0xC0; /* set top two bits: mod = 11b */
+   second_byte |= (ireg & 7); /* patch in our ireg */
+   VG_(emitB) ( second_byte );
+   if (dis)
+      VG_(printf)("\n\t\tmmx2:mmxreg-to-reg--0x%x:0x%x-(%s)\n", 
                   (UInt)first_byte, (UInt)second_byte,
                   nameIReg(4,ireg) );
 }
@@ -2715,6 +2734,15 @@ static void synth_MMX2_reg_to_mmxreg ( Bool uses_flags, Bool sets_flags,
                              first_byte, second_byte, ireg );
 }
 
+static void synth_MMX2_mmxreg_to_reg ( Bool uses_flags, Bool sets_flags,
+                                       UChar first_byte,
+                                       UChar second_byte, 
+                                       Int ireg )
+{
+   emit_MMX2_mmxreg_to_reg ( uses_flags, sets_flags,
+                             first_byte, second_byte, ireg );
+}
+
 static void synth_MMX2_no_mem ( Bool uses_flags, Bool sets_flags,
                                UChar first_byte,
                                 UChar second_byte )
@@ -3477,6 +3505,7 @@ static void emitUInstr ( UCodeBlock* cb, Int i,
 
       case MMX2_MemWr:
       case MMX2_MemRd:
+         vg_assert(u->size == 4 || u->size == 8);
          vg_assert(u->tag1 == Lit16);
          vg_assert(u->tag2 == RealReg);
          vg_assert(u->tag3 == NoValue);
@@ -3506,6 +3535,21 @@ static void emitUInstr ( UCodeBlock* cb, Int i,
                                     u->val2 );
          break;
 
+      case MMX2_RegWr:
+         vg_assert(u->tag1 == Lit16);
+         vg_assert(u->tag2 == RealReg);
+         vg_assert(u->tag3 == NoValue);
+         vg_assert(!anyFlagUse(u));
+         if (!(*fplive)) {
+            emit_get_fpu_state();
+            *fplive = True;
+         }
+         synth_MMX2_mmxreg_to_reg ( u->flags_r, u->flags_w,
+                                    (u->val1 >> 8) & 0xFF,
+                                    u->val1 & 0xFF,
+                                    u->val2 );
+         break;
+
       case MMX1:
          vg_assert(u->tag1 == Lit16);
          vg_assert(u->tag2 == NoValue);
index cbfd51d3813810291e9e0690b7c4c9df7f3ac2ce..82a52bd88bde57c2da614c0bd7cfa6aefcce214f 100644 (file)
@@ -4829,6 +4829,37 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
             VG_(printf)("emms\n");
          break;
 
+      case 0x7E: /* MOVD (src)mmxreg, (dst)ireg-or-mem */
+         vg_assert(sz == 4);
+         modrm = getUChar(eip);
+         if (epartIsReg(modrm)) {
+            eip++;
+            t1 = newTemp(cb);
+            uInstr2(cb, MMX2_RegWr, 4, 
+                        Lit16, 
+                        (((UShort)(opc)) << 8) | ((UShort)modrm),
+                        TempReg, t1 );
+            uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, eregOfRM(modrm));
+            if (dis)
+               VG_(printf)("movd %s, %s\n", 
+                           nameMMXReg(gregOfRM(modrm)),
+                           nameIReg(4,eregOfRM(modrm)));
+         } else {
+            Int tmpa;
+            pair = disAMode ( cb, sorb, eip, dis?dis_buf:NULL );
+            tmpa = LOW24(pair);
+            eip += HI8(pair);
+            uInstr2(cb, MMX2_MemWr, 4, 
+                        Lit16, 
+                        (((UShort)(opc)) << 8) | ((UShort)modrm),
+                        TempReg, tmpa);
+            if (dis)
+               VG_(printf)("movd %s, %s\n", 
+                           nameMMXReg(gregOfRM(modrm)),
+                           dis_buf);
+         }
+         break;
+
       case 0x6E: /* MOVD (src)ireg-or-mem, (dst)mmxreg */
          vg_assert(sz == 4);
          modrm = getUChar(eip);
index c99e53ecf10f7f8fded46193a279dd1ef317dca7..57302b4d9dc849a90510e1f6c4c2c44dc8c4a2f9 100644 (file)
@@ -550,8 +550,9 @@ Bool VG_(saneUInstr) ( Bool beforeRA, Bool beforeLiveness, UInstr* u )
    case MMX2:       return LIT0 && SZ0  && CC0 &&  Ls1 &&  N2 &&  N3 && XOTHER;
    case MMX3:       return LIT0 && SZ0  && CC0 &&  Ls1 && Ls1 &&  N3 && XOTHER;
    case MMX2_MemRd: return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
-   case MMX2_MemWr: return LIT0 && SZ && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2_MemWr: return LIT0 && SZ48 && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
    case MMX2_RegRd: return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
+   case MMX2_RegWr: return LIT0 && SZ4  && CC0 &&  Ls1 && TR2 &&  N3 && XOTHER;
    default: 
       if (VG_(needs).extended_UCode)
          return SK_(sane_XUInstr)(beforeRA, beforeLiveness, u);
@@ -859,6 +860,7 @@ Char* VG_(name_UOpcode) ( Bool upper, Opcode opc )
       case MMX2_MemRd: return "MMX2_MRd" ;
       case MMX2_MemWr: return "MMX2_MWr" ;
       case MMX2_RegRd: return "MMX2_RRd" ;
+      case MMX2_RegWr: return "MMX2_RWr" ;
       default:
          if (VG_(needs).extended_UCode)
             return SK_(name_XUOpcode)(opc);
@@ -992,6 +994,7 @@ void pp_UInstrWorker ( Int instrNo, UInstr* u, Bool ppRegsLiveness )
                      (u->val1 >> 8) & 0xFF, u->val1 & 0xFF, u->val2 & 0xFF );
          break;
 
+      case MMX2_RegWr:
       case MMX2_RegRd:
          VG_(printf)("\t0x%x:0x%x, ",
                      (u->val1 >> 8) & 0xFF, u->val1 & 0xFF );
@@ -1157,6 +1160,7 @@ Int VG_(get_reg_usage) ( UInstr* u, Tag tag, Int* regs, Bool* isWrites )
       case LEA2: RD(1); RD(2); WR(3); break;
 
       case MMX2_RegRd: RD(2); break;
+      case MMX2_RegWr: WR(2); break;
 
       case MMX1: case MMX2: case MMX3:
       case NOP:   case FPU:   case INCEIP: case CALLM_S: case CALLM_E:
@@ -1308,7 +1312,7 @@ Int maybe_uinstrReadsArchReg ( UInstr* u )
       case FPU: case FPU_R: case FPU_W:
       case MMX1: case MMX2: case MMX3:
       case MMX2_MemRd: case MMX2_MemWr:
-      case MMX2_RegRd:
+      case MMX2_RegRd: case MMX2_RegWr:
       case WIDEN:
       /* GETSEG and USESEG are to do with ArchRegS, not ArchReg */
       case GETSEG: case PUTSEG: 
index 1833e720ddb67e56cde1d5c4c303d984cc5ee444..a90f9e3357773e5d8a96dbbbf1f7e2000ca4546c 100644 (file)
@@ -1097,9 +1097,13 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in )
             VG_(copy_UInstr)(cb, u_in);
             break;
 
+        /* The MMX register is assumed to be fully defined, so
+           that's what this register becomes. */
          case MMX2_RegWr:
-            VG_(skin_panic)(
-               "I don't know how to instrument MMX2_RegWr (yet)");
+            sk_assert(u_in->tag2 == TempReg);
+            sk_assert(u_in->size == 4);
+            uInstr1(cb, SETV,  4, TempReg, SHADOW(u_in->val2));
+            VG_(copy_UInstr)(cb, u_in);         
             break;
 
          default: