[RFA] patch for float/pthread issue.

Don Howard dhoward@redhat.com
Mon Apr 9 12:12:00 GMT 2001


Here is a patch from Kevin Buettner that fixes gdb's handling of the i387 fpu
tag word.  This bug causes multi-threaded programs run under gdb to produce
incorrect floating point results.

I added a single line to Kevin's patch ensure that gdb stores the fpu tag word
correctly:

in i387_fill_fxsave()
+		      val |= (1 << (fpreg * 2));



        * i387-nat.c (i387_supply_fxsave, i387_fill_fxsave, i387_tag):
        Fix typos in which hexadecimal constants were really intended
        to be binary constants.
        (i387_tag): Swap logic regarding zero vs non-zero exponents.


Index: i387-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i387-nat.c,v
retrieving revision 1.4
diff -p -u -w -r1.4 i387-nat.c
--- i387-nat.c	2001/03/01 01:39:20	1.4
+++ i387-nat.c	2001/04/09 17:39:50
@@ -210,17 +210,19 @@ i387_supply_fxsave (char *fxsave)
 	      int top;
 
 	      fstat = *(unsigned short *) (FXSAVE_ADDR (fxsave, FSTAT_REGNUM));
-	      top = ((fstat >> 11) & 0x111);
+	      top = ((fstat >> 11) & 0x7);
 
 	      for (fpreg = 7; fpreg >= 0; fpreg--)
 		{
-		  int tag = 0x11;
+		  int tag;
 
 		  if (val & (1 << fpreg))
 		    {
 		      int regnum = (fpreg + 8 - top) % 8 + FP0_REGNUM;
 		      tag = i387_tag (FXSAVE_ADDR (fxsave, regnum));
 		    }
+		  else
+		    tag = 3;		/* Empty */
 
 		  ftag |= tag << (2 * fpreg);
 		}
@@ -275,10 +277,10 @@ i387_fill_fxsave (char *fxsave, int regn
 
 		for (fpreg = 7; fpreg >= 0; fpreg--)
 		  {
-		    int tag = (ftag >> (fpreg * 2)) & 0x11;
+		    int tag = (ftag >> (fpreg * 2)) & 3;
 
-		    if (tag != 0x11)
-		      val |= (1 << fpreg);
+		    if (tag != 3)
+		      val |= (1 << (fpreg * 2));
 		  }
 
 		memcpy (FXSAVE_ADDR (fxsave, i), &val, 2);
@@ -312,32 +314,32 @@ i387_tag (unsigned char *raw)
   if (exponent == 0x7fff)
     {
       /* Special.  */
-      return (0x10);
+      return (2);
     }
   else if (exponent == 0x0000)
     {
-      if (integer)
+      if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
 	{
-	  /* Valid.  */
-	  return (0x00);
+	  /* Zero.  */
+	  return (1);
 	}
       else
 	{
 	  /* Special.  */
-	  return (0x10);
+	  return (2);
 	}
     }
   else
     {
-      if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
+      if (integer)
 	{
-	  /* Zero.  */
-	  return (0x01);
+	  /* Valid.  */
+	  return (0);
 	}
       else
 	{
 	  /* Special.  */
-	  return (0x10);
+	  return (2);
 	}
     }
 }



-- 
-Don
dhoward@redhat.com



More information about the Gdb-patches mailing list