X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Freal.c;h=5da2cb3b2cedf3f8958c6229116aa091690d431f;hp=5d5b12ff7e82baf54ef2edf8591c5dffb45614dc;hb=317db9789686e571d02df8129f7fd924d75c020a;hpb=c676730acf72c6f724ff87bfcbb4685125609a28 diff --git a/gcc/real.c b/gcc/real.c index 5d5b12ff7e8..5da2cb3b2ce 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -1,6 +1,6 @@ /* real.c - software floating point emulation. Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2000, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. Contributed by Stephen L. Moshier (moshier@world.std.com). Re-written by Richard Henderson @@ -8,7 +8,7 @@ GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2, or (at your option) any later + Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -17,9 +17,8 @@ for more details. You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING. If not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with GCC; see the file COPYING3. If not see + . */ #include "config.h" #include "system.h" @@ -65,12 +64,7 @@ have guard digits or rounding, the computation of 10**exp can accumulate more than a few digits of error. The previous incarnation of real.c successfully used a 144-bit fraction; given the current - layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits. - - Target floating point models that use base 16 instead of base 2 - (i.e. IBM 370), are handled during round_for_format, in which we - canonicalize the exponent to be a multiple of 4 (log2(16)), and - adjust the significand to match. */ + layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits. */ /* Used to classify two numbers simultaneously. */ @@ -1168,6 +1162,14 @@ real_isnan (const REAL_VALUE_TYPE *r) return (r->cl == rvc_nan); } +/* Determine whether a floating-point value X is finite. */ + +bool +real_isfinite (const REAL_VALUE_TYPE *r) +{ + return (r->cl != rvc_nan) && (r->cl != rvc_inf); +} + /* Determine whether a floating-point value X is negative. */ bool @@ -1469,7 +1471,8 @@ real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size, return; case rvc_nan: /* ??? Print the significand as well, if not canonical? */ - strcpy (str, (r.sign ? "-NaN" : "+NaN")); + sprintf (str, "%c%cNaN", (r_orig->sign ? '-' : '+'), + (r_orig->signalling ? 'S' : 'Q')); return; default: gcc_unreachable (); @@ -1741,7 +1744,8 @@ real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size, return; case rvc_nan: /* ??? Print the significand as well, if not canonical? */ - strcpy (str, (r->sign ? "-NaN" : "+NaN")); + sprintf (str, "%c%cNaN", (r->sign ? '-' : '+'), + (r->signalling ? 'S' : 'Q')); return; default: gcc_unreachable (); @@ -1791,9 +1795,10 @@ real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size, } /* Initialize R from a decimal or hexadecimal string. The string is - assumed to have been syntax checked already. */ + assumed to have been syntax checked already. Return -1 if the + value underflows, +1 if overflows, and 0 otherwise. */ -void +int real_from_string (REAL_VALUE_TYPE *r, const char *str) { int exp = 0; @@ -1809,6 +1814,22 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str) else if (*str == '+') str++; + if (!strncmp (str, "QNaN", 4)) + { + get_canonical_qnan (r, sign); + return 0; + } + else if (!strncmp (str, "SNaN", 4)) + { + get_canonical_snan (r, sign); + return 0; + } + else if (!strncmp (str, "Inf", 3)) + { + get_inf (r, sign); + return 0; + } + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { /* Hexadecimal floating point. */ @@ -1862,6 +1883,11 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str) str++; } } + + /* If the mantissa is zero, ignore the exponent. */ + if (!cmp_significand_0 (r)) + goto is_a_zero; + if (*str == 'p' || *str == 'P') { bool exp_neg = false; @@ -1934,6 +1960,10 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str) } } + /* If the mantissa is zero, ignore the exponent. */ + if (r->cl == rvc_zero) + goto is_a_zero; + if (*str == 'e' || *str == 'E') { bool exp_neg = false; @@ -1972,15 +2002,19 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str) } r->sign = sign; - return; + return 0; + + is_a_zero: + get_zero (r, sign); + return 0; underflow: get_zero (r, sign); - return; + return -1; overflow: get_inf (r, sign); - return; + return 1; } /* Legacy. Similar, but return the result directly. */ @@ -2147,6 +2181,49 @@ times_pten (REAL_VALUE_TYPE *r, int exp) do_divide (r, r, &pten); } +/* Returns the special REAL_VALUE_TYPE enumerated by E. */ + +const REAL_VALUE_TYPE * +get_real_const (enum real_value_const e) +{ + static REAL_VALUE_TYPE value[rv_max]; + + gcc_assert (e < rv_max); + + /* Initialize mathematical constants for constant folding builtins. + These constants need to be given to at least 160 bits precision. */ + if (value[e].cl == rvc_zero) + switch (e) + { + case rv_e: + { + mpfr_t m; + mpfr_init2 (m, SIGNIFICAND_BITS); + mpfr_set_ui (m, 1, GMP_RNDN); + mpfr_exp (m, m, GMP_RNDN); + real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN); + mpfr_clear (m); + } + break; + case rv_third: + real_arithmetic (&value[e], RDIV_EXPR, &dconst1, real_digit (3)); + break; + case rv_sqrt2: + { + mpfr_t m; + mpfr_init2 (m, SIGNIFICAND_BITS); + mpfr_sqrt_ui (m, 2, GMP_RNDN); + real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN); + mpfr_clear (m); + } + break; + default: + gcc_unreachable(); + } + + return &value[e]; +} + /* Fills R with +Inf. */ void @@ -2193,8 +2270,12 @@ real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet, str++; if (*str == '0') { - if (*++str == 'x') - str++, base = 16; + str++; + if (*str == 'x' || *str == 'X') + { + base = 16; + str++; + } else base = 8; } @@ -2264,18 +2345,27 @@ real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode) { r->cl = rvc_normal; r->sign = sign; - SET_REAL_EXP (r, fmt->emax * fmt->log2_b); + SET_REAL_EXP (r, fmt->emax); - np2 = SIGNIFICAND_BITS - fmt->p * fmt->log2_b; + np2 = SIGNIFICAND_BITS - fmt->p; memset (r->sig, -1, SIGSZ * sizeof (unsigned long)); clear_significand_below (r, np2); + + if (fmt->pnan < fmt->p) + /* This is an IBM extended double format 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. Rounding means we need a slightly smaller + value for LDBL_MAX. */ + clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan); } } /* Fills R with 2**N. */ void -real_2expN (REAL_VALUE_TYPE *r, int n) +real_2expN (REAL_VALUE_TYPE *r, int n, enum machine_mode fmode) { memset (r, 0, sizeof (*r)); @@ -2290,6 +2380,8 @@ real_2expN (REAL_VALUE_TYPE *r, int n) SET_REAL_EXP (r, n); r->sig[SIGSZ-1] = SIG_MSB; } + if (DECIMAL_FLOAT_MODE_P (fmode)) + decimal_real_convert (r, fmode, r); } @@ -2315,9 +2407,9 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r) decimal_real_convert (r, DFmode, r); } - p2 = fmt->p * fmt->log2_b; - emin2m1 = (fmt->emin - 1) * fmt->log2_b; - emax2 = fmt->emax * fmt->log2_b; + p2 = fmt->p; + emin2m1 = fmt->emin - 1; + emax2 = fmt->emax; np2 = SIGNIFICAND_BITS - p2; switch (r->cl) @@ -2345,22 +2437,6 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r) gcc_unreachable (); } - /* If we're not base2, normalize the exponent to a multiple of - the true base. */ - if (fmt->log2_b != 1) - { - int shift; - - gcc_assert (fmt->b != 10); - shift = REAL_EXP (r) & (fmt->log2_b - 1); - if (shift) - { - shift = fmt->log2_b - shift; - r->sig[0] |= sticky_rshift_significand (r, r, shift); - SET_REAL_EXP (r, REAL_EXP (r) + shift); - } - } - /* Check the range of the exponent. If we're out of range, either underflow or overflow. */ if (REAL_EXP (r) > emax2) @@ -2416,19 +2492,6 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r) if (REAL_EXP (r) > emax2) goto overflow; r->sig[SIGSZ-1] = SIG_MSB; - - if (fmt->log2_b != 1) - { - int shift = REAL_EXP (r) & (fmt->log2_b - 1); - if (shift) - { - shift = fmt->log2_b - shift; - rshift_significand (r, r, shift); - SET_REAL_EXP (r, REAL_EXP (r) + shift); - if (REAL_EXP (r) > emax2) - goto overflow; - } - } } } @@ -2486,7 +2549,7 @@ exact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a) gcc_assert (fmt); /* Don't allow conversion to denormals. */ - emin2m1 = (fmt->emin - 1) * fmt->log2_b; + emin2m1 = fmt->emin - 1; if (REAL_EXP (a) <= emin2m1) return false; @@ -2577,7 +2640,7 @@ significand_size (enum machine_mode mode) double log2_10 = 3.3219281; return fmt->p * log2_10; } - return fmt->p * fmt->log2_b; + return fmt->p; } /* Return a hash value for the given real value. */ @@ -2659,18 +2722,12 @@ encode_ieee_single (const struct real_format *fmt, long *buf, if (fmt->has_nans) { if (r->canonical) - sig = 0; + sig = (fmt->canonical_nan_lsbs_set ? (1 << 22) - 1 : 0); if (r->signalling == fmt->qnan_msb_set) sig &= ~(1 << 22); else sig |= 1 << 22; - /* 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) + if (sig == 0) sig = 1 << 21; image |= 255 << 23; @@ -2754,7 +2811,6 @@ const struct real_format ieee_single_format = encode_ieee_single, decode_ieee_single, 2, - 1, 24, 24, -125, @@ -2765,7 +2821,8 @@ const struct real_format ieee_single_format = true, true, true, - true + true, + false }; const struct real_format mips_single_format = @@ -2773,7 +2830,6 @@ const struct real_format mips_single_format = encode_ieee_single, decode_ieee_single, 2, - 1, 24, 24, -125, @@ -2784,9 +2840,28 @@ const struct real_format mips_single_format = true, true, true, - false + false, + true }; +const struct real_format motorola_single_format = + { + encode_ieee_single, + decode_ieee_single, + 2, + 24, + 24, + -125, + 128, + 31, + 31, + true, + true, + true, + true, + true, + true + }; /* IEEE double-precision format. */ @@ -2838,21 +2913,23 @@ encode_ieee_double (const struct real_format *fmt, long *buf, if (fmt->has_nans) { if (r->canonical) - sig_hi = sig_lo = 0; + { + if (fmt->canonical_nan_lsbs_set) + { + sig_hi = (1 << 19) - 1; + sig_lo = 0xffffffff; + } + else + { + sig_hi = 0; + sig_lo = 0; + } + } if (r->signalling == fmt->qnan_msb_set) sig_hi &= ~(1 << 19); else sig_hi |= 1 << 19; - /* 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) + if (sig_hi == 0 && sig_lo == 0) sig_hi = 1 << 18; image_hi |= 2047 << 20; @@ -2979,7 +3056,6 @@ const struct real_format ieee_double_format = encode_ieee_double, decode_ieee_double, 2, - 1, 53, 53, -1021, @@ -2990,7 +3066,8 @@ const struct real_format ieee_double_format = true, true, true, - true + true, + false }; const struct real_format mips_double_format = @@ -2998,7 +3075,6 @@ const struct real_format mips_double_format = encode_ieee_double, decode_ieee_double, 2, - 1, 53, 53, -1021, @@ -3009,9 +3085,28 @@ const struct real_format mips_double_format = true, true, true, - false + false, + true }; +const struct real_format motorola_double_format = + { + encode_ieee_double, + decode_ieee_double, + 2, + 53, + 53, + -1021, + 1024, + 63, + 63, + true, + true, + true, + true, + true, + true + }; /* IEEE extended real format. This comes in three flavors: Intel's as a 12 byte image, Intel's as a 16 byte image, and Motorola's. Intel @@ -3057,7 +3152,15 @@ encode_ieee_extended (const struct real_format *fmt, long *buf, if (fmt->has_nans) { image_hi |= 32767; - if (HOST_BITS_PER_LONG == 32) + if (r->canonical) + { + if (fmt->canonical_nan_lsbs_set) + { + sig_hi = (1 << 30) - 1; + sig_lo = 0xffffffff; + } + } + else if (HOST_BITS_PER_LONG == 32) { sig_hi = r->sig[SIGSZ-1]; sig_lo = r->sig[SIGSZ-2]; @@ -3328,7 +3431,6 @@ const struct real_format ieee_extended_motorola_format = encode_ieee_extended_motorola, decode_ieee_extended_motorola, 2, - 1, 64, 64, -16382, @@ -3339,6 +3441,7 @@ const struct real_format ieee_extended_motorola_format = true, true, true, + true, true }; @@ -3347,7 +3450,6 @@ const struct real_format ieee_extended_intel_96_format = encode_ieee_extended_intel_96, decode_ieee_extended_intel_96, 2, - 1, 64, 64, -16381, @@ -3358,7 +3460,8 @@ const struct real_format ieee_extended_intel_96_format = true, true, true, - true + true, + false }; const struct real_format ieee_extended_intel_128_format = @@ -3366,7 +3469,6 @@ const struct real_format ieee_extended_intel_128_format = encode_ieee_extended_intel_128, decode_ieee_extended_intel_128, 2, - 1, 64, 64, -16381, @@ -3377,7 +3479,8 @@ const struct real_format ieee_extended_intel_128_format = true, true, true, - true + true, + false }; /* The following caters to i386 systems that set the rounding precision @@ -3387,7 +3490,6 @@ const struct real_format ieee_extended_intel_96_round_53_format = encode_ieee_extended_intel_96, decode_ieee_extended_intel_96, 2, - 1, 53, 53, -16381, @@ -3398,7 +3500,8 @@ const struct real_format ieee_extended_intel_96_round_53_format = true, true, true, - true + true, + false }; /* IBM 128-bit extended precision format: a pair of IEEE double precision @@ -3423,7 +3526,7 @@ encode_ibm_extended (const struct real_format *fmt, long *buf, base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; - /* Renormlize R before doing any arithmetic on it. */ + /* Renormalize R before doing any arithmetic on it. */ normr = *r; if (normr.cl == rvc_normal) normalize (&normr); @@ -3473,7 +3576,6 @@ const struct real_format ibm_extended_format = encode_ibm_extended, decode_ibm_extended, 2, - 1, 53 + 53, 53, -1021 + 53, @@ -3484,7 +3586,8 @@ const struct real_format ibm_extended_format = true, true, true, - true + true, + false }; const struct real_format mips_extended_format = @@ -3492,7 +3595,6 @@ const struct real_format mips_extended_format = encode_ibm_extended, decode_ibm_extended, 2, - 1, 53 + 53, 53, -1021 + 53, @@ -3503,7 +3605,8 @@ const struct real_format mips_extended_format = true, true, true, - false + false, + true }; @@ -3553,8 +3656,11 @@ encode_ieee_quad (const struct real_format *fmt, long *buf, if (r->canonical) { - /* Don't use bits from the significand. The - initialization above is right. */ + if (fmt->canonical_nan_lsbs_set) + { + image3 |= 0x7fff; + image2 = image1 = image0 = 0xffffffff; + } } else if (HOST_BITS_PER_LONG == 32) { @@ -3576,16 +3682,7 @@ encode_ieee_quad (const struct real_format *fmt, long *buf, image3 &= ~0x8000; else image3 |= 0x8000; - /* 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) + if (((image3 & 0xffff) | image2 | image1 | image0) == 0) image3 |= 0x4000; } else @@ -3759,7 +3856,6 @@ const struct real_format ieee_quad_format = encode_ieee_quad, decode_ieee_quad, 2, - 1, 113, 113, -16381, @@ -3770,7 +3866,8 @@ const struct real_format ieee_quad_format = true, true, true, - true + true, + false }; const struct real_format mips_quad_format = @@ -3778,7 +3875,6 @@ const struct real_format mips_quad_format = encode_ieee_quad, decode_ieee_quad, 2, - 1, 113, 113, -16381, @@ -3789,7 +3885,8 @@ const struct real_format mips_quad_format = true, true, true, - false + false, + true }; /* Descriptions of VAX floating point formats can be found beginning at @@ -4076,7 +4173,6 @@ const struct real_format vax_f_format = encode_vax_f, decode_vax_f, 2, - 1, 24, 24, -127, @@ -4087,6 +4183,7 @@ const struct real_format vax_f_format = false, false, false, + false, false }; @@ -4095,7 +4192,6 @@ const struct real_format vax_d_format = encode_vax_d, decode_vax_d, 2, - 1, 56, 56, -127, @@ -4106,6 +4202,7 @@ const struct real_format vax_d_format = false, false, false, + false, false }; @@ -4114,7 +4211,6 @@ const struct real_format vax_g_format = encode_vax_g, decode_vax_g, 2, - 1, 53, 53, -1023, @@ -4125,201 +4221,7 @@ const struct real_format vax_g_format = false, false, false, - false - }; - -/* A good reference for these can be found in chapter 9 of - "ESA/390 Principles of Operation", IBM document number SA22-7201-01. - An on-line version can be found here: - - http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR001/9.1?DT=19930923083613 -*/ - -static void encode_i370_single (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_i370_single (const struct real_format *, - REAL_VALUE_TYPE *, const long *); -static void encode_i370_double (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_i370_double (const struct real_format *, - REAL_VALUE_TYPE *, const long *); - -static void -encode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED, - long *buf, const REAL_VALUE_TYPE *r) -{ - unsigned long sign, exp, sig, image; - - sign = r->sign << 31; - - switch (r->cl) - { - case rvc_zero: - image = 0; - break; - - case rvc_inf: - case rvc_nan: - image = 0x7fffffff | sign; - break; - - case rvc_normal: - sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0xffffff; - exp = ((REAL_EXP (r) / 4) + 64) << 24; - image = sign | exp | sig; - break; - - default: - gcc_unreachable (); - } - - buf[0] = image; -} - -static void -decode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED, - REAL_VALUE_TYPE *r, const long *buf) -{ - unsigned long sign, sig, image = buf[0]; - int exp; - - sign = (image >> 31) & 1; - exp = (image >> 24) & 0x7f; - sig = image & 0xffffff; - - memset (r, 0, sizeof (*r)); - - if (exp || sig) - { - r->cl = rvc_normal; - r->sign = sign; - SET_REAL_EXP (r, (exp - 64) * 4); - r->sig[SIGSZ-1] = sig << (HOST_BITS_PER_LONG - 24); - normalize (r); - } -} - -static void -encode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED, - long *buf, const REAL_VALUE_TYPE *r) -{ - unsigned long sign, exp, image_hi, image_lo; - - sign = r->sign << 31; - - switch (r->cl) - { - case rvc_zero: - image_hi = image_lo = 0; - break; - - case rvc_inf: - case rvc_nan: - image_hi = 0x7fffffff | sign; - image_lo = 0xffffffff; - break; - - case rvc_normal: - if (HOST_BITS_PER_LONG == 64) - { - image_hi = r->sig[SIGSZ-1]; - image_lo = (image_hi >> (64 - 56)) & 0xffffffff; - image_hi = (image_hi >> (64 - 56 + 1) >> 31) & 0xffffff; - } - else - { - image_hi = r->sig[SIGSZ-1]; - image_lo = r->sig[SIGSZ-2]; - image_lo = (image_lo >> 8) | (image_hi << 24); - image_hi >>= 8; - } - - exp = ((REAL_EXP (r) / 4) + 64) << 24; - image_hi |= sign | exp; - break; - - default: - gcc_unreachable (); - } - - if (FLOAT_WORDS_BIG_ENDIAN) - buf[0] = image_hi, buf[1] = image_lo; - else - buf[0] = image_lo, buf[1] = image_hi; -} - -static void -decode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED, - REAL_VALUE_TYPE *r, const long *buf) -{ - unsigned long sign, image_hi, image_lo; - int exp; - - if (FLOAT_WORDS_BIG_ENDIAN) - image_hi = buf[0], image_lo = buf[1]; - else - image_lo = buf[0], image_hi = buf[1]; - - sign = (image_hi >> 31) & 1; - exp = (image_hi >> 24) & 0x7f; - image_hi &= 0xffffff; - image_lo &= 0xffffffff; - - memset (r, 0, sizeof (*r)); - - if (exp || image_hi || image_lo) - { - r->cl = rvc_normal; - r->sign = sign; - SET_REAL_EXP (r, (exp - 64) * 4 + (SIGNIFICAND_BITS - 56)); - - if (HOST_BITS_PER_LONG == 32) - { - r->sig[0] = image_lo; - r->sig[1] = image_hi; - } - else - r->sig[0] = image_lo | (image_hi << 31 << 1); - - normalize (r); - } -} - -const struct real_format i370_single_format = - { - encode_i370_single, - decode_i370_single, - 16, - 4, - 6, - 6, - -64, - 63, - 31, - 31, - false, - false, - false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ - false - }; - -const struct real_format i370_double_format = - { - encode_i370_double, - decode_i370_double, - 16, - 4, - 14, - 14, - -64, - 63, - 63, - 63, - false, false, - false, /* ??? The encoding does allow for "unnormals". */ - false, /* ??? The encoding does allow for "unnormals". */ false }; @@ -4383,7 +4285,6 @@ const struct real_format decimal_single_format = encode_decimal_single, decode_decimal_single, 10, - 1, /* log10 */ 7, 7, -95, @@ -4394,7 +4295,8 @@ const struct real_format decimal_single_format = true, true, true, - true + true, + false }; /* Double precision decimal floating point (IEEE 754R). */ @@ -4403,7 +4305,6 @@ const struct real_format decimal_double_format = encode_decimal_double, decode_decimal_double, 10, - 1, /* log10 */ 16, 16, -383, @@ -4414,7 +4315,8 @@ const struct real_format decimal_double_format = true, true, true, - true + true, + false }; /* Quad precision decimal floating point (IEEE 754R). */ @@ -4423,7 +4325,6 @@ const struct real_format decimal_quad_format = encode_decimal_quad, decode_decimal_quad, 10, - 1, /* log10 */ 34, 34, -6143, @@ -4434,237 +4335,9 @@ const struct real_format decimal_quad_format = true, true, true, - true - }; - -/* The "twos-complement" c4x format is officially defined as - - x = s(~s).f * 2**e - - This is rather misleading. One must remember that F is signed. - A better description would be - - x = -1**s * ((s + 1 + .f) * 2**e - - So if we have a (4 bit) fraction of .1000 with a sign bit of 1, - that's -1 * (1+1+(-.5)) == -1.5. I think. - - The constructions here are taken from Tables 5-1 and 5-2 of the - TMS320C4x User's Guide wherein step-by-step instructions for - conversion from IEEE are presented. That's close enough to our - internal representation so as to make things easy. - - See http://www-s.ti.com/sc/psheets/spru063c/spru063c.pdf */ - -static void encode_c4x_single (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_c4x_single (const struct real_format *, - REAL_VALUE_TYPE *, const long *); -static void encode_c4x_extended (const struct real_format *fmt, - long *, const REAL_VALUE_TYPE *); -static void decode_c4x_extended (const struct real_format *, - REAL_VALUE_TYPE *, const long *); - -static void -encode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED, - long *buf, const REAL_VALUE_TYPE *r) -{ - unsigned long image, exp, sig; - - switch (r->cl) - { - case rvc_zero: - exp = -128; - sig = 0; - break; - - case rvc_inf: - case rvc_nan: - exp = 127; - sig = 0x800000 - r->sign; - break; - - case rvc_normal: - exp = REAL_EXP (r) - 1; - sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff; - if (r->sign) - { - if (sig) - sig = -sig; - else - exp--; - sig |= 0x800000; - } - break; - - default: - gcc_unreachable (); - } - - image = ((exp & 0xff) << 24) | (sig & 0xffffff); - buf[0] = image; -} - -static void -decode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED, - REAL_VALUE_TYPE *r, const long *buf) -{ - unsigned long image = buf[0]; - unsigned long sig; - int exp, sf; - - exp = (((image >> 24) & 0xff) ^ 0x80) - 0x80; - sf = ((image & 0xffffff) ^ 0x800000) - 0x800000; - - memset (r, 0, sizeof (*r)); - - if (exp != -128) - { - r->cl = rvc_normal; - - sig = sf & 0x7fffff; - if (sf < 0) - { - r->sign = 1; - if (sig) - sig = -sig; - else - exp++; - } - sig = (sig << (HOST_BITS_PER_LONG - 24)) | SIG_MSB; - - SET_REAL_EXP (r, exp + 1); - r->sig[SIGSZ-1] = sig; - } -} - -static void -encode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, - long *buf, const REAL_VALUE_TYPE *r) -{ - unsigned long exp, sig; - - switch (r->cl) - { - case rvc_zero: - exp = -128; - sig = 0; - break; - - case rvc_inf: - case rvc_nan: - exp = 127; - sig = 0x80000000 - r->sign; - break; - - case rvc_normal: - exp = REAL_EXP (r) - 1; - - sig = r->sig[SIGSZ-1]; - if (HOST_BITS_PER_LONG == 64) - sig = sig >> 1 >> 31; - sig &= 0x7fffffff; - - if (r->sign) - { - if (sig) - sig = -sig; - else - exp--; - sig |= 0x80000000; - } - break; - - default: - gcc_unreachable (); - } - - exp = (exp & 0xff) << 24; - sig &= 0xffffffff; - - if (FLOAT_WORDS_BIG_ENDIAN) - buf[0] = exp, buf[1] = sig; - else - buf[0] = sig, buf[0] = exp; -} - -static void -decode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, - REAL_VALUE_TYPE *r, const long *buf) -{ - unsigned long sig; - int exp, sf; - - if (FLOAT_WORDS_BIG_ENDIAN) - exp = buf[0], sf = buf[1]; - else - sf = buf[0], exp = buf[1]; - - exp = (((exp >> 24) & 0xff) & 0x80) - 0x80; - sf = ((sf & 0xffffffff) ^ 0x80000000) - 0x80000000; - - memset (r, 0, sizeof (*r)); - - if (exp != -128) - { - r->cl = rvc_normal; - - sig = sf & 0x7fffffff; - if (sf < 0) - { - r->sign = 1; - if (sig) - sig = -sig; - else - exp++; - } - if (HOST_BITS_PER_LONG == 64) - sig = sig << 1 << 31; - sig |= SIG_MSB; - - SET_REAL_EXP (r, exp + 1); - r->sig[SIGSZ-1] = sig; - } -} - -const struct real_format c4x_single_format = - { - encode_c4x_single, - decode_c4x_single, - 2, - 1, - 24, - 24, - -126, - 128, - 23, - -1, - false, - false, - false, - false, - false - }; - -const struct real_format c4x_extended_format = - { - encode_c4x_extended, - decode_c4x_extended, - 2, - 1, - 32, - 32, - -126, - 128, - 31, - -1, - false, - false, - false, - false, + true, false }; - /* A synthetic "format" for internal arithmetic. It's the size of the internal significand minus the two bits needed for proper rounding. @@ -4695,7 +4368,6 @@ const struct real_format real_internal_format = encode_internal, decode_internal, 2, - 1, SIGNIFICAND_BITS - 2, SIGNIFICAND_BITS - 2, -MAX_EXP, @@ -4706,7 +4378,8 @@ const struct real_format real_internal_format = true, false, true, - true + true, + false }; /* Calculate the square root of X in mode MODE, and store the result @@ -4739,7 +4412,7 @@ real_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode, } /* Infinity and NaN return themselves. */ - if (real_isinf (x) || real_isnan (x)) + if (!real_isfinite (x)) { *r = *x; return false; @@ -4909,3 +4582,121 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x) r->sign = x->sign; } +/* Convert from REAL_VALUE_TYPE to MPFR. The caller is responsible + for initializing and clearing the MPFR parameter. */ + +void +mpfr_from_real (mpfr_ptr m, const REAL_VALUE_TYPE *r, mp_rnd_t rndmode) +{ + /* We use a string as an intermediate type. */ + char buf[128]; + int ret; + + /* Take care of Infinity and NaN. */ + if (r->cl == rvc_inf) + { + mpfr_set_inf (m, r->sign == 1 ? -1 : 1); + return; + } + + if (r->cl == rvc_nan) + { + mpfr_set_nan (m); + return; + } + + real_to_hexadecimal (buf, r, sizeof (buf), 0, 1); + /* mpfr_set_str() parses hexadecimal floats from strings in the same + format that GCC will output them. Nothing extra is needed. */ + ret = mpfr_set_str (m, buf, 16, rndmode); + gcc_assert (ret == 0); +} + +/* Convert from MPFR to REAL_VALUE_TYPE, for a given type TYPE and rounding + mode RNDMODE. TYPE is only relevant if M is a NaN. */ + +void +real_from_mpfr (REAL_VALUE_TYPE *r, mpfr_srcptr m, tree type, mp_rnd_t rndmode) +{ + /* We use a string as an intermediate type. */ + char buf[128], *rstr; + mp_exp_t exp; + + /* Take care of Infinity and NaN. */ + if (mpfr_inf_p (m)) + { + real_inf (r); + if (mpfr_sgn (m) < 0) + *r = REAL_VALUE_NEGATE (*r); + return; + } + + if (mpfr_nan_p (m)) + { + real_nan (r, "", 1, TYPE_MODE (type)); + return; + } + + rstr = mpfr_get_str (NULL, &exp, 16, 0, m, rndmode); + + /* The additional 12 chars add space for the sprintf below. This + leaves 6 digits for the exponent which is supposedly enough. */ + gcc_assert (rstr != NULL && strlen (rstr) < sizeof (buf) - 12); + + /* REAL_VALUE_ATOF expects the exponent for mantissa * 2**exp, + mpfr_get_str returns the exponent for mantissa * 16**exp, adjust + for that. */ + exp *= 4; + + if (rstr[0] == '-') + sprintf (buf, "-0x.%sp%d", &rstr[1], (int) exp); + else + sprintf (buf, "0x.%sp%d", rstr, (int) exp); + + mpfr_free_str (rstr); + + real_from_string (r, buf); +} + +/* Check whether the real constant value given is an integer. */ + +bool +real_isinteger (const REAL_VALUE_TYPE *c, enum machine_mode mode) +{ + REAL_VALUE_TYPE cint; + + real_trunc (&cint, mode, c); + return real_identical (c, &cint); +} + +/* Write into BUF the maximum representable finite floating-point + number, (1 - b**-p) * b**emax for a given FP format FMT as a hex + float string. LEN is the size of BUF, and the buffer must be large + enough to contain the resulting string. */ + +void +get_max_float (const struct real_format *fmt, char *buf, size_t len) +{ + int i, n; + char *p; + + strcpy (buf, "0x0."); + n = fmt->p; + for (i = 0, p = buf + 4; i + 3 < n; i += 4) + *p++ = 'f'; + if (i < n) + *p++ = "08ce"[n - i]; + sprintf (p, "p%d", fmt->emax); + if (fmt->pnan < fmt->p) + { + /* This is an IBM extended double format 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. Rounding means we need a slightly smaller + value for LDBL_MAX. */ + buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4]; + } + + gcc_assert (strlen (buf) < len); +}