Commit 45e574d0 by John David Anglin

real.c (REAL_WORDS_BIG_ENDIAN): Make 1 for DEC.

	* real.c (REAL_WORDS_BIG_ENDIAN): Make 1 for DEC.
	(LARGEST_EXPONENT_IS_NORMAL): Ditto.
	(VAX_HALFWORD_ORDER): Define (1 for DEC VAX, 0 otherwise).
	(TARGET_G_FLOAT): Default to 0 if not defined.
	(ieeetoe): New, common routine to convert target format floats
	to internal form.
	(e24toe, e53toe): Change to use ieeetoe, distinguish DEC
	vs. others.
	(e113toe): Change to use ieeetoe.
	(REAL_WORDS_BIG_ENDIAN): Make sure it is 0 for DEC and 1 for
	IBM.
	(e53toe): Assume IEEE if non of DEC, IBM and C4X is defined.
	(e64toe): Remove special cases for DEC and IBM. Remove support for
	ARM_EXTENDED_IEEE_FORMAT.
	(e24toe): Remove special cases for DEC.
	(significand_size): Simplify. Indent.
	(ieee_format, ieee_24, ieee_53, ieee_64, ieee_113): New.
	(etoieee, toieee): New.
	(etoe113, toe113, etoe64, toe64, etoe53, toe53, etoe24, toe24): Use
	etoieee and toieee for IEEE arithmetic.

