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
2 changed files with 63 additions and 30 deletions
|
@ -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>
|
||||
|
||||
* config/c4x/c4x.c (TARGET_ASM_EXTERNAL_LIBCALL): New.
|
||||
|
|
|
@ -330,58 +330,76 @@ pack_d ( fp_number_type * src)
|
|||
#else
|
||||
# if defined TFLOAT && defined HALFFRACBITS
|
||||
{
|
||||
halffractype high, low;
|
||||
halffractype high, low, unity;
|
||||
int lowsign, lowexp;
|
||||
|
||||
high = (fraction >> (FRACBITS - HALFFRACBITS));
|
||||
high &= (((fractype)1) << HALFFRACBITS) - 1;
|
||||
high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
|
||||
high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
|
||||
unity = (halffractype) 1 << HALFFRACBITS;
|
||||
|
||||
low = (halffractype)fraction &
|
||||
((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1);
|
||||
/* Set HIGH to the high double's significand, masking out the implicit 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)
|
||||
low = 0;
|
||||
else
|
||||
{
|
||||
exp -= HALFFRACBITS + 1;
|
||||
|
||||
while (exp > 0
|
||||
&& low < ((halffractype)1 << HALFFRACBITS))
|
||||
while (lowexp > 0 && low < unity)
|
||||
{
|
||||
low <<= 1;
|
||||
exp--;
|
||||
lowexp--;
|
||||
}
|
||||
|
||||
if (exp <= 0)
|
||||
if (lowexp <= 0)
|
||||
{
|
||||
halffractype roundmsb, round;
|
||||
int shift;
|
||||
|
||||
exp = -exp + 1;
|
||||
|
||||
roundmsb = (1 << (exp - 1));
|
||||
shift = 1 - lowexp;
|
||||
roundmsb = (1 << (shift - 1));
|
||||
round = low & ((roundmsb << 1) - 1);
|
||||
|
||||
low >>= exp;
|
||||
exp = 0;
|
||||
low >>= shift;
|
||||
lowexp = 0;
|
||||
|
||||
if (round > roundmsb || (round == roundmsb && (low & 1)))
|
||||
if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
|
||||
{
|
||||
low++;
|
||||
if (low >= ((halffractype)1 << HALFFRACBITS))
|
||||
/* We don't shift left, since it has just become the
|
||||
smallest normal number, whose implicit 1 bit is
|
||||
now indicated by the nonzero exponent. */
|
||||
exp++;
|
||||
if (low == unity)
|
||||
/* LOW rounds up to the smallest normal number. */
|
||||
lowexp++;
|
||||
}
|
||||
}
|
||||
|
||||
low &= ((halffractype)1 << HALFFRACBITS) - 1;
|
||||
low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
|
||||
low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
|
||||
low &= unity - 1;
|
||||
low |= (halffractype) lowexp << HALFFRACBITS;
|
||||
low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
|
||||
}
|
||||
|
||||
dst.value_raw = (((fractype) high) << HALFSHIFT) | low;
|
||||
dst.value_raw = ((fractype) high << HALFSHIFT) | low;
|
||||
}
|
||||
# else
|
||||
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;
|
||||
if (sign == lowsign)
|
||||
fraction += xlow;
|
||||
else
|
||||
else if (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
|
||||
|
|
Loading…
Add table
Reference in a new issue