From e444d54e44e4ac836ee2f78dd5bddf75a1c2b95f Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 18 Jan 2007 19:49:59 +0000 Subject: [PATCH] 200x-xx-xx Nathan Sidwell gcc/ 200x-xx-xx Nathan Sidwell * config/m68k/fpgnulib.c (__truncdfsf2): Implement round to nearest even, fix denormal rounding overflow. From-SVN: r120925 --- gcc/ChangeLog | 5 +++++ gcc/config/m68k/fpgnulib.c | 40 +++++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f4801b7826..4d95624c9b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-01-18 Nathan Sidwell + + * config/m68k/fpgnulib.c (__truncdfsf2): Implement round to + nearest even, fix denormal rounding overflow. + 2007-01-18 Richard Sandiford * config/m68k/m68k.md (movsf_cf_hard): Use fsmove instead of diff --git a/gcc/config/m68k/fpgnulib.c b/gcc/config/m68k/fpgnulib.c index cbff9184abf..2a7f6c75d11 100644 --- a/gcc/config/m68k/fpgnulib.c +++ b/gcc/config/m68k/fpgnulib.c @@ -277,6 +277,8 @@ __truncdfsf2 (double a1) register long mant; register union float_long fl; register union double_long dl1; + int sticky; + int shift; dl1.d = a1; @@ -288,29 +290,45 @@ __truncdfsf2 (double a1) exp = EXPD (dl1) - EXCESSD + EXCESS; + sticky = dl1.l.lower & ((1 << 22) - 1); + mant = MANTD (dl1); /* 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. */ if (exp <= 0) { if (exp < -24) - mant = 0; + { + sticky |= mant; + mant = 0; + } else - mant >>= 1 - exp; + { + sticky |= mant & ((1 << (1 - exp)) - 1); + mant >>= 1 - exp; + } exp = 0; } - /* now round and shift down */ - mant += 1; - mant >>= 1; - - /* did the round overflow? */ - if (mant & 0xFF000000L) + /* now round */ + shift = 1; + if ((mant & 1) && (sticky || (mant & 2))) { - mant >>= 1; - exp++; + int rounding = exp ? 2 : 1; + + mant += 1; + + /* did the round overflow? */ + if (mant >= (HIDDEN << rounding)) + { + exp++; + shift = rounding; + } } + /* shift down */ + mant >>= shift; mant &= ~HIDDEN;