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
This commit is contained in:
parent
975421be9e
commit
f01519dd00
3 changed files with 47 additions and 88 deletions
|
@ -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>
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
60
gcc/real.c
60
gcc/real.c
|
@ -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)
|
||||
/* u = IEEE double precision portion of significand. */
|
||||
u = *r;
|
||||
round_for_format (base_fmt, &u);
|
||||
encode_ieee_double (base_fmt, &buf[0], &u);
|
||||
|
||||
if (r->class == rvc_normal)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue