]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
real.h (struct real_value): Add signalling.
authorRichard Henderson <rth@redhat.com>
Thu, 27 Mar 2003 22:42:02 +0000 (14:42 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 27 Mar 2003 22:42:02 +0000 (14:42 -0800)
        * real.h (struct real_value): Add signalling.
        (EXP_BITS): Decrement.
        * real.c (get_canonical_qnan): Don't set MSB-1.
        (get_canonical_snan): Likewise.  Set signalling.
        (real_identical): Compare signalling.
        (round_for_format): Remove force-one-bit on code.
        (real_nan): Likewise.  Set signalling.
        (encode_ieee_single): Add force-one-bit code; honor signalling.
        (encode_ieee_double, encode_ieee_extended, encode_ieee_quad): Likewise.
        (decode_ieee_single): Set signalling.
        (decode_ieee_double, decode_ieee_extended, decode_ieee_quad): Likewise.

From-SVN: r64935

gcc/ChangeLog
gcc/real.c
gcc/real.h

index b76daafe4aa6ec3f734aad843ad29df588dd42dc..a706e78f8c301b487c2d24f6570f3fc888422e07 100644 (file)
@@ -1,3 +1,17 @@
+2003-03-27  Richard Henderson  <rth@redhat.com>
+
+       * real.h (struct real_value): Add signalling.
+       (EXP_BITS): Decrement.
+       * real.c (get_canonical_qnan): Don't set MSB-1.
+       (get_canonical_snan): Likewise.  Set signalling.
+       (real_identical): Compare signalling.
+       (round_for_format): Remove force-one-bit on code.
+       (real_nan): Likewise.  Set signalling.
+       (encode_ieee_single): Add force-one-bit code; honor signalling.
+       (encode_ieee_double, encode_ieee_extended, encode_ieee_quad): Likewise.
+       (decode_ieee_single): Set signalling.
+       (decode_ieee_double, decode_ieee_extended, decode_ieee_quad): Likewise.
+
 2003-03-27  Olivier Hainque  <hainque@act-europe.fr>
 
        PR ada/9953
index 1e70bf7d4d95d94548a3c431b40dba3f6e83f19e..f6074f99639242b9abf6ef49fb2fa2b71d4d8b40 100644 (file)
@@ -158,7 +158,6 @@ get_canonical_qnan (r, sign)
   memset (r, 0, sizeof (*r));
   r->class = rvc_nan;
   r->sign = sign;
-  r->sig[SIGSZ-1] = SIG_MSB >> 1;
 }
 
 static inline void
@@ -169,7 +168,7 @@ get_canonical_snan (r, sign)
   memset (r, 0, sizeof (*r));
   r->class = rvc_nan;
   r->sign = sign;
-  r->sig[SIGSZ-1] = SIG_MSB >> 2;
+  r->signalling = 1;
 }
 
 static inline void
@@ -1235,6 +1234,8 @@ real_identical (a, b)
        return false;
       /* FALLTHRU */
     case rvc_nan:
+      if (a->signalling != b->signalling)
+       return false;
       for (i = 0; i < SIGSZ; ++i)
        if (a->sig[i] != b->sig[i])
          return false;
@@ -2249,23 +2250,7 @@ real_nan (r, str, quiet, mode)
       r->sig[SIGSZ-1] &= ~SIG_MSB;
 
       /* Force quiet or signalling NaN.  */
-      if (quiet)
-       r->sig[SIGSZ-1] |= SIG_MSB >> 1;
-      else
-       r->sig[SIGSZ-1] &= ~(SIG_MSB >> 1);
-
-      /* Force at least one bit of the significand set.  */
-      for (d = 0; d < SIGSZ; ++d)
-       if (r->sig[d])
-         break;
-      if (d == SIGSZ)
-       r->sig[SIGSZ-1] |= SIG_MSB >> 2;
-
-      /* Our intermediate format forces QNaNs to have MSB-1 set.
-        If the target format has QNaNs with the top bit unset,
-        mirror the output routines and invert the top two bits.  */
-      if (!fmt->qnan_msb_set)
-       r->sig[SIGSZ-1] ^= (SIG_MSB >> 1) | (SIG_MSB >> 2);
+      r->signalling = !quiet;
     }
 
   return true;
@@ -2325,14 +2310,6 @@ round_for_format (fmt, r)
 
     case rvc_nan:
       clear_significand_below (r, np2);
-
-      /* If we've cleared the entire significand, we need one bit
-        set for this to continue to be a NaN.  */
-      for (i = 0; i < SIGSZ; ++i)
-       if (r->sig[i])
-         break;
-      if (i == SIGSZ)
-       r->sig[SIGSZ-1] = SIG_MSB >> 2;
       return;
 
     case rvc_normal:
@@ -2642,10 +2619,15 @@ encode_ieee_single (fmt, buf, r)
     case rvc_nan:
       if (fmt->has_nans)
        {
+         if (r->signalling == fmt->qnan_msb_set)
+           sig &= ~(1 << 22);
+         else
+           sig |= 1 << 22;
+         if (sig == 0)
+           sig = 1 << 21;
+
          image |= 255 << 23;
          image |= sig;
-         if (!fmt->qnan_msb_set)
-           image ^= 1 << 23 | 1 << 22;
        }
       else
        image |= 0x7fffffff;
