]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Oops! The floating-point conditional-move instructions read %EIP, so
authorJulian Seward <jseward@acm.org>
Thu, 18 Apr 2002 02:18:24 +0000 (02:18 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 18 Apr 2002 02:18:24 +0000 (02:18 +0000)
we'd better annotate them as such!

Fixes a floating-point misbehaviour bug reported by Robert W. Anderson
<anderson110@poptop.llnl.gov>.

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

coregrind/vg_from_ucode.c
coregrind/vg_to_ucode.c
coregrind/vg_translate.c
vg_from_ucode.c
vg_to_ucode.c
vg_translate.c

index 972077566dfeed19d758086745c8c59f9263d275..214d2ca1006c1bad097fbc623f4a6cdf873cfa08 100644 (file)
@@ -2605,8 +2605,7 @@ static void emitUInstr ( Int i, UInstr* u )
       case FPU:
          vg_assert(u->tag1 == Lit16);
          vg_assert(u->tag2 == NoValue);
-         vg_assert(u->flags_r == FlagsEmpty);
-         if (u->flags_w != FlagsEmpty) 
+         if (u->flags_r != FlagsEmpty || u->flags_w != FlagsEmpty) 
             emit_get_eflags();
          synth_fpu_no_mem ( (u->val1 >> 8) & 0xFF,
                             u->val1 & 0xFF );
index df52cdffcbb491ce339e1552c956fd4a93340b05..bed8ff69aedad874481f409d1cada3aba4944603 100644 (file)
@@ -2291,9 +2291,12 @@ static
 Addr dis_fpu_no_mem ( UCodeBlock* cb, Addr eip, UChar first_byte )
 {
    Bool  sets_ZCP    = False;
+   Bool  uses_ZCP    = False;
    UChar second_byte = getUChar(eip); eip++;
    vg_assert(second_byte >= 0xC0);
 
+   /* Does the insn write any integer condition codes (%EIP) ? */
+
    if (first_byte == 0xDB && second_byte >= 0xF0 && second_byte <= 0xF7) {
       /* FCOMI */
       sets_ZCP = True;
@@ -2311,17 +2314,43 @@ Addr dis_fpu_no_mem ( UCodeBlock* cb, Addr eip, UChar first_byte )
       sets_ZCP = True;
    } 
 
+   /* Dually, does the insn read any integer condition codes (%EIP) ? */
+
+   if (first_byte == 0xDA && second_byte >= 0xC0 && second_byte <= 0xDF) {
+      /* FCMOVB  %st(n), %st(0)
+         FCMOVE  %st(n), %st(0)
+         FCMOVBE %st(n), %st(0)
+         FCMOVU  %st(n), %st(0)
+      */
+      uses_ZCP = True;
+   } else
+   if (first_byte == 0xDB && second_byte >= 0xC0 && second_byte <= 0xDF) {
+      /* FCMOVNB  %st(n), %st(0)
+         FCMOVNE  %st(n), %st(0)
+         FCMOVNBE %st(n), %st(0)
+         FCMOVNU  %st(n), %st(0)
+      */
+      uses_ZCP = True;
+   }
+
    uInstr1(cb, FPU, 0,
                Lit16,
                (((UShort)first_byte) << 8) | ((UShort)second_byte)
           );
+   if (uses_ZCP) {
+      /* VG_(printf)("!!! --- FPU insn which reads %EFLAGS\n"); */
+      uFlagsRWU(cb, FlagsZCP, FlagsEmpty, FlagsEmpty);
+      vg_assert(!sets_ZCP);
+   }
    if (sets_ZCP) {
       /* VG_(printf)("!!! --- FPU insn which writes %EFLAGS\n"); */
       uFlagsRWU(cb, FlagsEmpty, FlagsZCP, FlagsEmpty);
+      vg_assert(!uses_ZCP);
    }
 
-   if (dis) VG_(printf)("fpu 0x%x:0x%x%s\n",
+   if (dis) VG_(printf)("fpu 0x%x:0x%x%s%s\n",
                         (UInt)first_byte, (UInt)second_byte,
+                        uses_ZCP ? " -rZCP" : "",
                         sets_ZCP ? " -wZCP" : "" );
    return eip;
 }
index ca4f64e25ffe1acd0b913ab649abed1d3596c1e9..19bdfb5d8a0b68a6a21aa3fe9720db62e72032ae 100644 (file)
@@ -476,8 +476,10 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 #  define CC0 (u->flags_r == FlagsEmpty && u->flags_w == FlagsEmpty)
 #  define FLG_RD (u->flags_r == FlagsALL && u->flags_w == FlagsEmpty)
 #  define FLG_WR (u->flags_r == FlagsEmpty && u->flags_w == FlagsALL)
-#  define FLG_WR_MAYBE (u->flags_r == FlagsEmpty && \
-                    (u->flags_w == FlagsEmpty || u->flags_w == FlagsZCP))
+#  define FLG_RD_WR_MAYBE                                         \
+       ((u->flags_r == FlagsEmpty && u->flags_w == FlagsEmpty)    \
+        || (u->flags_r == FlagsEmpty && u->flags_w == FlagsZCP)   \
+        || (u->flags_r == FlagsZCP && u->flags_w == FlagsEmpty))
 #  define CC1 (!(CC0))
 #  define SZ4_IF_TR1 ((u->tag1 == TempReg || u->tag1 == RealReg) \
                       ? (u->size == 4) : True)
