OSDN Git Service

* config/rs6000/darwin-ldouble.c: Add big comment explaining
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Jan 2004 05:47:14 +0000 (05:47 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Jan 2004 05:47:14 +0000 (05:47 +0000)
exactly what is expected as a 'long double'.
(_xlqadd): When a value to be returned is representable as a
'double', just return it directly, do not construct it using a union.
Also, correct final fixup.
(_xlqmul): Likewise.
(_xlqdiv): Likewise.
* real.c (encode_ibm_extended): Make consistent with darwin-ldouble.c.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75629 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/darwin-ldouble.c
gcc/real.c

index 0ae5c9d..367a26a 100644 (file)
@@ -6,6 +6,15 @@
 
 2004-01-09  Geoffrey Keating  <geoffk@apple.com>
 
+       * config/rs6000/darwin-ldouble.c: Add big comment explaining
+       exactly what is expected as a 'long double'.
+       (_xlqadd): When a value to be returned is representable as a
+       'double', just return it directly, do not construct it using a union.
+       Also, correct final fixup.
+       (_xlqmul): Likewise.
+       (_xlqdiv): Likewise.
+       * real.c (encode_ibm_extended): Make consistent with darwin-ldouble.c.
+
        * config/rs6000/rs6000.md (fix_trunctfdi2): Delete.
 
 2004-01-09  Richard Henderson  <rth@redhat.com>
index 281eb2a..c73b24f 100644 (file)
@@ -37,6 +37,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    Floating-Point Computations", by Seppo Linnainmaa, ACM TOMS vol 7
    no 3, September 1961, pages 272-283.  */
 
+/* Each long double is made up of two IEEE doubles.  The value of the
+   long double is the sum of the values of the two parts.  The most
+   significant part is required to be the value of the long double
+   rounded to the nearest double, as specified by IEEE.  For Inf
+   values, the least significant part is required to be one of +0.0 or
+   -0.0.  No other requirements are made; so, for example, 1.0 may be
+   represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
+   NaN is don't-care.
+
+   This code currently assumes big-endian.  */
+
 #define fabs(x) __builtin_fabs(x)
 
 #define unlikely(x) __builtin_expect ((x), 0)
@@ -68,11 +79,8 @@ _xlqadd (double a, double b, double c, double d)
   FPR_zero = 0.0;
   FPR_PosInf = FPKINF;
 
-  if (unlikely (a != a) || unlikely (c != c)) {
-    z.dval[0] = a + c;         /* NaN result.  */
-    z.dval[1] = a + c;         /* NaN result.  */
-    return z.ldval;
-  }
+  if (unlikely (a != a) || unlikely (c != c)) 
+    return a + c;  /* NaN result.  */
 
   /* Ordered operands are arranged in order of their magnitudes.  */
 
@@ -110,18 +118,14 @@ _xlqadd (double a, double b, double c, double d)
   t = (tau + b) + a;        /* Sum values in ascending magnitude order.  */
 
   /* Infinite or zero result.  */
-  if (unlikely (fabs (t) == FPR_PosInf) || unlikely (t == FPR_zero))
-    {
-      z.dval[0] = t;
-      z.dval[1] = t >= 0.0 ? (fabs (t) >= 0.0 ? t : 0.0) : -0.0;
-      return z.ldval;
-    }
+  if (unlikely (t == FPR_zero) || unlikely (fabs (t) == FPR_PosInf))
+    return t;
 
   /* Usual case.  */
   tau = (((a-t) + b) + c) + d;
   u = t + tau;
   z.dval[0] = u;              /* Final fixup for long double result.  */
-  z.dval[1] = (u - t) + tau;
+  z.dval[1] = (t - u) + tau;
   return z.ldval;
 }
 
@@ -142,22 +146,10 @@ _xlqmul (double a, double b, double c, double d)
 
   t = a * c;                   /* Highest order double term.  */
 
