fp-bit.c (pack_d): When using paired doubles to implement a long double...
* config/fp-bit.c (pack_d): When using paired doubles to implement a long double, round the high part separately. (unpack_d): Fix the case in which the high part is a power of two and the low part is a nonzero value of the opposite sign. From-SVN: r76780
This commit is contained in:
parent
28b241764f
commit
faceece35d
|
@ -1,3 +1,10 @@
|
||||||
|
2004-01-28 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
|
* config/fp-bit.c (pack_d): When using paired doubles to implement
|
||||||
|
a long double, round the high part separately.
|
||||||
|
(unpack_d): Fix the case in which the high part is a power of two
|
||||||
|
and the low part is a nonzero value of the opposite sign.
|
||||||
|
|
||||||
2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
|
2004-01-28 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* config/c4x/c4x.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
|
* config/c4x/c4x.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
|
||||||
|
|
|
@ -330,58 +330,76 @@ pack_d ( fp_number_type * src)
|
||||||
#else
|
#else
|
||||||
# if defined TFLOAT && defined HALFFRACBITS
|
# if defined TFLOAT && defined HALFFRACBITS
|
||||||
{
|
{
|
||||||
halffractype high, low;
|
halffractype high, low, unity;
|
||||||
|
int lowsign, lowexp;
|
||||||
|
|
||||||
high = (fraction >> (FRACBITS - HALFFRACBITS));
|
unity = (halffractype) 1 << HALFFRACBITS;
|
||||||
high &= (((fractype)1) << HALFFRACBITS) - 1;
|
|
||||||
high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
|
|
||||||
high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
|
|
||||||
|
|
||||||
low = (halffractype)fraction &
|
/* Set HIGH to the high double's significand, masking out the implicit 1.
|
||||||
((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1);
|
Set LOW to the low double's full significand. */
|
||||||
|
high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
|
||||||
|
low = fraction & (unity * 2 - 1);
|
||||||
|
|
||||||
|
/* Get the initial sign and exponent of the low double. */
|
||||||
|
lowexp = exp - HALFFRACBITS - 1;
|
||||||
|
lowsign = sign;
|
||||||
|
|
||||||
|
/* HIGH should be rounded like a normal double, making |LOW| <=
|
||||||
|
0.5 ULP of HIGH. Assume round-to-nearest. */
|
||||||
|
if (exp < EXPMAX)
|
||||||
|
if (low > unity || (low == unity && (high & 1) == 1))
|
||||||
|
{
|
||||||
|
/* Round HIGH up and adjust LOW to match. */
|
||||||
|
high++;
|
||||||
|
if (high == unity)
|
||||||
|
{
|
||||||
|
/* May make it infinite, but that's OK. */
|
||||||
|
high = 0;
|
||||||
|
exp++;
|
||||||
|
}
|
||||||
|
low = unity * 2 - low;
|
||||||
|
lowsign ^= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
high |= (halffractype) exp << HALFFRACBITS;
|
||||||
|
high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
|
||||||
|
|
||||||
if (exp == EXPMAX || exp == 0 || low == 0)
|
if (exp == EXPMAX || exp == 0 || low == 0)
|
||||||
low = 0;
|
low = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exp -= HALFFRACBITS + 1;
|
while (lowexp > 0 && low < unity)
|
||||||
|
|
||||||
while (exp > 0
|
|
||||||
&& low < ((halffractype)1 << HALFFRACBITS))
|
|
||||||
{
|
{
|
||||||
low <<= 1;
|
low <<= 1;
|
||||||
exp--;
|
lowexp--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exp <= 0)
|
if (lowexp <= 0)
|
||||||
{
|
{
|
||||||
halffractype roundmsb, round;
|
halffractype roundmsb, round;
|
||||||
|
int shift;
|
||||||
|
|
||||||
exp = -exp + 1;
|
shift = 1 - lowexp;
|
||||||
|
roundmsb = (1 << (shift - 1));
|
||||||
roundmsb = (1 << (exp - 1));
|
|
||||||
round = low & ((roundmsb << 1) - 1);
|
round = low & ((roundmsb << 1) - 1);
|
||||||
|
|
||||||
low >>= exp;
|
low >>= shift;
|
||||||
exp = 0;
|
lowexp = 0;
|
||||||
|
|
||||||
if (round > roundmsb || (round == roundmsb && (low & 1)))
|
if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
|
||||||
{
|
{
|
||||||
low++;
|
low++;
|
||||||
if (low >= ((halffractype)1 << HALFFRACBITS))
|
if (low == unity)
|
||||||
/* We don't shift left, since it has just become the
|
/* LOW rounds up to the smallest normal number. */
|
||||||
smallest normal number, whose implicit 1 bit is
|
lowexp++;
|
||||||
now indicated by the nonzero exponent. */
|
|
||||||
exp++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
low &= ((halffractype)1 << HALFFRACBITS) - 1;
|
low &= unity - 1;
|
||||||
low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
|
low |= (halffractype) lowexp << HALFFRACBITS;
|
||||||
low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
|
low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
|
||||||
}
|
}
|
||||||
|
dst.value_raw = ((fractype) high << HALFSHIFT) | low;
|
||||||
dst.value_raw = (((fractype) high) << HALFSHIFT) | low;
|
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
|
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
|
||||||
|
@ -475,8 +493,16 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
|
||||||
xlow >>= -shift;
|
xlow >>= -shift;
|
||||||
if (sign == lowsign)
|
if (sign == lowsign)
|
||||||
fraction += xlow;
|
fraction += xlow;
|
||||||
else
|
else if (fraction >= xlow)
|
||||||
fraction -= xlow;
|
fraction -= xlow;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The high part is a power of two but the full number is lower.
|
||||||
|
This code will leave the implicit 1 in FRACTION, but we'd
|
||||||
|
have added that below anyway. */
|
||||||
|
fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
|
||||||
|
exp--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
|
|
Loading…
Reference in New Issue