@@ -2703,8 +2685,7 @@ decode_ieee_single (fmt, r, buf)
        {
          r->class = rvc_nan;
          r->sign = sign;
-         if (!fmt->qnan_msb_set)
-           image ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
+         r->signalling = ((image >> 22) & 1) ^ fmt->qnan_msb_set;
          r->sig[SIGSZ-1] = image;
        }
       else
@@ -2791,10 +2772,15 @@ encode_ieee_double (fmt, buf, r)
     case rvc_nan:
       if (fmt->has_nans)
        {
+         if (r->signalling == fmt->qnan_msb_set)
+           sig_hi &= ~(1 << 19);
+         else
+           sig_hi |= 1 << 19;
+         if (sig_hi == 0 && sig_lo == 0)
+           sig_hi = 1 << 18;
+
          image_hi |= 2047 << 20;
          image_hi |= sig_hi;
-         if (!fmt->qnan_msb_set)
-           image_hi ^= 1 << 19 | 1 << 18;
          image_lo = sig_lo;
        }
       else
@@ -2884,6 +2870,7 @@ decode_ieee_double (fmt, r, buf)
        {
          r->class = rvc_nan;
          r->sign = sign;
+         r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set;
          if (HOST_BITS_PER_LONG == 32)
            {
              r->sig[SIGSZ-1] = image_hi;
@@ -2891,9 +2878,6 @@ decode_ieee_double (fmt, r, buf)
            }
          else
            r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo;
-
-         if (!fmt->qnan_msb_set)
-           r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
        }
       else
        {
@@ -2999,8 +2983,12 @@ encode_ieee_extended (fmt, buf, r)
              sig_hi = sig_lo >> 31 >> 1;
              sig_lo &= 0xffffffff;
            }
-         if (!fmt->qnan_msb_set)
-           sig_hi ^= 1 << 30 | 1 << 29;
+         if (r->signalling == fmt->qnan_msb_set)
+           sig_hi &= ~(1 << 30);
+         else
+           sig_hi |= 1 << 30;
+         if ((sig_hi & 0x7fffffff) == 0 && sig_lo == 0)
+           sig_hi = 1 << 29;
 
          /* Intel requires the explicit integer bit to be set, otherwise
             it considers the value a "pseudo-nan".  Motorola docs say it
@@ -3131,6 +3119,7 @@ decode_ieee_extended (fmt, r, buf)
        {
          r->class = rvc_nan;
          r->sign = sign;
+         r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set;
          if (HOST_BITS_PER_LONG == 32)
            {
              r->sig[SIGSZ-1] = sig_hi;
@@ -3138,9 +3127,6 @@ decode_ieee_extended (fmt, r, buf)
            }
          else
            r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
-
-         if (!fmt->qnan_msb_set)
-           r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
        }
       else
        {
@@ -3395,9 +3381,12 @@ encode_ieee_quad (fmt, buf, r)
              image0 &= 0xffffffff;
              image2 &= 0xffffffff;
            }
-
-         if (!fmt->qnan_msb_set)
-           image3 ^= 1 << 15 | 1 << 14;
+         if (r->signalling == fmt->qnan_msb_set)
+           image3 &= ~0x8000;
+         else
+           image3 |= 0x8000;
+         if (((image3 & 0xffff) | image2 | image1 | image0) == 0)
+           image3 |= 0x4000;
        }
       else
        {
@@ -3522,6 +3511,7 @@ decode_ieee_quad (fmt, r, buf)
        {
          r->class = rvc_nan;
          r->sign = sign;
+         r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set;
 
          if (HOST_BITS_PER_LONG == 32)
            {
@@ -3536,9 +3526,6 @@ decode_ieee_quad (fmt, r, buf)
              r->sig[1] = (image3 << 31 << 1) | image2;
            }
          lshift_significand (r, r, SIGNIFICAND_BITS - 113);
-
-         if (!fmt->qnan_msb_set)
-           r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
        }
       else
        {
index 0055106555515c82cd61871226332db773029bc1..d16231acae88ac35b81536ed0af389811d4cfff9 100644 (file)
@@ -35,7 +35,7 @@ enum real_value_class {
 };
 
 #define SIGNIFICAND_BITS       (128 + HOST_BITS_PER_LONG)
-#define EXP_BITS               (32 - 3)
+#define EXP_BITS               (32 - 4)
 #define MAX_EXP                        ((1 << (EXP_BITS - 1)) - 1)
 #define SIGSZ                  (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
 #define SIG_MSB                        ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
@@ -44,6 +44,7 @@ struct real_value GTY(())
 {
   ENUM_BITFIELD (real_value_class) class : 2;
   unsigned int sign : 1;
+  unsigned int signalling : 1;
   signed int exp : EXP_BITS;
   unsigned long sig[SIGSZ];
 };