200x-xx-xx Nathan Sidwell <nathan@codesourcery.com>

gcc/
200x-xx-xx  Nathan Sidwell  <nathan@codesourcery.com>

	* config/m68k/fpgnulib.c (__truncdfsf2): Implement round to
	nearest even, fix denormal rounding overflow.

From-SVN: r120925
This commit is contained in:
Nathan Sidwell 2007-01-18 19:49:59 +00:00 committed by Richard Sandiford
parent 17e143a173
commit e444d54e44
2 changed files with 34 additions and 11 deletions

View File

@ -1,3 +1,8 @@
2007-01-18 Nathan Sidwell <nathan@codesourcery.com>
* config/m68k/fpgnulib.c (__truncdfsf2): Implement round to
nearest even, fix denormal rounding overflow.
2007-01-18 Richard Sandiford <richard@codesourcery.com> 2007-01-18 Richard Sandiford <richard@codesourcery.com>
* config/m68k/m68k.md (movsf_cf_hard): Use fsmove instead of * config/m68k/m68k.md (movsf_cf_hard): Use fsmove instead of

View File

@ -277,6 +277,8 @@ __truncdfsf2 (double a1)
register long mant; register long mant;
register union float_long fl; register union float_long fl;
register union double_long dl1; register union double_long dl1;
int sticky;
int shift;
dl1.d = a1; dl1.d = a1;
@ -288,29 +290,45 @@ __truncdfsf2 (double a1)
exp = EXPD (dl1) - EXCESSD + EXCESS; exp = EXPD (dl1) - EXCESSD + EXCESS;
sticky = dl1.l.lower & ((1 << 22) - 1);
mant = MANTD (dl1);
/* shift double mantissa 6 bits so we can round */ /* shift double mantissa 6 bits so we can round */
mant = MANTD (dl1) >> 6; sticky |= mant & ((1 << 6) - 1);
mant >>= 6;
/* Check for underflow and denormals. */ /* Check for underflow and denormals. */
if (exp <= 0) if (exp <= 0)
{ {
if (exp < -24) if (exp < -24)
mant = 0; {
sticky |= mant;
mant = 0;
}
else else
mant >>= 1 - exp; {
sticky |= mant & ((1 << (1 - exp)) - 1);
mant >>= 1 - exp;
}
exp = 0; exp = 0;
} }
/* now round and shift down */ /* now round */
mant += 1; shift = 1;
mant >>= 1; if ((mant & 1) && (sticky || (mant & 2)))
/* did the round overflow? */
if (mant & 0xFF000000L)
{ {
mant >>= 1; int rounding = exp ? 2 : 1;
exp++;
mant += 1;
/* did the round overflow? */
if (mant >= (HIDDEN << rounding))
{
exp++;
shift = rounding;
}
} }
/* shift down */
mant >>= shift;
mant &= ~HIDDEN; mant &= ~HIDDEN;