-  if (unlikely (t != t) || unlikely (t == FPR_zero)) 
-    {
-      /* NaN or zero result.  */
-      z.dval[0] = t;
-      z.dval[1] = t;
-      return z.ldval;
-    }
+  if (unlikely (t != t) || unlikely (t == FPR_zero) 
+      || unlikely (fabs (t) == FPR_PosInf))
+    return t;
 
-  if (unlikely (fabs(t) == FPR_PosInf))
-    {
-      /* Infinite result.  */
-      z.dval[0] = t;
-      z.dval[1] = t >= 0 ? 0.0 : -0.0;
-      return z.ldval;
-    }
-  
   /* Finite nonzero result requires summing of terms of two highest
      orders.   */
   
@@ -170,7 +162,7 @@ _xlqmul (double a, double b, double c, double d)
 
   /* Construct long double result.  */
   z.dval[0] = u;
-  z.dval[1] = (u - t) + tau;
+  z.dval[1] = (t - u) + tau;
   return z.ldval;
 }
 
@@ -185,21 +177,9 @@ _xlqdiv (double a, double b, double c, double d)
   
   t = a / c;                    /* highest order double term */
   
-  if (unlikely (t != t) || unlikely (t == FPR_zero))
-    {
-      /* NaN or zero result.  */
-      z.dval[0] = t;
-      z.dval[1] = t;
-      return z.ldval;
-    }
-
-  if (unlikely (fabs (t) == FPR_PosInf))
-    {
-      /* Infinite result.  */
-      z.dval[0] = t;
-      z.dval[1] = t >= 0.0 ? 0.0 : -0.0;
-      return z.ldval;
-    }
+  if (unlikely (t != t) || unlikely (t == FPR_zero) 
+      || unlikely (fabs (t) == FPR_PosInf))
+    return t;
 
   /* Finite nonzero result requires corrections to the highest order term.  */
 
index f7af346..ecee90b 100644 (file)
@@ -3235,53 +3235,23 @@ encode_ibm_extended (const struct real_format *fmt, long *buf,
 
   base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
 
-  switch (r->class)
-    {
-    case rvc_zero:
-      /* Both doubles have sign bit set.  */
-      buf[0] = FLOAT_WORDS_BIG_ENDIAN ? r->sign << 31 : 0;
-      buf[1] = FLOAT_WORDS_BIG_ENDIAN ? 0 : r->sign << 31;
-      buf[2] = buf[0];
-      buf[3] = buf[1];
-      break;
-
-    case rvc_inf:
-    case rvc_nan:
-      /* Both doubles set to Inf / NaN.  */
-      encode_ieee_double (base_fmt, &buf[0], r);
-      buf[2] = buf[0];
-      buf[3] = buf[1];
-      return;
+  /* u = IEEE double precision portion of significand.  */
+  u = *r;
+  round_for_format (base_fmt, &u);
+  encode_ieee_double (base_fmt, &buf[0], &u);
 
-    case rvc_normal:
-      /* u = IEEE double precision portion of significand.  */
-      u = *r;
-      clear_significand_below (&u, SIGNIFICAND_BITS - 53);
-
-      normalize (&u);
-      /* If the upper double is zero, we have a denormal double, so
-        move it to the first double and leave the second as zero.  */
-      if (u.class == rvc_zero)
-       {
-         v = u;
-         u = *r;
-         normalize (&u);
-       }
-      else
-       {
-         /* v = remainder containing additional 53 bits of significand.  */
-         do_add (&v, r, &u, 1);
-         round_for_format (base_fmt, &v);
-       }
-
-      round_for_format (base_fmt, &u);
-
-      encode_ieee_double (base_fmt, &buf[0], &u);
+  if (r->class == rvc_normal)
+    {
+      do_add (&v, r, &u, 1);
+      round_for_format (base_fmt, &v);
       encode_ieee_double (base_fmt, &buf[2], &v);
-      break;
-
-    default:
-      abort ();
+    }
+  else
+    {
+      /* Inf, NaN, 0 are all representable as doubles, so the
+        least-significant part can be 0.0.  */
+      buf[2] = 0;
+      buf[3] = 0;
     }
 }