diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2007-01-18 19:49:59 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-01-18 19:49:59 +0000 |
commit | e444d54e44e4ac836ee2f78dd5bddf75a1c2b95f (patch) | |
tree | dd09592ee23041e2582c2bbdf6b2f384cb0efdc5 /gcc | |
parent | 17e143a1730125d9630c8fb1b0ec9a334330a1c0 (diff) | |
download | gcc-e444d54e44e4ac836ee2f78dd5bddf75a1c2b95f.zip gcc-e444d54e44e4ac836ee2f78dd5bddf75a1c2b95f.tar.gz gcc-e444d54e44e4ac836ee2f78dd5bddf75a1c2b95f.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/m68k/fpgnulib.c | 40 |
2 files changed, 34 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4f4801b..4d95624 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> * 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 cbff918..2a7f6c7 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; |