From: Alexandre Oliva Date: Tue, 1 Apr 2003 21:45:28 +0000 (+0000) Subject: real.h (EXP_BITS): Make room for... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fe0002ee9dd1311b3dc451132198def49a465203;p=gcc.git real.h (EXP_BITS): Make room for... * real.h (EXP_BITS): Make room for... (struct real_value): ... added canonical bit. (struct real_format): Added pnan. (mips_single_format, mips_double_format, mips_extended_format, mips_quad_format): New. * real.c: Copy p to pnan in all formats. (get_canonical_qnan, get_canonical_snan): Set canonical bit. (real_nan): Use pnan to compute significand's shift. (real_identical): Disregard significand in canonical NaNs. (real_hash): Likewise. Take signalling into account. (encode_ieee_single, encode_ieee_double, encode_ieee_quad): Disregard significand bits in canonical NaNs. Set all bits of canonical NaN if !qnan_msb_set. (encode_ibm_extended, decode_ibm_extended): Likewise. Use qnan_msb_set to tell the base double format. (ibm_extended_format): Use 53 as pnan. (mips_single_format, mips_double_format, mips_extended_format, mips_quad_format): Copied from the corresponding ieee/ibm formats, with qnan_msb_set false. * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Use mips_extended_format. * config/mips/linux64.h (MIPS_TFMODE_FORMAT): Use mips_quad_format. * config/mips/mips.c (override_options): Use mips_single_format and mips_double_format. Default TFmode to mips_quad_format. * config/mips/t-linux64 (tp-bit.c): Define QUIET_NAN_NEGATED. * config/mips/t-irix6: Likewise. * config/mips/t-mips (fp-bit.c, dp-bit.c): Likewise. * config/fp-bit.c (pack_d, unpack_d): Obey it. From-SVN: r65146 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a96f1ad677a..82c47e019bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2003-04-01 Alexandre Oliva + + * real.h (EXP_BITS): Make room for... + (struct real_value): ... added canonical bit. + (struct real_format): Added pnan. + (mips_single_format, mips_double_format, mips_extended_format, + mips_quad_format): New. + * real.c: Copy p to pnan in all formats. + (get_canonical_qnan, get_canonical_snan): Set canonical bit. + (real_nan): Use pnan to compute significand's shift. + (real_identical): Disregard significand in canonical + NaNs. + (real_hash): Likewise. Take signalling into account. + (encode_ieee_single, encode_ieee_double, encode_ieee_quad): + Disregard significand bits in canonical NaNs. Set all bits of + canonical NaN if !qnan_msb_set. + (encode_ibm_extended, decode_ibm_extended): Likewise. Use + qnan_msb_set to tell the base double format. + (ibm_extended_format): Use 53 as pnan. + (mips_single_format, mips_double_format, mips_extended_format, + mips_quad_format): Copied from the corresponding ieee/ibm + formats, with qnan_msb_set false. + * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Use mips_extended_format. + * config/mips/linux64.h (MIPS_TFMODE_FORMAT): Use mips_quad_format. + * config/mips/mips.c (override_options): Use mips_single_format + and mips_double_format. Default TFmode to mips_quad_format. + * config/mips/t-linux64 (tp-bit.c): Define QUIET_NAN_NEGATED. + * config/mips/t-irix6: Likewise. + * config/mips/t-mips (fp-bit.c, dp-bit.c): Likewise. + * config/fp-bit.c (pack_d, unpack_d): Obey it. + 2003-04-01 Geoffrey Keating * unwind-dw2-fde-darwin.c (DESTRUCTOR_MAY_BE_CALLED_LIVE): New. diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c index 3e0b843f505..2832f96d578 100644 --- a/gcc/config/fp-bit.c +++ b/gcc/config/fp-bit.c @@ -210,7 +210,11 @@ pack_d ( fp_number_type * src) exp = EXPMAX; if (src->class == CLASS_QNAN || 1) { +#ifdef QUIET_NAN_NEGATED + fraction |= QUIET_NAN - 1; +#else fraction |= QUIET_NAN; +#endif } } else if (isinf (src)) @@ -521,7 +525,11 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) else { /* Nonzero fraction, means nan */ +#ifdef QUIET_NAN_NEGATED + if ((fraction & QUIET_NAN) == 0) +#else if (fraction & QUIET_NAN) +#endif { dst->class = CLASS_QNAN; } diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h index dd69c156064..69f01aafa2f 100644 --- a/gcc/config/mips/iris6.h +++ b/gcc/config/mips/iris6.h @@ -525,4 +525,4 @@ do { \ -_SYSTYPE_SVR4 -woff 131 \ %{mabi=32: -32}%{mabi=n32: -n32}%{mabi=64: -64}%{!mabi*: -n32}" -#define MIPS_TFMODE_FORMAT ibm_extended_format +#define MIPS_TFMODE_FORMAT mips_extended_format diff --git a/gcc/config/mips/linux64.h b/gcc/config/mips/linux64.h index db1d4e0cc40..c78e789f89c 100644 --- a/gcc/config/mips/linux64.h +++ b/gcc/config/mips/linux64.h @@ -98,4 +98,4 @@ Boston, MA 02111-1307, USA. */ for long double. There's no need to override this here, since ieee_quad_format is the default, but let's put this here to make sure nobody thinks we just forgot to set it to something else. */ -#define MIPS_TFMODE_FORMAT ieee_quad_format +#define MIPS_TFMODE_FORMAT mips_quad_format diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index b806fb1c975..6425f232203 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -5714,8 +5714,12 @@ override_options () else mips16 = 0; + real_format_for_mode[SFmode - QFmode] = &mips_single_format; + real_format_for_mode[DFmode - QFmode] = &mips_double_format; #ifdef MIPS_TFMODE_FORMAT real_format_for_mode[TFmode - QFmode] = &MIPS_TFMODE_FORMAT; +#else + real_format_for_mode[TFmode - QFmode] = &mips_quad_format; #endif mips_print_operand_punct['?'] = 1; diff --git a/gcc/config/mips/t-iris6 b/gcc/config/mips/t-iris6 index a1be0b9c9ed..d403df4cf00 100644 --- a/gcc/config/mips/t-iris6 +++ b/gcc/config/mips/t-iris6 @@ -27,6 +27,7 @@ tp-bit.c: $(srcdir)/config/fp-bit.c echo '#ifdef __MIPSEL__' > tp-bit.c echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c echo '#endif' >> tp-bit.c + echo '#define QUIET_NAN_NEGATED' >> dp-bit.c echo '#if __LDBL_MANT_DIG__ == 106' >> tp-bit.c echo '# define TFLOAT' >> tp-bit.c cat $(srcdir)/config/fp-bit.c >> tp-bit.c diff --git a/gcc/config/mips/t-linux64 b/gcc/config/mips/t-linux64 index cf639287770..a0792f23a94 100644 --- a/gcc/config/mips/t-linux64 +++ b/gcc/config/mips/t-linux64 @@ -13,6 +13,7 @@ tp-bit.c: $(srcdir)/config/fp-bit.c echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c echo '#endif' >> tp-bit.c echo '#if __LDBL_MANT_DIG__ == 113' >> tp-bit.c + echo '#define QUIET_NAN_NEGATED' >> dp-bit.c echo '# define TFLOAT' >> tp-bit.c cat $(srcdir)/config/fp-bit.c >> tp-bit.c echo '#endif' >> tp-bit.c diff --git a/gcc/config/mips/t-mips b/gcc/config/mips/t-mips index 292386d0383..497f4fb20cb 100644 --- a/gcc/config/mips/t-mips +++ b/gcc/config/mips/t-mips @@ -9,6 +9,7 @@ dp-bit.c: $(srcdir)/config/fp-bit.c echo '#ifdef __MIPSEL__' > dp-bit.c echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c echo '#endif' >> dp-bit.c + echo '#define QUIET_NAN_NEGATED' >> dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c fp-bit.c: $(srcdir)/config/fp-bit.c @@ -16,4 +17,5 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#ifdef __MIPSEL__' >> fp-bit.c echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c echo '#endif' >> fp-bit.c + echo '#define QUIET_NAN_NEGATED' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c diff --git a/gcc/real.c b/gcc/real.c index 29d5de1f014..74f430c29ae 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -158,6 +158,7 @@ get_canonical_qnan (r, sign) memset (r, 0, sizeof (*r)); r->class = rvc_nan; r->sign = sign; + r->canonical = 1; } static inline void @@ -169,6 +170,7 @@ get_canonical_snan (r, sign) r->class = rvc_nan; r->sign = sign; r->signalling = 1; + r->canonical = 1; } static inline void @@ -1212,7 +1214,7 @@ real_isnegzero (r) /* Compare two floating-point objects for bitwise identity. */ -extern bool +bool real_identical (a, b) const REAL_VALUE_TYPE *a, *b; { @@ -1237,6 +1239,9 @@ real_identical (a, b) case rvc_nan: if (a->signalling != b->signalling) return false; + /* The significand is ignored for canonical NaNs. */ + if (a->canonical || b->canonical) + return a->canonical == b->canonical; break; default: @@ -2246,7 +2251,7 @@ real_nan (r, str, quiet, mode) /* Shift the significand into place such that the bits are in the most significant bits for the format. */ - lshift_significand (r, r, SIGNIFICAND_BITS - fmt->p); + lshift_significand (r, r, SIGNIFICAND_BITS - fmt->pnan); /* Our MSB is always unset for NaNs. */ r->sig[SIGSZ-1] &= ~SIG_MSB; @@ -2562,28 +2567,33 @@ real_hash (r) { case rvc_zero: case rvc_inf: - break; + return h; case rvc_normal: h |= r->exp << 3; - /* FALLTHRU */ + break; case rvc_nan: - if (sizeof(unsigned long) > sizeof(unsigned int)) - for (i = 0; i < SIGSZ; ++i) - { - unsigned long s = r->sig[i]; - h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2)); - } - else - for (i = 0; i < SIGSZ; ++i) - h ^= r->sig[i]; + if (r->signalling) + h ^= (unsigned int)-1; + if (r->canonical) + return h; break; default: abort (); } + if (sizeof(unsigned long) > sizeof(unsigned int)) + for (i = 0; i < SIGSZ; ++i) + { + unsigned long s = r->sig[i]; + h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2)); + } + else + for (i = 0; i < SIGSZ; ++i) + h ^= r->sig[i]; + return h; } @@ -2621,11 +2631,19 @@ encode_ieee_single (fmt, buf, r) case rvc_nan: if (fmt->has_nans) { + if (r->canonical) + sig = 0; if (r->signalling == fmt->qnan_msb_set) sig &= ~(1 << 22); else sig |= 1 << 22; - if (sig == 0) + /* We overload qnan_msb_set here: it's only clear for + mips_ieee_single, which wants all mantissa bits but the + quiet/signalling one set in canonical NaNs (at least + Quiet ones). */ + if (r->canonical && !fmt->qnan_msb_set) + sig |= (1 << 22) - 1; + else if (sig == 0) sig = 1 << 21; image |= 255 << 23; @@ -2712,6 +2730,7 @@ const struct real_format ieee_single_format = 2, 1, 24, + 24, -125, 128, 31, @@ -2722,6 +2741,24 @@ const struct real_format ieee_single_format = true }; +const struct real_format mips_single_format = + { + encode_ieee_single, + decode_ieee_single, + 2, + 1, + 24, + 24, + -125, + 128, + 31, + true, + true, + true, + true, + false + }; + /* IEEE double-precision format. */ @@ -2774,11 +2811,22 @@ encode_ieee_double (fmt, buf, r) case rvc_nan: if (fmt->has_nans) { + if (r->canonical) + sig_hi = sig_lo = 0; if (r->signalling == fmt->qnan_msb_set) sig_hi &= ~(1 << 19); else sig_hi |= 1 << 19; - if (sig_hi == 0 && sig_lo == 0) + /* We overload qnan_msb_set here: it's only clear for + mips_ieee_single, which wants all mantissa bits but the + quiet/signalling one set in canonical NaNs (at least + Quiet ones). */ + if (r->canonical && !fmt->qnan_msb_set) + { + sig_hi |= (1 << 19) - 1; + sig_lo = 0xffffffff; + } + else if (sig_hi == 0 && sig_lo == 0) sig_hi = 1 << 18; image_hi |= 2047 << 20; @@ -2909,6 +2957,7 @@ const struct real_format ieee_double_format = 2, 1, 53, + 53, -1021, 1024, 63, @@ -2919,6 +2968,24 @@ const struct real_format ieee_double_format = true }; +const struct real_format mips_double_format = + { + encode_ieee_double, + decode_ieee_double, + 2, + 1, + 53, + 53, + -1021, + 1024, + 63, + true, + true, + true, + true, + false + }; + /* IEEE extended double precision format. This comes in three flavours: Intel's as a 12 byte image, Intel's as a 16 byte image, @@ -3167,6 +3234,7 @@ const struct real_format ieee_extended_motorola_format = 2, 1, 64, + 64, -16382, 16384, 95, @@ -3184,6 +3252,7 @@ const struct real_format ieee_extended_intel_96_format = 2, 1, 64, + 64, -16381, 16384, 79, @@ -3201,6 +3270,7 @@ const struct real_format ieee_extended_intel_128_format = 2, 1, 64, + 64, -16381, 16384, 79, @@ -3228,11 +3298,14 @@ static void decode_ibm_extended PARAMS ((const struct real_format *, static void encode_ibm_extended (fmt, buf, r) - const struct real_format *fmt ATTRIBUTE_UNUSED; + const struct real_format *fmt; long *buf; const REAL_VALUE_TYPE *r; { REAL_VALUE_TYPE u, v; + const struct real_format *base_fmt; + + base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; switch (r->class) { @@ -3247,7 +3320,7 @@ encode_ibm_extended (fmt, buf, r) case rvc_inf: case rvc_nan: /* Both doubles set to Inf / NaN. */ - encode_ieee_double (&ieee_double_format, &buf[0], r); + encode_ieee_double (base_fmt, &buf[0], r); buf[2] = buf[0]; buf[3] = buf[1]; return; @@ -3270,13 +3343,13 @@ encode_ibm_extended (fmt, buf, r) { /* v = remainder containing additional 53 bits of significand. */ do_add (&v, r, &u, 1); - round_for_format (&ieee_double_format, &v); + round_for_format (base_fmt, &v); } - round_for_format (&ieee_double_format, &u); + round_for_format (base_fmt, &u); - encode_ieee_double (&ieee_double_format, &buf[0], &u); - encode_ieee_double (&ieee_double_format, &buf[2], &v); + encode_ieee_double (base_fmt, &buf[0], &u); + encode_ieee_double (base_fmt, &buf[2], &v); break; default: @@ -3291,12 +3364,14 @@ decode_ibm_extended (fmt, r, buf) const long *buf; { REAL_VALUE_TYPE u, v; + const struct real_format *base_fmt; - decode_ieee_double (&ieee_double_format, &u, &buf[0]); + base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; + decode_ieee_double (base_fmt, &u, &buf[0]); if (u.class != rvc_zero && u.class != rvc_inf && u.class != rvc_nan) { - decode_ieee_double (&ieee_double_format, &v, &buf[2]); + decode_ieee_double (base_fmt, &v, &buf[2]); do_add (r, &u, &v, 0); } else @@ -3310,6 +3385,7 @@ const struct real_format ibm_extended_format = 2, 1, 53 + 53, + 53, -1021 + 53, 1024, -1, @@ -3320,6 +3396,24 @@ const struct real_format ibm_extended_format = true }; +const struct real_format mips_extended_format = + { + encode_ibm_extended, + decode_ibm_extended, + 2, + 1, + 53 + 53, + 53, + -1021 + 53, + 1024, + -1, + true, + true, + true, + true, + false + }; + /* IEEE quad precision format. */ @@ -3367,7 +3461,12 @@ encode_ieee_quad (fmt, buf, r) { image3 |= 32767 << 16; - if (HOST_BITS_PER_LONG == 32) + if (r->canonical) + { + /* Don't use bits from the significand. The + initialization above is right. */ + } + else if (HOST_BITS_PER_LONG == 32) { image0 = u.sig[0]; image1 = u.sig[1]; @@ -3387,7 +3486,16 @@ encode_ieee_quad (fmt, buf, r) image3 &= ~0x8000; else image3 |= 0x8000; - if (((image3 & 0xffff) | image2 | image1 | image0) == 0) + /* We overload qnan_msb_set here: it's only clear for + mips_ieee_single, which wants all mantissa bits but the + quiet/signalling one set in canonical NaNs (at least + Quiet ones). */ + if (r->canonical && !fmt->qnan_msb_set) + { + image3 |= 0x7fff; + image2 = image1 = image0 = 0xffffffff; + } + else if (((image3 & 0xffff) | image2 | image1 | image0) == 0) image3 |= 0x4000; } else @@ -3565,6 +3673,7 @@ const struct real_format ieee_quad_format = 2, 1, 113, + 113, -16381, 16384, 127, @@ -3574,6 +3683,24 @@ const struct real_format ieee_quad_format = true, true }; + +const struct real_format mips_quad_format = + { + encode_ieee_quad, + decode_ieee_quad, + 2, + 1, + 113, + 113, + -16381, + 16384, + 127, + true, + true, + true, + true, + false + }; /* Descriptions of VAX floating point formats can be found beginning at @@ -3873,6 +4000,7 @@ const struct real_format vax_f_format = 2, 1, 24, + 24, -127, 127, 15, @@ -3890,6 +4018,7 @@ const struct real_format vax_d_format = 2, 1, 56, + 56, -127, 127, 15, @@ -3907,6 +4036,7 @@ const struct real_format vax_g_format = 2, 1, 53, + 53, -1023, 1023, 15, @@ -4089,6 +4219,7 @@ const struct real_format i370_single_format = 16, 4, 6, + 6, -64, 63, 31, @@ -4106,6 +4237,7 @@ const struct real_format i370_double_format = 16, 4, 14, + 14, -64, 63, 63, @@ -4321,6 +4453,7 @@ const struct real_format c4x_single_format = 2, 1, 24, + 24, -126, 128, -1, @@ -4338,6 +4471,7 @@ const struct real_format c4x_extended_format = 2, 1, 32, + 32, -126, 128, -1, @@ -4384,6 +4518,7 @@ const struct real_format real_internal_format = 2, 1, SIGNIFICAND_BITS - 2, + SIGNIFICAND_BITS - 2, -MAX_EXP, MAX_EXP, -1, diff --git a/gcc/real.h b/gcc/real.h index 9507af2270d..0a470a512f3 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -35,7 +35,7 @@ enum real_value_class { }; #define SIGNIFICAND_BITS (128 + HOST_BITS_PER_LONG) -#define EXP_BITS (32 - 4) +#define EXP_BITS (32 - 5) #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)) @@ -45,6 +45,7 @@ struct real_value GTY(()) ENUM_BITFIELD (real_value_class) class : 2; unsigned int sign : 1; unsigned int signalling : 1; + unsigned int canonical : 1; signed int exp : EXP_BITS; unsigned long sig[SIGSZ]; }; @@ -119,6 +120,9 @@ struct real_format /* Size of the significand in digits of radix B. */ int p; + /* Size of the significant of a NaN, in digits of radix B. */ + int pnan; + /* The minimum negative integer, x, such that b**(x-1) is normalized. */ int emin; @@ -222,12 +226,16 @@ extern unsigned int real_hash PARAMS ((const REAL_VALUE_TYPE *)); /* Target formats defined in real.c. */ extern const struct real_format ieee_single_format; +extern const struct real_format mips_single_format; extern const struct real_format ieee_double_format; +extern const struct real_format mips_double_format; 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 mips_extended_format; extern const struct real_format ieee_quad_format; +extern const struct real_format mips_quad_format; extern const struct real_format vax_f_format; extern const struct real_format vax_d_format; extern const struct real_format vax_g_format;