diff options
author | Geoffrey Keating <geoffk@apple.com> | 2004-01-10 05:47:14 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2004-01-10 05:47:14 +0000 |
commit | f01519dd00355e65f34b40acc82457dcdeedf3d6 (patch) | |
tree | d30bf7e4c2a8d092733cec701722dc75f1fb8112 /gcc | |
parent | 975421be9e4f094f3958c264cc7f793221d90d39 (diff) | |
download | gcc-f01519dd00355e65f34b40acc82457dcdeedf3d6.zip gcc-f01519dd00355e65f34b40acc82457dcdeedf3d6.tar.gz gcc-f01519dd00355e65f34b40acc82457dcdeedf3d6.tar.bz2 |
darwin-ldouble.c: Add big comment explaining exactly what is expected as a 'long double'.
* 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.
From-SVN: r75629
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/darwin-ldouble.c | 66 | ||||
-rw-r--r-- | gcc/real.c | 60 |
3 files changed, 47 insertions, 88 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ae5c9d..367a26a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> diff --git a/gcc/config/rs6000/darwin-ldouble.c b/gcc/config/rs6000/darwin-ldouble.c index 281eb2a..c73b24f 100644 --- a/gcc/config/rs6000/darwin-ldouble.c +++ b/gcc/config/rs6000/darwin-ldouble.c @@ -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. */ @@ -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; } } |