diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-05-05 07:10:06 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-05-05 07:10:06 -0400 |
commit | d730ef29fb00a6e572db89aa4fb0e01045e5a447 (patch) | |
tree | 515a03b65dede77cb549d813d99f32f274c9db9b /gcc | |
parent | 0e8c9172226c75708e4e240ad27d11e4b31bbfc5 (diff) | |
download | gcc-d730ef29fb00a6e572db89aa4fb0e01045e5a447.zip gcc-d730ef29fb00a6e572db89aa4fb0e01045e5a447.tar.gz gcc-d730ef29fb00a6e572db89aa4fb0e01045e5a447.tar.bz2 |
(emdnorm, toe64, etoe64): Significand of Intel long double denormals
is shifted down one bit.
From-SVN: r9578
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/real.c | 26 |
1 files changed, 23 insertions, 3 deletions
@@ -2367,8 +2367,10 @@ emdnorm (s, lost, subflg, exp, rcntrl) } /* Shift down 1 temporarily if the data structure has an implied - most significant bit and the number is denormal. */ - if ((exp <= 0) && (rndprc != 64) && (rndprc != NBITS)) + most significant bit and the number is denormal. + Intel long double denormals also lose one bit of precision. */ + if ((exp <= 0) && (rndprc != NBITS) + && ((rndprc != 64) || ((rndprc == 64) && ! REAL_WORDS_BIG_ENDIAN))) { lost |= s[NI - 1] & 1; eshdn1 (s); @@ -2406,7 +2408,9 @@ emdnorm (s, lost, subflg, exp, rcntrl) eaddm (rbit, s); } mddone: - if ((exp <= 0) && (rndprc != 64) && (rndprc != NBITS)) +/* Undo the temporary shift for denormal values. */ + if ((exp <= 0) && (rndprc != NBITS) + && ((rndprc != 64) || ((rndprc == 64) && ! REAL_WORDS_BIG_ENDIAN))) { eshup1 (s); } @@ -2948,6 +2952,19 @@ e64toe (pe, y) { for (i = 0; i < 5; i++) *p++ = *e++; + + /* For denormal long double Intel format, shift significand up one + -- but only if the top significand bit is zero. A top bit of 1 + is "pseudodenormal" when the exponent is zero. */ + if((yy[NE-1] & 0x7fff) == 0 && (yy[NE-2] & 0x8000) == 0) + { + unsigned EMUSHORT temp[NI]; + + emovi(yy, temp); + eshup1(temp); + emovo(temp,y); + return; + } } else { @@ -3323,6 +3340,9 @@ toe64 (a, b) return; } #endif + /* Shift denormal long double Intel format significand down one bit. */ + if ((a[E] == 0) && ! REAL_WORDS_BIG_ENDIAN) + eshdn1 (a); p = a; #ifdef IBM q = b; |