aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-05-05 07:10:06 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-05-05 07:10:06 -0400
commitd730ef29fb00a6e572db89aa4fb0e01045e5a447 (patch)
tree515a03b65dede77cb549d813d99f32f274c9db9b /gcc
parent0e8c9172226c75708e4e240ad27d11e4b31bbfc5 (diff)
downloadgcc-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.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/real.c b/gcc/real.c
index 29deee33..6c21b94 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -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;