From-SVN: r55683
parent b5dec7da
2002-07-23 Paul Koning <pkoning@equallogic.com>
* real.c (REAL_WORDS_BIG_ENDIAN): Make 1 for DEC.
(LARGEST_EXPONENT_IS_NORMAL): Ditto.
(VAX_HALFWORD_ORDER): Define (1 for DEC VAX, 0 otherwise).
(TARGET_G_FLOAT): Default to 0 if not defined.
(ieeetoe): New, common routine to convert target format floats
to internal form.
(e24toe, e53toe): Change to use ieeetoe, distinguish DEC
vs. others.
(e113toe): Change to use ieeetoe.
2002-07-23 Roman Lechtchinsky <rl@cs.tu-berlin.de>
* real.c (REAL_WORDS_BIG_ENDIAN): Make sure it is 0 for DEC and 1 for
IBM.
(e53toe): Assume IEEE if non of DEC, IBM and C4X is defined.
(e64toe): Remove special cases for DEC and IBM. Remove support for
ARM_EXTENDED_IEEE_FORMAT.
(e24toe): Remove special cases for DEC.
(significand_size): Simplify. Indent.
(ieee_format, ieee_24, ieee_53, ieee_64, ieee_113): New.
(etoieee, toieee): New.
(etoe113, toe113, etoe64, toe64, etoe53, toe53, etoe24, toe24): Use
etoieee and toieee for IEEE arithmetic.
2002-07-23 Gabriel Dos Reis <gdr@nerim.net> 2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
* doc/extend.texi: Say ISO C90, not ISO C89. * doc/extend.texi: Say ISO C90, not ISO C89.
......
...@@ -129,6 +129,31 @@ unknown arithmetic type ...@@ -129,6 +129,31 @@ unknown arithmetic type
#define REAL_WORDS_BIG_ENDIAN FLOAT_WORDS_BIG_ENDIAN #define REAL_WORDS_BIG_ENDIAN FLOAT_WORDS_BIG_ENDIAN
/* Make sure that the endianness is correct for IBM and DEC. */
#if defined(DEC)
#undef LARGEST_EXPONENT_IS_NORMAL
#define LARGEST_EXPONENT_IS_NORMAL(x) 1
#undef REAL_WORDS_BIG_ENDIAN
/* Strangely enough, DEC float most closely resembles big endian IEEE */
#define REAL_WORDS_BIG_ENDIAN 1
/* ... but the halfwords are reversed from IEEE big endian. */
#ifndef VAX_HALFWORD_ORDER
#define VAX_HALFWORD_ORDER 1
#endif
#else
#if defined(IBM) && !REAL_WORDS_BIG_ENDIAN
#error "Little-endian representations are not supported for IBM."
#endif
#endif
#if defined(DEC) && !defined (TARGET_G_FLOAT)
#define TARGET_G_FLOAT 0
#endif
#ifndef VAX_HALFWORD_ORDER
#define VAX_HALFWORD_ORDER 0
#endif
/* Define INFINITY for support of infinity. /* Define INFINITY for support of infinity.
Define NANS for support of Not-a-Number's (NaN's). */ Define NANS for support of Not-a-Number's (NaN's). */
#if !defined(DEC) && !defined(IBM) && !defined(C4X) #if !defined(DEC) && !defined(IBM) && !defined(C4X)
...@@ -276,6 +301,106 @@ struct compile_test_dummy { ...@@ -276,6 +301,106 @@ struct compile_test_dummy {
#define CHARMASK 0x7f #define CHARMASK 0x7f
#endif #endif
/* Information about the various IEEE precisions. At the moment, we only
support exponents of 15 bits or less. */
struct ieee_format
{
/* Precision. */
int precision;
/* Size of the exponent in bits. */
int expbits;
/* Overall size of the value in bits. */
int bits;
/* Mode used for representing the value. */
enum machine_mode mode;
/* Exponent adjustment for offsets. */
EMULONG adjustment;
};
/* IEEE float (24 bits). */
static const struct ieee_format ieee_24 =
{
24,
8,
32,
SFmode,
EXONE - 0x7f
};
/* IEEE double (53 bits). */
static const struct ieee_format ieee_53 =
{
53,
11,
64,
DFmode,
EXONE - 0x3ff
};
/* IEEE extended double (64 bits). */
static const struct ieee_format ieee_64 =
{
64,
15,
80,
XFmode,
0
};
/* IEEE long double (113 bits). */
static const struct ieee_format ieee_113 =
{
113,
15,
128,
TFmode,
0
};
/* DEC F float (24 bits). */
static const struct ieee_format dec_f =
{
24,
8,
32,
SFmode,
EXONE - 0201
};
/* DEC D float (56 bits). */
static const struct ieee_format dec_d =
{
56,
8,
64,
DFmode,
EXONE - 0201
};
/* DEC G float (53 bits). */
static const struct ieee_format dec_g =
{
53,
11,
64,
DFmode,
EXONE - 1025
};
/* DEC H float (113 bits). (not yet used) */
static const struct ieee_format dec_h =
{
113,
15,
128,
TFmode,
EXONE - 16385
};
extern int extra_warnings; extern int extra_warnings;
extern const UEMUSHORT ezero[NE], ehalf[NE], eone[NE], etwo[NE]; extern const UEMUSHORT ezero[NE], ehalf[NE], eone[NE], etwo[NE];
extern const UEMUSHORT elog2[NE], esqrt2[NE]; extern const UEMUSHORT elog2[NE], esqrt2[NE];
...@@ -350,6 +475,12 @@ static void etoe53 PARAMS ((const UEMUSHORT *, UEMUSHORT *)); ...@@ -350,6 +475,12 @@ static void etoe53 PARAMS ((const UEMUSHORT *, UEMUSHORT *));
static void toe53 PARAMS ((UEMUSHORT *, UEMUSHORT *)); static void toe53 PARAMS ((UEMUSHORT *, UEMUSHORT *));
static void etoe24 PARAMS ((const UEMUSHORT *, UEMUSHORT *)); static void etoe24 PARAMS ((const UEMUSHORT *, UEMUSHORT *));
static void toe24 PARAMS ((UEMUSHORT *, UEMUSHORT *)); static void toe24 PARAMS ((UEMUSHORT *, UEMUSHORT *));
static void ieeetoe PARAMS ((const UEMUSHORT *, UEMUSHORT *,
const struct ieee_format *));
static void etoieee PARAMS ((const UEMUSHORT *, UEMUSHORT *,
const struct ieee_format *));
static void toieee PARAMS ((UEMUSHORT *, UEMUSHORT *,
const struct ieee_format *));
static int ecmp PARAMS ((const UEMUSHORT *, const UEMUSHORT *)); static int ecmp PARAMS ((const UEMUSHORT *, const UEMUSHORT *));
#if 0 #if 0
static void eround PARAMS ((const UEMUSHORT *, UEMUSHORT *)); static void eround PARAMS ((const UEMUSHORT *, UEMUSHORT *));
...@@ -430,7 +561,7 @@ endian (e, x, mode) ...@@ -430,7 +561,7 @@ endian (e, x, mode)
{ {
unsigned long th, t; unsigned long th, t;
if (REAL_WORDS_BIG_ENDIAN) if (REAL_WORDS_BIG_ENDIAN && !VAX_HALFWORD_ORDER)
{ {
switch (mode) switch (mode)
{ {
...@@ -3072,90 +3203,9 @@ e53toe (pe, y) ...@@ -3072,90 +3203,9 @@ e53toe (pe, y)
c4xtoe (pe, y, HFmode); c4xtoe (pe, y, HFmode);
#else #else
UEMUSHORT r;
const UEMUSHORT *e;
UEMUSHORT *p;
UEMUSHORT yy[NI];
int denorm, k;
e = pe;
denorm = 0; /* flag if denormalized number */
ecleaz (yy);
if (! REAL_WORDS_BIG_ENDIAN)
e += 3;
r = *e;
yy[0] = 0;
if (r & 0x8000)
yy[0] = 0xffff;
yy[M] = (r & 0x0f) | 0x10;
r &= ~0x800f; /* strip sign and 4 significand bits */
#ifdef INFINITY
if (r == 0x7ff0)
{
#ifdef NANS
if (! REAL_WORDS_BIG_ENDIAN)
{
if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
|| (pe[1] != 0) || (pe[0] != 0))
{
enan (y, yy[0] != 0);
return;
}
}
else
{
if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
|| (pe[2] != 0) || (pe[3] != 0))
{
enan (y, yy[0] != 0);
return;
}
}
#endif /* NANS */
eclear (y);
einfin (y);
if (yy[0])
eneg (y);
return;
}
#endif /* INFINITY */
r >>= 4;
/* If zero exponent, then the significand is denormalized.
So take back the understood high significand bit. */
if (r == 0) ieeetoe (pe, y, &ieee_53);
{
denorm = 1;
yy[M] &= ~0x10;
}
r += EXONE - 01777;
yy[E] = r;
p = &yy[M + 1];
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
{
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
}
else
{
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
}
#endif
eshift (yy, -5);
if (denorm)
{
/* If zero exponent, then normalize the significand. */
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
yy[E] -= (UEMUSHORT) (k - 1);
}
emovo (yy, y);
#endif /* not C4X */ #endif /* not C4X */
#endif /* not IBM */ #endif /* not IBM */
#endif /* not DEC */ #endif /* not DEC */
...@@ -3177,24 +3227,15 @@ e64toe (pe, y) ...@@ -3177,24 +3227,15 @@ e64toe (pe, y)
p = yy; p = yy;
for (i = 0; i < NE - 5; i++) for (i = 0; i < NE - 5; i++)
*p++ = 0; *p++ = 0;
/* This precision is not ordinarily supported on DEC or IBM. */ #ifndef C4X
#ifdef DEC /* REAL_WORDS_BIG_ENDIAN is always 0 for DEC and 1 for IBM.
for (i = 0; i < 5; i++) This precision is not ordinarily supported on DEC or IBM. */
*p++ = *e++;
#endif
#ifdef IBM
p = &yy[0] + (NE - 1);
*p-- = *e++;
++e;
for (i = 0; i < 5; i++)
*p-- = *e++;
#endif
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN) if (! REAL_WORDS_BIG_ENDIAN)
{ {
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
*p++ = *e++; *p++ = *e++;
#ifdef IEEE
/* For denormal long double Intel format, shift significand up one /* For denormal long double Intel format, shift significand up one
-- but only if the top significand bit is zero. A top bit of 1 -- but only if the top significand bit is zero. A top bit of 1
is "pseudodenormal" when the exponent is zero. */ is "pseudodenormal" when the exponent is zero. */
...@@ -3207,22 +3248,17 @@ e64toe (pe, y) ...@@ -3207,22 +3248,17 @@ e64toe (pe, y)
emovo (temp,y); emovo (temp,y);
return; return;
} }
#endif /* IEEE */
} }
else else
{ {
p = &yy[0] + (NE - 1); p = &yy[0] + (NE - 1);
#ifdef ARM_EXTENDED_IEEE_FORMAT
/* For ARMs, the exponent is in the lowest 15 bits of the word. */
*p-- = (e[0] & 0x8000) | (e[1] & 0x7ffff);
e += 2;
#else
*p-- = *e++; *p-- = *e++;
++e; ++e;
#endif
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
*p-- = *e++; *p-- = *e++;
} }
#endif #endif /* not C4X */
#ifdef INFINITY #ifdef INFINITY
/* Point to the exponent field and check max exponent cases. */ /* Point to the exponent field and check max exponent cases. */
p = &yy[NE - 1]; p = &yy[NE - 1];
...@@ -3244,16 +3280,6 @@ e64toe (pe, y) ...@@ -3244,16 +3280,6 @@ e64toe (pe, y)
} }
else else
{ {
#ifdef ARM_EXTENDED_IEEE_FORMAT
for (i = 2; i <= 5; i++)
{
if (pe[i] != 0)
{
enan (y, (*p & 0x8000) != 0);
return;
}
}
#else /* not ARM */
/* In Motorola extended precision format, the most significant /* In Motorola extended precision format, the most significant
bit of an infinity mantissa could be either 1 or 0. It is bit of an infinity mantissa could be either 1 or 0. It is
the lower order bits that tell whether the value is a NaN. */ the lower order bits that tell whether the value is a NaN. */
...@@ -3269,7 +3295,6 @@ bigend_nan: ...@@ -3269,7 +3295,6 @@ bigend_nan:
return; return;
} }
} }
#endif /* not ARM */
} }
#endif /* NANS */ #endif /* NANS */
eclear (y); eclear (y);
...@@ -3293,86 +3318,9 @@ e113toe (pe, y) ...@@ -3293,86 +3318,9 @@ e113toe (pe, y)
const UEMUSHORT *pe; const UEMUSHORT *pe;
UEMUSHORT *y; UEMUSHORT *y;
{ {
UEMUSHORT r; ieeetoe (pe, y, &ieee_113);
const UEMUSHORT *e;
UEMUSHORT *p;
UEMUSHORT yy[NI];
int denorm, i;
e = pe;
denorm = 0;
ecleaz (yy);
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
e += 7;
#endif
r = *e;
yy[0] = 0;
if (r & 0x8000)
yy[0] = 0xffff;
r &= 0x7fff;
#ifdef INFINITY
if (r == 0x7fff)
{
#ifdef NANS
if (! REAL_WORDS_BIG_ENDIAN)
{
for (i = 0; i < 7; i++)
{
if (pe[i] != 0)
{
enan (y, yy[0] != 0);
return;
}
}
}
else
{
for (i = 1; i < 8; i++)
{
if (pe[i] != 0)
{
enan (y, yy[0] != 0);
return;
}
}
}
#endif /* NANS */
eclear (y);
einfin (y);
if (yy[0])
eneg (y);
return;
}
#endif /* INFINITY */
yy[E] = r;
p = &yy[M + 1];
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
{
for (i = 0; i < 7; i++)
*p++ = *(--e);
}
else
{
++e;
for (i = 0; i < 7; i++)
*p++ = *e++;
}
#endif
/* If denormal, remove the implied bit; else shift down 1. */
if (r == 0)
{
yy[M] = 0;
}
else
{
yy[M] = 1;
eshift (yy, -1);
}
emovo (yy, y);
} }
#endif #endif /* INTEL_EXTENDED_IEEE_FORMAT == 0 */
/* Convert single precision float PE to e type Y. */ /* Convert single precision float PE to e type Y. */
...@@ -3392,50 +3340,83 @@ e24toe (pe, y) ...@@ -3392,50 +3340,83 @@ e24toe (pe, y)
c4xtoe (pe, y, QFmode); c4xtoe (pe, y, QFmode);
#else #else
#ifdef DEC
ieeetoe (pe, y, &dec_f);
#else
ieeetoe (pe, y, &ieee_24);
#endif /* not DEC */
#endif /* not C4X */
#endif /* not IBM */
}
/* Convert machine format float of specified format PE to e type Y. */
static void
ieeetoe (pe, y, fmt)
const UEMUSHORT *pe;
UEMUSHORT *y;
const struct ieee_format *fmt;
{
UEMUSHORT r; UEMUSHORT r;
const UEMUSHORT *e; const UEMUSHORT *e;
UEMUSHORT *p; UEMUSHORT *p;
UEMUSHORT yy[NI]; UEMUSHORT yy[NI];
int denorm, k; int denorm, i, k;
int shortsm1 = fmt->bits / 16 - 1;
#ifdef INFINITY
int expmask = (1 << fmt->expbits) - 1;
#endif
int expshift = (fmt->precision - 1) & 0x0f;
int highbit = 1 << expshift;
e = pe; e = pe;
denorm = 0; /* flag if denormalized number */ denorm = 0;
ecleaz (yy); ecleaz (yy);
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN) if (! REAL_WORDS_BIG_ENDIAN)
e += 1; e += shortsm1;
#endif
#ifdef DEC
e += 1;
#endif
r = *e; r = *e;
yy[0] = 0; yy[0] = 0;
if (r & 0x8000) if (r & 0x8000)
yy[0] = 0xffff; yy[0] = 0xffff;
yy[M] = (r & 0x7f) | 0200; yy[M] = (r & (highbit - 1)) | highbit;
r &= ~0x807f; /* strip sign and 7 significand bits */ r = (r & 0x7fff) >> expshift;
#ifdef INFINITY #ifdef INFINITY
if (!LARGEST_EXPONENT_IS_NORMAL (32) && r == 0x7f80) if (!LARGEST_EXPONENT_IS_NORMAL (fmt->precision) && r == expmask)
{ {
#ifdef NANS #ifdef NANS
if (REAL_WORDS_BIG_ENDIAN) /* First check the word where high order mantissa and exponent live */
if ((*e & (highbit - 1)) != 0)
{
enan (y, yy[0] != 0);
return;
}
if (! REAL_WORDS_BIG_ENDIAN)
{ {
if (((pe[0] & 0x7f) != 0) || (pe[1] != 0)) for (i = 0; i < shortsm1; i++)
{ {
enan (y, yy[0] != 0); if (pe[i] != 0)
return; {
enan (y, yy[0] != 0);
return;
}
} }
} }
else else
{ {
if (((pe[1] & 0x7f) != 0) || (pe[0] != 0)) for (i = 1; i < shortsm1 + 1; i++)
{ {
enan (y, yy[0] != 0); if (pe[i] != 0)
return; {
enan (y, yy[0] != 0);
return;
}
} }
} }
#endif /* NANS */ #endif /* NANS */
eclear (y); eclear (y);
einfin (y); einfin (y);
if (yy[0]) if (yy[0])
...@@ -3443,40 +3424,45 @@ e24toe (pe, y) ...@@ -3443,40 +3424,45 @@ e24toe (pe, y)
return; return;
} }
#endif /* INFINITY */ #endif /* INFINITY */
r >>= 7;
/* If zero exponent, then the significand is denormalized. /* If zero exponent, then the significand is denormalized.
So take back the understood high significand bit. */ So take back the understood high significand bit. */
if (r == 0) if (r == 0)
{ {
denorm = 1; denorm = 1;
yy[M] &= ~0200; yy[M] &= ~highbit;
} }
r += EXONE - 0177; r += fmt->adjustment;
yy[E] = r; yy[E] = r;
p = &yy[M + 1]; p = &yy[M + 1];
#ifdef DEC
*p++ = *(--e);
#endif
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN) if (! REAL_WORDS_BIG_ENDIAN)
*p++ = *(--e); {
for (i = 0; i < shortsm1; i++)
*p++ = *(--e);
}
else else
{ {
++e; ++e;
*p++ = *e++; for (i = 0; i < shortsm1; i++)
*p++ = *e++;
} }
#endif if (fmt->precision == 113)
eshift (yy, -8); {
if (denorm) /* denorm is left alone in 113 bit format */
{ /* if zero exponent, then normalize the significand */ if (!denorm)
if ((k = enormlz (yy)) > NBITS) eshift (yy, -1);
ecleazs (yy); }
else else
yy[E] -= (UEMUSHORT) (k - 1); {
eshift (yy, -(expshift + 1));
if (denorm)
{ /* if zero exponent, then normalize the significand */
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
yy[E] -= (UEMUSHORT) (k - 1);
}
} }
emovo (yy, y); emovo (yy, y);
#endif /* not C4X */
#endif /* not IBM */
} }
#if (INTEL_EXTENDED_IEEE_FORMAT == 0) #if (INTEL_EXTENDED_IEEE_FORMAT == 0)
...@@ -3487,93 +3473,20 @@ etoe113 (x, e) ...@@ -3487,93 +3473,20 @@ etoe113 (x, e)
const UEMUSHORT *x; const UEMUSHORT *x;
UEMUSHORT *e; UEMUSHORT *e;
{ {
UEMUSHORT xi[NI]; etoieee (x, e, &ieee_113);
EMULONG exp; }
int rndsav;
#ifdef NANS
if (eisnan (x))
{
make_nan (e, eisneg (x), TFmode);
return;
}
#endif
emovi (x, xi);
exp = (EMULONG) xi[E];
#ifdef INFINITY
if (eisinf (x))
goto nonorm;
#endif
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 113;
emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
#ifdef INFINITY
nonorm:
#endif
toe113 (xi, e);
}
/* Convert exploded e-type X, that has already been rounded to /* Convert exploded e-type X, that has already been rounded to
113-bit precision, to IEEE 128-bit long double format Y. */ 113-bit precision, to IEEE 128-bit long double format Y. */
static void static void
toe113 (a, b) toe113 (x, y)
UEMUSHORT *a, *b; UEMUSHORT *x, *y;
{ {
UEMUSHORT *p, *q; toieee (x, y, &ieee_113);
UEMUSHORT i;
#ifdef NANS
if (eiisnan (a))
{
make_nan (b, eiisneg (a), TFmode);
return;
}
#endif
p = a;
if (REAL_WORDS_BIG_ENDIAN)
q = b;
else
q = b + 7; /* point to output exponent */
/* If not denormal, delete the implied bit. */
if (a[E] != 0)
{
eshup1 (a);
}
/* combine sign and exponent */
i = *p++;
if (REAL_WORDS_BIG_ENDIAN)
{
if (i)
*q++ = *p++ | 0x8000;
else
*q++ = *p++;
}
else
{
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
}
/* skip over guard word */
++p;
/* move the significand */
if (REAL_WORDS_BIG_ENDIAN)
{
for (i = 0; i < 7; i++)
*q++ = *p++;
}
else
{
for (i = 0; i < 7; i++)
*q-- = *p++;
}
} }
#endif
#endif /* INTEL_EXTENDED_IEEE_FORMAT == 0 */
/* Convert e-type X to IEEE double extended format E. */ /* Convert e-type X to IEEE double extended format E. */
...@@ -3582,148 +3495,17 @@ etoe64 (x, e) ...@@ -3582,148 +3495,17 @@ etoe64 (x, e)
const UEMUSHORT *x; const UEMUSHORT *x;
UEMUSHORT *e; UEMUSHORT *e;
{ {
UEMUSHORT xi[NI]; etoieee (x, e, &ieee_64);
EMULONG exp;
int rndsav;
#ifdef NANS
if (eisnan (x))
{
make_nan (e, eisneg (x), XFmode);
return;
}
#endif
emovi (x, xi);
/* adjust exponent for offset */
exp = (EMULONG) xi[E];
#ifdef INFINITY
if (eisinf (x))
goto nonorm;
#endif
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 64;
emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
#ifdef INFINITY
nonorm:
#endif
toe64 (xi, e);
} }
/* Convert exploded e-type X, that has already been rounded to /* Convert exploded e-type X, that has already been rounded to
64-bit precision, to IEEE double extended format Y. */ 64-bit precision, to IEEE double extended format Y. */
static void static void
toe64 (a, b) toe64 (x, y)
UEMUSHORT *a, *b; UEMUSHORT *x, *y;
{ {
UEMUSHORT *p, *q; toieee (x, y, &ieee_64);
UEMUSHORT i;
#ifdef NANS
if (eiisnan (a))
{
make_nan (b, eiisneg (a), XFmode);
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;
#endif
#ifdef DEC
q = b + 4;
#endif
#ifdef IEEE
if (REAL_WORDS_BIG_ENDIAN)
q = b;
else
{
q = b + 4; /* point to output exponent */
/* Clear the last two bytes of 12-byte Intel format. q is pointing
into an array of size 6 (e.g. x[NE]), so the last two bytes are
always there, and there are never more bytes, even when we are using
INTEL_EXTENDED_IEEE_FORMAT. */
*(q+1) = 0;
}
#endif
/* combine sign and exponent */
i = *p++;
#ifdef IBM
if (i)
*q++ = *p++ | 0x8000;
else
*q++ = *p++;
*q++ = 0;
#endif
#ifdef DEC
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
#endif
#ifdef IEEE
if (REAL_WORDS_BIG_ENDIAN)
{
#ifdef ARM_EXTENDED_IEEE_FORMAT
/* The exponent is in the lowest 15 bits of the first word. */
*q++ = i ? 0x8000 : 0;
*q++ = *p++;
#else
if (i)
*q++ = *p++ | 0x8000;
else
*q++ = *p++;
*q++ = 0;
#endif
}
else
{
if (i)
*q-- = *p++ | 0x8000;
else
*q-- = *p++;
}
#endif
/* skip over guard word */
++p;
/* move the significand */
#ifdef IBM
for (i = 0; i < 4; i++)
*q++ = *p++;
#endif
#ifdef DEC
for (i = 0; i < 4; i++)
*q-- = *p++;
#endif
#ifdef IEEE
if (REAL_WORDS_BIG_ENDIAN)
{
for (i = 0; i < 4; i++)
*q++ = *p++;
}
else
{
#ifdef INFINITY
if (eiisinf (a))
{
/* Intel long double infinity significand. */
*q-- = 0x8000;
*q-- = 0;
*q-- = 0;
*q = 0;
return;
}
#endif
for (i = 0; i < 4; i++)
*q-- = *p++;
}
#endif
} }
/* e type to double precision. */ /* e type to double precision. */
...@@ -3736,7 +3518,7 @@ etoe53 (x, e) ...@@ -3736,7 +3518,7 @@ etoe53 (x, e)
const UEMUSHORT *x; const UEMUSHORT *x;
UEMUSHORT *e; UEMUSHORT *e;
{ {
etodec (x, e); /* see etodec.c */ etodec (x, e);
} }
/* Convert exploded e-type X, that has already been rounded to /* Convert exploded e-type X, that has already been rounded to
...@@ -3799,36 +3581,10 @@ toe53 (x, y) ...@@ -3799,36 +3581,10 @@ toe53 (x, y)
static void static void
etoe53 (x, e) etoe53 (x, e)
const UEMUSHORT *x; const UEMUSHORT *x;
UEMUSHORT *e; UEMUSHORT *e;
{ {
UEMUSHORT xi[NI]; etoieee (x, e, &ieee_53);
EMULONG exp;
int rndsav;
#ifdef NANS
if (eisnan (x))
{
make_nan (e, eisneg (x), DFmode);
return;
}
#endif
emovi (x, xi);
/* adjust exponent for offsets */
exp = (EMULONG) xi[E] - (EXONE - 0x3ff);
#ifdef INFINITY
if (eisinf (x))
goto nonorm;
#endif
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 53;
emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
#ifdef INFINITY
nonorm:
#endif
toe53 (xi, e);
} }
/* Convert exploded e-type X, that has already been rounded to /* Convert exploded e-type X, that has already been rounded to
...@@ -3838,91 +3594,7 @@ static void ...@@ -3838,91 +3594,7 @@ static void
toe53 (x, y) toe53 (x, y)
UEMUSHORT *x, *y; UEMUSHORT *x, *y;
{ {
UEMUSHORT i; toieee (x, y, &ieee_53);
UEMUSHORT *p;
#ifdef NANS
if (eiisnan (x))
{
make_nan (y, eiisneg (x), DFmode);
return;
}
#endif
if (LARGEST_EXPONENT_IS_NORMAL (64) && x[1] > 2047)
{
saturate (y, eiisneg (x), 64, 1);
return;
}
p = &x[0];
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
y += 3;
#endif
*y = 0; /* output high order */
if (*p++)
*y = 0x8000; /* output sign bit */
i = *p++;
if (i >= (unsigned int) 2047)
{
/* Saturate at largest number less than infinity. */
#ifdef INFINITY
*y |= 0x7ff0;
if (! REAL_WORDS_BIG_ENDIAN)
{
*(--y) = 0;
*(--y) = 0;
*(--y) = 0;
}
else
{
++y;
*y++ = 0;
*y++ = 0;
*y++ = 0;
}
#else
*y |= (UEMUSHORT) 0x7fef;
if (! REAL_WORDS_BIG_ENDIAN)
{
*(--y) = 0xffff;
*(--y) = 0xffff;
*(--y) = 0xffff;
}
else
{
++y;
*y++ = 0xffff;
*y++ = 0xffff;
*y++ = 0xffff;
}
#endif
return;
}
if (i == 0)
{
eshift (x, 4);
}
else
{
i <<= 4;
eshift (x, 5);
}
i |= *p++ & (UEMUSHORT) 0x0f; /* *p = xi[M] */
*y |= (UEMUSHORT) i; /* high order output already has sign bit set */
if (! REAL_WORDS_BIG_ENDIAN)
{
*(--y) = *p++;
*(--y) = *p++;
*(--y) = *p;
}
else
{
++y;
*y++ = *p++;
*y++ = *p++;
*y++ = *p++;
}
} }
#endif /* not C4X */ #endif /* not C4X */
...@@ -3954,7 +3626,7 @@ toe24 (x, y) ...@@ -3954,7 +3626,7 @@ toe24 (x, y)
toibm (x, y, SFmode); toibm (x, y, SFmode);
} }
#else #else /* it's not IBM */
#ifdef C4X #ifdef C4X
/* Convert e-type X to C4X float E. */ /* Convert e-type X to C4X float E. */
...@@ -3977,143 +3649,242 @@ toe24 (x, y) ...@@ -3977,143 +3649,242 @@ toe24 (x, y)
toc4x (x, y, QFmode); toc4x (x, y, QFmode);
} }
#else /* it's neither IBM nor C4X */
#ifdef DEC
/* Convert e-type X to DEC F-float E. */
static void
etoe24 (x, e)
const UEMUSHORT *x;
UEMUSHORT *e;
{
etoieee (x, e, &dec_f);
}
/* Convert exploded e-type X, that has already been rounded to
float precision, to DEC F-float Y. */
static void
toe24 (x, y)
UEMUSHORT *x, *y;
{
toieee (x, y, &dec_f);
}
#else #else
/* Convert e-type X to IEEE float E. DEC float is the same as IEEE float. */ /* Convert e-type X to IEEE float E. */
static void static void
etoe24 (x, e) etoe24 (x, e)
const UEMUSHORT *x; const UEMUSHORT *x;
UEMUSHORT *e; UEMUSHORT *e;
{
etoieee (x, e, &ieee_24);
}
/* Convert exploded e-type X, that has already been rounded to
float precision, to IEEE float Y. */
static void
toe24 (x, y)
UEMUSHORT *x, *y;
{
toieee (x, y, &ieee_24);
}
#endif /* not DEC */
#endif /* not C4X */
#endif /* not IBM */
/* Convert e-type X to the IEEE format described by FMT. */
static void
etoieee (x, e, fmt)
const UEMUSHORT *x;
UEMUSHORT *e;
const struct ieee_format *fmt;
{ {
EMULONG exp;
UEMUSHORT xi[NI]; UEMUSHORT xi[NI];
EMULONG exp;
int rndsav; int rndsav;
#ifdef NANS #ifdef NANS
if (eisnan (x)) if (eisnan (x))
{ {
make_nan (e, eisneg (x), SFmode); make_nan (e, eisneg (x), fmt->mode);
return; return;
} }
#endif #endif
emovi (x, xi); emovi (x, xi);
/* adjust exponent for offsets */
exp = (EMULONG) xi[E] - (EXONE - 0177);
#ifdef INFINITY #ifdef INFINITY
if (eisinf (x)) if (eisinf (x))
goto nonorm; goto nonorm;
#endif #endif
/* round off to nearest or even */ /* Adjust exponent for offset. */
exp = (EMULONG) xi[E] - fmt->adjustment;
/* Round off to nearest or even. */
rndsav = rndprc; rndsav = rndprc;
rndprc = 24; rndprc = fmt->precision;
emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO); emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav; rndprc = rndsav;
#ifdef INFINITY #ifdef INFINITY
nonorm: nonorm:
#endif #endif
toe24 (xi, e); toieee (xi, e, fmt);
} }
/* Convert exploded e-type X, that has already been rounded to /* Convert exploded e-type X, that has already been rounded to
float precision, to IEEE float Y. */ the necessary precision, to the IEEE format described by FMT. */
static void static void
toe24 (x, y) toieee (x, y, fmt)
UEMUSHORT *x, *y; UEMUSHORT *x, *y;
const struct ieee_format *fmt;
{ {
UEMUSHORT i; UEMUSHORT maxexp;
UEMUSHORT *p; UEMUSHORT *q;
int words;
int i;
maxexp = (1 << fmt->expbits) - 1;
words = (fmt->bits - fmt->expbits) / EMUSHORT_SIZE;
#ifdef NANS #ifdef NANS
if (eiisnan (x)) if (eiisnan (x))
{ {
make_nan (y, eiisneg (x), SFmode); make_nan (y, eiisneg (x), fmt->mode);
return; return;
} }
#endif #endif
if (LARGEST_EXPONENT_IS_NORMAL (32) && x[1] > 255)
if (fmt->expbits < 15
&& LARGEST_EXPONENT_IS_NORMAL (fmt->bits)
&& x[E] > maxexp)
{ {
saturate (y, eiisneg (x), 32, 1); saturate (y, eiisneg (x), fmt->bits, 1);
return; return;
} }
p = &x[0];
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
y += 1;
#endif
#ifdef DEC
y += 1;
#endif
*y = 0; /* output high order */
if (*p++)
*y = 0x8000; /* output sign bit */
i = *p++; /* Point to the exponent. */
/* Handle overflow cases. */ if (REAL_WORDS_BIG_ENDIAN)
if (!LARGEST_EXPONENT_IS_NORMAL (32) && i >= 255) q = y;
else
q = y + words;
/* Copy the sign. */
if (x[0])
*q = 0x8000;
else
*q = 0;
if (fmt->expbits < 15
&& !LARGEST_EXPONENT_IS_NORMAL (fmt->bits)
&& x[E] >= maxexp)
{ {
/* Saturate at largest number less that infinity. */
UEMUSHORT fill;
#ifdef INFINITY #ifdef INFINITY
*y |= (UEMUSHORT) 0x7f80; *q |= maxexp << (15 - fmt->expbits);
#ifdef DEC fill = 0;
*(--y) = 0; #else
*q |= (maxexp << (15 - fmt->expbits)) - 1;
fill = 0xffff;
#endif #endif
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN) if (!REAL_WORDS_BIG_ENDIAN)
*(--y) = 0;
else
{ {
++y; for (i = 0; i < words; i++)
*y = 0; *(--q) = fill;
} }
#endif
#else /* no INFINITY */
*y |= (UEMUSHORT) 0x7f7f;
#ifdef DEC
*(--y) = 0xffff;
#endif
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
*(--y) = 0xffff;
else else
{ {
++y; for (i = 0; i < words; i++)
*y = 0xffff; *(++q) = fill;
} }
#endif #if defined(INFINITY) && defined(ERANGE)
#ifdef ERANGE
errno = ERANGE; errno = ERANGE;
#endif #endif
#endif /* no INFINITY */
return; return;
} }
if (i == 0)
/* If denormal and DEC float, return zero (DEC has no denormals) */
#ifdef DEC
if (x[E] == 0)
{
for (i = 0; i < fmt->bits / EMUSHORT_SIZE ; i++)
q[i] = 0;
return;
}
#endif /* DEC */
/* Delete the implied bit unless denormal, except for
64-bit precision. */
if (fmt->precision != 64 && x[E] != 0)
{ {
eshift (x, 7); eshup1 (x);
}
/* Shift denormal double extended Intel format significand down
one bit. */
if (fmt->precision == 64 && x[E] == 0 && ! REAL_WORDS_BIG_ENDIAN)
eshdn1 (x);
if (fmt->expbits < 15)
{
/* Shift the significand. */
eshift (x, 15 - fmt->expbits);
/* Combine the exponent and upper bits of the significand. */
*q |= x[E] << (15 - fmt->expbits);
*q |= x[M] & (UEMUSHORT) ~((maxexp << (15 - fmt->expbits)) | 0x8000);
} }
else else
{ {
i <<= 7; /* Copy the exponent. */
eshift (x, 8); *q |= x[E];
}
/* Add padding after the exponent. At the moment, this is only necessary for
64-bit precision; in this case, the padding is 16 bits. */
if (fmt->precision == 64)
{
*(q + 1) = 0;
/* Skip padding. */
if (REAL_WORDS_BIG_ENDIAN)
++q;
}
/* Copy the significand. */
if (REAL_WORDS_BIG_ENDIAN)
{
for (i = 0; i < words; i++)
*(++q) = x[i + M + 1];
}
#ifdef INFINITY
else if (fmt->precision == 64 && eiisinf (x))
{
/* Intel double extended infinity significand. */
*(--q) = 0x8000;
*(--q) = 0;
*(--q) = 0;
*(--q) = 0;
} }
i |= *p++ & (UEMUSHORT) 0x7f; /* *p = xi[M] */
/* High order output already has sign bit set. */
*y |= i;
#ifdef DEC
*(--y) = *p;
#endif #endif
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
*(--y) = *p;
else else
{ {
++y; for (i = 0; i < words; i++)
*y = *p; *(--q) = x[i + M + 1];
} }
#endif
} }
#endif /* not C4X */
#endif /* not IBM */
/* Compare two e type numbers. /* Compare two e type numbers.
Return +1 if a > b Return +1 if a > b
...@@ -5436,14 +5207,22 @@ read_expnt: ...@@ -5436,14 +5207,22 @@ read_expnt:
else if (oprec == 24 || oprec == 56) else if (oprec == 24 || oprec == 56)
lexp -= EXONE - (0x41 << 2); lexp -= EXONE - (0x41 << 2);
#else #else
#ifdef DEC
else if (oprec == 24) else if (oprec == 24)
lexp -= dec_f.adjustment;
else if (oprec == 56)
{
if (TARGET_G_FLOAT)
lexp -= dec_g.adjustment;
else
lexp -= dec_d.adjustment;
}
#else
else if (oprec == 24)
lexp -= EXONE - 0177; lexp -= EXONE - 0177;
#endif /* DEC */
#endif /* IBM */ #endif /* IBM */
#endif /* C4X */ #endif /* C4X */
#ifdef DEC
else if (oprec == 56)
lexp -= EXONE - 0201;
#endif
rndprc = oprec; rndprc = oprec;
emdnorm (yy, lost, 0, lexp, 64); emdnorm (yy, lost, 0, lexp, 64);
...@@ -5455,7 +5234,7 @@ read_expnt: ...@@ -5455,7 +5234,7 @@ read_expnt:
{ {
#ifdef DEC #ifdef DEC
case 56: case 56:
todec (yy, y); /* see etodec.c */ todec (yy, y);
break; break;
#endif #endif
#ifdef IBM #ifdef IBM
...@@ -5754,37 +5533,10 @@ dectoe (d, e) ...@@ -5754,37 +5533,10 @@ dectoe (d, e)
const UEMUSHORT *d; const UEMUSHORT *d;
UEMUSHORT *e; UEMUSHORT *e;
{ {
UEMUSHORT y[NI]; if (TARGET_G_FLOAT)
UEMUSHORT r, *p; ieeetoe (d, e, &dec_g);
else
ecleaz (y); /* start with a zero */ ieeetoe (d, e, &dec_d);
p = y; /* point to our number */
r = *d; /* get DEC exponent word */
if (*d & (unsigned int) 0x8000)
*p = 0xffff; /* fill in our sign */
++p; /* bump pointer to our exponent word */
r &= 0x7fff; /* strip the sign bit */
if (r == 0) /* answer = 0 if high order DEC word = 0 */
goto done;
r >>= 7; /* shift exponent word down 7 bits */
r += EXONE - 0201; /* subtract DEC exponent offset */
/* add our e type exponent offset */
*p++ = r; /* to form our exponent */
r = *d++; /* now do the high order mantissa */
r &= 0177; /* strip off the DEC exponent and sign bits */
r |= 0200; /* the DEC understood high order mantissa bit */
*p++ = r; /* put result in our high guard word */
*p++ = *d++; /* fill in the rest of our mantissa */
*p++ = *d++;
*p = *d;
eshdn8 (y); /* shift our mantissa down 8 bits */
done:
emovo (y, e);
} }
/* Convert e type X to DEC double precision D. */ /* Convert e type X to DEC double precision D. */
...@@ -5797,13 +5549,19 @@ etodec (x, d) ...@@ -5797,13 +5549,19 @@ etodec (x, d)
UEMUSHORT xi[NI]; UEMUSHORT xi[NI];
EMULONG exp; EMULONG exp;
int rndsav; int rndsav;
const struct ieee_format *fmt;
if (TARGET_G_FLOAT)
fmt = &dec_g;
else
fmt = &dec_d;
emovi (x, xi); emovi (x, xi);
/* Adjust exponent for offsets. */ /* Adjust exponent for offsets. */
exp = (EMULONG) xi[E] - (EXONE - 0201); exp = (EMULONG) xi[E] - fmt->adjustment;
/* Round off to nearest or even. */ /* Round off to nearest or even. */
rndsav = rndprc; rndsav = rndprc;
rndprc = 56; rndprc = fmt->precision;
emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO); emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav; rndprc = rndsav;
todec (xi, d); todec (xi, d);
...@@ -5816,42 +5574,10 @@ static void ...@@ -5816,42 +5574,10 @@ static void
todec (x, y) todec (x, y)
UEMUSHORT *x, *y; UEMUSHORT *x, *y;
{ {
UEMUSHORT i; if (TARGET_G_FLOAT)
UEMUSHORT *p; toieee (x, y, &dec_g);
else
p = x; toieee (x, y, &dec_d);
*y = 0;
if (*p++)
*y = 0100000;
i = *p++;
if (i == 0)
{
*y++ = 0;
*y++ = 0;
*y++ = 0;
*y++ = 0;
return;
}
if (i > 0377)
{
*y++ |= 077777;
*y++ = 0xffff;
*y++ = 0xffff;
*y++ = 0xffff;
#ifdef ERANGE
errno = ERANGE;
#endif
return;
}
i &= 0377;
i <<= 7;
eshup8 (x);
x[M] &= 0177;
i |= x[M];
*y++ |= i;
*y++ = x[M + 1];
*y++ = x[M + 2];
*y++ = x[M + 3];
} }
#endif /* DEC */ #endif /* DEC */
...@@ -6904,49 +6630,37 @@ significand_size (mode) ...@@ -6904,49 +6630,37 @@ significand_size (mode)
enum machine_mode mode; enum machine_mode mode;
{ {
/* Don't test the modes, but their sizes, lest this /* Don't test the modes, but their sizes, lest this
code won't work for BITS_PER_UNIT != 8 . */ code won't work for BITS_PER_UNIT != 8 . */
switch (GET_MODE_BITSIZE (mode)) switch (GET_MODE_BITSIZE (mode))
{ {
case 32: case 32:
#if TARGET_FLOAT_FORMAT == C4X_FLOAT_FORMAT #ifdef C4X
return 56; return 56;
#else
return 24;
#endif #endif
return 24; case 64:
#ifdef IEEE
case 64: return 53;
#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
return 53;
#else
#if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
return 56;
#else
#if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
return 56;
#else
#if TARGET_FLOAT_FORMAT == C4X_FLOAT_FORMAT
return 56;
#else #else
abort (); return 56;
#endif
#endif
#endif
#endif #endif
case 96: case 96:
return 64; return 64;
case 128: case 128:
#if (INTEL_EXTENDED_IEEE_FORMAT == 0) #if (INTEL_EXTENDED_IEEE_FORMAT == 0)
return 113; return 113;
#else #else
return 64; return 64;
#endif #endif
default: default:
abort (); abort ();
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment