This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] real.c IBM 128-bit extended format support


>>>>> Richard Henderson writes:

Richard> Both zeros carry the sign?

	Yes, both IEEE doubles carry the sign.

Richard> How do denormals work?  Seems like either you can't support them.
Richard> If you allow one double to underflow, that only gets you half
Richard> the denormal range.  Which, btw, would fail LIA-1's definition
Richard> of denormals, which means that you should set has_denorm false.

	Denormals in the IBM 128-bit extended precision format are limited
to IEEE double precision denormals.  The first number containing the part
of the value with large magnitude holds the IEEE double precision denormal
and the second number is zero.  When encode_ibm_extended calls
encode_ieee_double for the two parts, the first part will receive the IEEE
double precision denormalized value and the second part will underflow to
zero.  For decoding, the REAL_VALUE_TYPE precision will be truncated to
IEEE denormal.

David


	* real.h (ibm_extended_format): Declare.
	* real.c (encode_ibm_extended, decode_ibm_extended): New
	functions. 

Index: real.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/real.h,v
retrieving revision 1.52
diff -c -p -r1.52 real.h
*** real.h	21 Sep 2002 16:10:29 -0000	1.52
--- real.h	24 Sep 2002 17:39:34 -0000
*************** extern const struct real_format ieee_dou
*** 216,221 ****
--- 216,222 ----
  extern const struct real_format ieee_extended_motorola_format;
  extern const struct real_format ieee_extended_intel_96_format;
  extern const struct real_format ieee_extended_intel_128_format;
+ extern const struct real_format ibm_extended_format;
  extern const struct real_format ieee_quad_format;
  extern const struct real_format vax_f_format;
  extern const struct real_format vax_d_format;
Index: real.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/real.c,v
retrieving revision 1.91
diff -c -p -r1.91 real.c
*** real.c	23 Sep 2002 11:26:40 -0000	1.91
--- real.c	24 Sep 2002 17:39:35 -0000
*************** const struct real_format ieee_extended_i
*** 2951,2956 ****
--- 2951,3079 ----
    };
  
  
+ /* IBM 128-bit extended precision format: a pair of IEEE double precision
+    numbers whose sum is equal to the extended precision value.  The number
+    with greater magnitude is first.  This format has the same magnitude
+    range as an IEEE double precision value, but effectively 106 bits of
+    significand precision.  Infinity and NaN are represented by their IEEE
+    double precision value stored in the first number, the second number is
+    ignored.  */
+ 
+ static void encode_ibm_extended PARAMS ((const struct real_format *fmt,
+ 					 long *, const REAL_VALUE_TYPE *));
+ static void decode_ibm_extended PARAMS ((const struct real_format *,
+ 					 REAL_VALUE_TYPE *, const long *));
+ 
+ static void
+ encode_ibm_extended (fmt, buf, r)
+      const struct real_format *fmt ATTRIBUTE_UNUSED;
+      long *buf;
+      const REAL_VALUE_TYPE *r;
+ {
+   long image[4];
+   REAL_VALUE_TYPE u, v;
+ 
+   switch (r->class)
+     {
+     case rvc_zero:
+       /* Both doubles have sign bit set.  */
+       image[0] = r->sign << 31;
+       image[1] = 0;
+       image[2] = r->sign << 31;
+       image[3] = 0;
+       break;
+ 
+     case rvc_inf:
+     case rvc_nan:
+       encode_ieee_double (&ieee_double_format, &image[0], r);
+       image[2] = image[0];
+       image[3] = image[1];
+       return;
+       
+     case rvc_normal:
+       /* u = IEEE double precision portion of significand.  */
+       u = *r;
+       clear_significand_below (&u, SIGNIFICAND_BITS - 53);
+ 
+       /* v = remainder containing additional 53 bits of significand.  */
+       do_add (&v, r, &u, 1);
+ 
+       encode_ieee_double (&ieee_double_format, &image[0], &u);
+       encode_ieee_double (&ieee_double_format, &image[2], &v);
+       break;
+ 
+     default:
+       abort ();
+     }
+ 
+   if (FLOAT_WORDS_BIG_ENDIAN)
+     {
+       buf[0] = image[0];
+       buf[1] = image[1];
+       buf[2] = image[2];
+       buf[3] = image[3];
+     }
+   else
+     {
+       buf[0] = image[3];
+       buf[1] = image[2];
+       buf[2] = image[1];
+       buf[3] = image[0];
+     }
+ }
+ 
+ static void
+ decode_ibm_extended (fmt, r, buf)
+      const struct real_format *fmt ATTRIBUTE_UNUSED;
+      REAL_VALUE_TYPE *r;
+      const long *buf;
+ {
+   long image[4];
+   REAL_VALUE_TYPE u, v;
+ 
+   if (FLOAT_WORDS_BIG_ENDIAN)
+     {
+       image[0] = buf[0];
+       image[1] = buf[1];
+       image[2] = buf[2];
+       image[3] = buf[3];
+     }
+   else
+     {
+       image[3] = buf[0];
+       image[2] = buf[1];
+       image[1] = buf[2];
+       image[0] = buf[3];
+     }
+ 
+   decode_ieee_double (&ieee_double_format, &u, &image[0]);
+ 
+   if (u.class != rvc_zero && u.class != rvc_inf && u.class != rvc_nan)
+     {
+       decode_ieee_double (&ieee_double_format, &v, &image[2]);
+       do_add (r, &u, &v, 0);
+     }
+   else
+     *r = u;
+ }
+ 
+ const struct real_format ibm_extended_format = 
+   {
+     encode_ibm_extended,
+     decode_ibm_extended,
+     2,
+     1,
+     53 + 53,
+     -1021,
+     1024,
+     true,
+     true,
+     true,
+     true,
+     true
+   };
+ 
+ 
  /* IEEE quad precision format.  */
  
  static void encode_ieee_quad PARAMS ((const struct real_format *fmt,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]