@@ -491,9 +493,9 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 
    switch (u->opcode) {
       case GETF:
-       return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_RD;
+         return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_RD;
       case PUTF:
-       return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_WR;
+         return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_WR;
       case CALLM_S: case CALLM_E:
          return SZ0 && N1 && N2 && N3;
       case INCEIP:
@@ -540,7 +542,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
       case FPU_R:  case FPU_W: 
          return CC0 && Ls1 && TR2 && N3;
       case FPU: 
-         return SZ0 && FLG_WR_MAYBE && Ls1 && N2 && N3;
+         return SZ0 && FLG_RD_WR_MAYBE && Ls1 && N2 && N3;
       case LOADV:
          return CC0 && TR1 && TR2 && N3;
       case STOREV:
@@ -590,7 +592,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 #  undef N3
 #  undef FLG_RD
 #  undef FLG_WR
-#  undef FLG_WR_MAYBE
+#  undef FLG_RD_WR_MAYBE 
 }
 
 
index 972077566dfeed19d758086745c8c59f9263d275..214d2ca1006c1bad097fbc623f4a6cdf873cfa08 100644 (file)
@@ -2605,8 +2605,7 @@ static void emitUInstr ( Int i, UInstr* u )
       case FPU:
          vg_assert(u->tag1 == Lit16);
          vg_assert(u->tag2 == NoValue);
-         vg_assert(u->flags_r == FlagsEmpty);
-         if (u->flags_w != FlagsEmpty) 
+         if (u->flags_r != FlagsEmpty || u->flags_w != FlagsEmpty) 
             emit_get_eflags();
          synth_fpu_no_mem ( (u->val1 >> 8) & 0xFF,
                             u->val1 & 0xFF );
index df52cdffcbb491ce339e1552c956fd4a93340b05..bed8ff69aedad874481f409d1cada3aba4944603 100644 (file)
@@ -2291,9 +2291,12 @@ static
 Addr dis_fpu_no_mem ( UCodeBlock* cb, Addr eip, UChar first_byte )
 {
    Bool  sets_ZCP    = False;
+   Bool  uses_ZCP    = False;
    UChar second_byte = getUChar(eip); eip++;
    vg_assert(second_byte >= 0xC0);
 
+   /* Does the insn write any integer condition codes (%EIP) ? */
+
    if (first_byte == 0xDB && second_byte >= 0xF0 && second_byte <= 0xF7) {
       /* FCOMI */
       sets_ZCP = True;
@@ -2311,17 +2314,43 @@ Addr dis_fpu_no_mem ( UCodeBlock* cb, Addr eip, UChar first_byte )
       sets_ZCP = True;
    } 
 
+   /* Dually, does the insn read any integer condition codes (%EIP) ? */
+
+   if (first_byte == 0xDA && second_byte >= 0xC0 && second_byte <= 0xDF) {
+      /* FCMOVB  %st(n), %st(0)
+         FCMOVE  %st(n), %st(0)
+         FCMOVBE %st(n), %st(0)
+         FCMOVU  %st(n), %st(0)
+      */
+      uses_ZCP = True;
+   } else
+   if (first_byte == 0xDB && second_byte >= 0xC0 && second_byte <= 0xDF) {
+      /* FCMOVNB  %st(n), %st(0)
+         FCMOVNE  %st(n), %st(0)
+         FCMOVNBE %st(n), %st(0)
+         FCMOVNU  %st(n), %st(0)
+      */
+      uses_ZCP = True;
+   }
+
    uInstr1(cb, FPU, 0,
                Lit16,
                (((UShort)first_byte) << 8) | ((UShort)second_byte)
           );
+   if (uses_ZCP) {
+      /* VG_(printf)("!!! --- FPU insn which reads %EFLAGS\n"); */
+      uFlagsRWU(cb, FlagsZCP, FlagsEmpty, FlagsEmpty);
+      vg_assert(!sets_ZCP);
+   }
    if (sets_ZCP) {
       /* VG_(printf)("!!! --- FPU insn which writes %EFLAGS\n"); */
       uFlagsRWU(cb, FlagsEmpty, FlagsZCP, FlagsEmpty);
+      vg_assert(!uses_ZCP);
    }
 
-   if (dis) VG_(printf)("fpu 0x%x:0x%x%s\n",
+   if (dis) VG_(printf)("fpu 0x%x:0x%x%s%s\n",
                         (UInt)first_byte, (UInt)second_byte,
+                        uses_ZCP ? " -rZCP" : "",
                         sets_ZCP ? " -wZCP" : "" );
    return eip;
 }
index ca4f64e25ffe1acd0b913ab649abed1d3596c1e9..19bdfb5d8a0b68a6a21aa3fe9720db62e72032ae 100644 (file)
@@ -476,8 +476,10 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 #  define CC0 (u->flags_r == FlagsEmpty && u->flags_w == FlagsEmpty)
 #  define FLG_RD (u->flags_r == FlagsALL && u->flags_w == FlagsEmpty)
 #  define FLG_WR (u->flags_r == FlagsEmpty && u->flags_w == FlagsALL)
-#  define FLG_WR_MAYBE (u->flags_r == FlagsEmpty && \
-                    (u->flags_w == FlagsEmpty || u->flags_w == FlagsZCP))
+#  define FLG_RD_WR_MAYBE                                         \
+       ((u->flags_r == FlagsEmpty && u->flags_w == FlagsEmpty)    \
+        || (u->flags_r == FlagsEmpty && u->flags_w == FlagsZCP)   \
+        || (u->flags_r == FlagsZCP && u->flags_w == FlagsEmpty))
 #  define CC1 (!(CC0))
 #  define SZ4_IF_TR1 ((u->tag1 == TempReg || u->tag1 == RealReg) \
                       ? (u->size == 4) : True)
@@ -491,9 +493,9 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 
    switch (u->opcode) {
       case GETF:
-       return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_RD;
+         return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_RD;
       case PUTF:
-       return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_WR;
+         return (SZ2 || SZ4) && TR1 && N2 && N3 && FLG_WR;
       case CALLM_S: case CALLM_E:
          return SZ0 && N1 && N2 && N3;
       case INCEIP:
@@ -540,7 +542,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
       case FPU_R:  case FPU_W: 
          return CC0 && Ls1 && TR2 && N3;
       case FPU: 
-         return SZ0 && FLG_WR_MAYBE && Ls1 && N2 && N3;
+         return SZ0 && FLG_RD_WR_MAYBE && Ls1 && N2 && N3;
       case LOADV:
          return CC0 && TR1 && TR2 && N3;
       case STOREV:
@@ -590,7 +592,7 @@ Bool VG_(saneUInstr) ( Bool beforeRA, UInstr* u )
 #  undef N3
 #  undef FLG_RD
 #  undef FLG_WR
-#  undef FLG_WR_MAYBE
+#  undef FLG_RD_WR_MAYBE 
 }