diff options
author | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-23 17:43:01 +0000 |
---|---|---|
committer | danglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-07-23 17:43:01 +0000 |
commit | aca97d53c62c070d275e2767e6d83459ad92fd0b (patch) | |
tree | 6a0f04a2216b011ed8487563e27e0bb88ec8829e /gcc/real.c | |
parent | 59f38b0b33f88ff7045d339ff43778eef204f92b (diff) | |
download | ppe42-gcc-aca97d53c62c070d275e2767e6d83459ad92fd0b.tar.gz ppe42-gcc-aca97d53c62c070d275e2767e6d83459ad92fd0b.zip |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55683 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/real.c')
-rw-r--r-- | gcc/real.c | 1198 |
1 files changed, 456 insertions, 742 deletions
diff --git a/gcc/real.c b/gcc/real.c index 456108eb742..4dcd0363534 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -129,6 +129,31 @@ unknown arithmetic type #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 NANS for support of Not-a-Number's (NaN's). */ #if !defined(DEC) && !defined(IBM) && !defined(C4X) @@ -276,6 +301,106 @@ struct compile_test_dummy { #define CHARMASK 0x7f #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 const UEMUSHORT ezero[NE], ehalf[NE], eone[NE], etwo[NE]; extern const UEMUSHORT elog2[NE], esqrt2[NE]; @@ -350,6 +475,12 @@ static void etoe53 PARAMS ((const UEMUSHORT *, UEMUSHORT *)); static void toe53 PARAMS ((UEMUSHORT *, UEMUSHORT *)); static void etoe24 PARAMS ((const 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 *)); #if 0 static void eround PARAMS ((const UEMUSHORT *, UEMUSHORT *)); @@ -430,7 +561,7 @@ endian (e, x, mode) { unsigned long th, t; - if (REAL_WORDS_BIG_ENDIAN) + if (REAL_WORDS_BIG_ENDIAN && !VAX_HALFWORD_ORDER) { switch (mode) { @@ -3072,90 +3203,9 @@ e53toe (pe, y) c4xtoe (pe, y, HFmode); #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) - { - 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); + ieeetoe (pe, y, &ieee_53); + #endif /* not C4X */ #endif /* not IBM */ #endif /* not DEC */ @@ -3177,24 +3227,15 @@ e64toe (pe, y) p = yy; for (i = 0; i < NE - 5; i++) *p++ = 0; -/* This precision is not ordinarily supported on DEC or IBM. */ -#ifdef DEC - for (i = 0; i < 5; i++) - *p++ = *e++; -#endif -#ifdef IBM - p = &yy[0] + (NE - 1); - *p-- = *e++; - ++e; - for (i = 0; i < 5; i++) - *p-- = *e++; -#endif -#ifdef IEEE +#ifndef C4X + /* REAL_WORDS_BIG_ENDIAN is always 0 for DEC and 1 for IBM. + This precision is not ordinarily supported on DEC or IBM. */ if (! REAL_WORDS_BIG_ENDIAN) { for (i = 0; i < 5; i++) *p++ = *e++; +#ifdef IEEE /* 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. */ @@ -3207,22 +3248,17 @@ e64toe (pe, y) emovo (temp,y); return; } +#endif /* IEEE */ } else { 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++; ++e; -#endif for (i = 0; i < 4; i++) *p-- = *e++; } -#endif +#endif /* not C4X */ #ifdef INFINITY /* Point to the exponent field and check max exponent cases. */ p = &yy[NE - 1]; @@ -3244,16 +3280,6 @@ e64toe (pe, y) } 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 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. */ @@ -3269,7 +3295,6 @@ bigend_nan: return; } } -#endif /* not ARM */ } #endif /* NANS */ eclear (y); @@ -3293,86 +3318,9 @@ e113toe (pe, y) const UEMUSHORT *pe; UEMUSHORT *y; { - UEMUSHORT r; - 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); + ieeetoe (pe, y, &ieee_113); } -#endif +#endif /* INTEL_EXTENDED_IEEE_FORMAT == 0 */ /* Convert single precision float PE to e type Y. */ @@ -3392,50 +3340,83 @@ e24toe (pe, y) c4xtoe (pe, y, QFmode); #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; const UEMUSHORT *e; UEMUSHORT *p; 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; - denorm = 0; /* flag if denormalized number */ + denorm = 0; ecleaz (yy); -#ifdef IEEE if (! REAL_WORDS_BIG_ENDIAN) - e += 1; -#endif -#ifdef DEC - e += 1; -#endif + e += shortsm1; r = *e; yy[0] = 0; if (r & 0x8000) yy[0] = 0xffff; - yy[M] = (r & 0x7f) | 0200; - r &= ~0x807f; /* strip sign and 7 significand bits */ + yy[M] = (r & (highbit - 1)) | highbit; + r = (r & 0x7fff) >> expshift; #ifdef INFINITY - if (!LARGEST_EXPONENT_IS_NORMAL (32) && r == 0x7f80) + if (!LARGEST_EXPONENT_IS_NORMAL (fmt->precision) && r == expmask) { #ifdef NANS - if (REAL_WORDS_BIG_ENDIAN) + /* First check the word where high order mantissa and exponent live */ + if ((*e & (highbit - 1)) != 0) { - if (((pe[0] & 0x7f) != 0) || (pe[1] != 0)) + enan (y, yy[0] != 0); + return; + } + if (! REAL_WORDS_BIG_ENDIAN) + { + for (i = 0; i < shortsm1; i++) { - enan (y, yy[0] != 0); - return; + if (pe[i] != 0) + { + enan (y, yy[0] != 0); + return; + } } } else { - if (((pe[1] & 0x7f) != 0) || (pe[0] != 0)) + for (i = 1; i < shortsm1 + 1; i++) { - enan (y, yy[0] != 0); - return; + if (pe[i] != 0) + { + enan (y, yy[0] != 0); + return; + } } } -#endif /* NANS */ +#endif /* NANS */ eclear (y); einfin (y); if (yy[0]) @@ -3443,40 +3424,45 @@ e24toe (pe, y) return; } #endif /* INFINITY */ - r >>= 7; /* If zero exponent, then the significand is denormalized. So take back the understood high significand bit. */ if (r == 0) { denorm = 1; - yy[M] &= ~0200; + yy[M] &= ~highbit; } - r += EXONE - 0177; + r += fmt->adjustment; yy[E] = r; p = &yy[M + 1]; -#ifdef DEC - *p++ = *(--e); -#endif -#ifdef IEEE if (! REAL_WORDS_BIG_ENDIAN) - *p++ = *(--e); + { + for (i = 0; i < shortsm1; i++) + *p++ = *(--e); + } else { ++e; - *p++ = *e++; + for (i = 0; i < shortsm1; i++) + *p++ = *e++; } -#endif - eshift (yy, -8); - if (denorm) - { /* if zero exponent, then normalize the significand */ - if ((k = enormlz (yy)) > NBITS) - ecleazs (yy); - else - yy[E] -= (UEMUSHORT) (k - 1); + if (fmt->precision == 113) + { + /* denorm is left alone in 113 bit format */ + if (!denorm) + eshift (yy, -1); + } + else + { + 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); -#endif /* not C4X */ -#endif /* not IBM */ } #if (INTEL_EXTENDED_IEEE_FORMAT == 0) @@ -3487,93 +3473,20 @@ etoe113 (x, e) const UEMUSHORT *x; UEMUSHORT *e; { - UEMUSHORT xi[NI]; - 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); + etoieee (x, e, &ieee_113); } /* Convert exploded e-type X, that has already been rounded to 113-bit precision, to IEEE 128-bit long double format Y. */ static void -toe113 (a, b) - UEMUSHORT *a, *b; +toe113 (x, y) + UEMUSHORT *x, *y; { - UEMUSHORT *p, *q; - 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++; - } + toieee (x, y, &ieee_113); } -#endif + +#endif /* INTEL_EXTENDED_IEEE_FORMAT == 0 */ /* Convert e-type X to IEEE double extended format E. */ @@ -3582,148 +3495,17 @@ etoe64 (x, e) const UEMUSHORT *x; UEMUSHORT *e; { - UEMUSHORT xi[NI]; - 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); + etoieee (x, e, &ieee_64); } /* Convert exploded e-type X, that has already been rounded to 64-bit precision, to IEEE double extended format Y. */ static void -toe64 (a, b) - UEMUSHORT *a, *b; +toe64 (x, y) + UEMUSHORT *x, *y; { - UEMUSHORT *p, *q; - 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 + toieee (x, y, &ieee_64); } /* e type to double precision. */ @@ -3736,7 +3518,7 @@ etoe53 (x, e) const UEMUSHORT *x; UEMUSHORT *e; { - etodec (x, e); /* see etodec.c */ + etodec (x, e); } /* Convert exploded e-type X, that has already been rounded to @@ -3799,36 +3581,10 @@ toe53 (x, y) static void etoe53 (x, e) - const UEMUSHORT *x; - UEMUSHORT *e; + const UEMUSHORT *x; + UEMUSHORT *e; { - UEMUSHORT xi[NI]; - 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); + etoieee (x, e, &ieee_53); } /* Convert exploded e-type X, that has already been rounded to @@ -3838,91 +3594,7 @@ static void toe53 (x, y) UEMUSHORT *x, *y; { - UEMUSHORT i; - 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++; - } + toieee (x, y, &ieee_53); } #endif /* not C4X */ @@ -3954,7 +3626,7 @@ toe24 (x, y) toibm (x, y, SFmode); } -#else +#else /* it's not IBM */ #ifdef C4X /* Convert e-type X to C4X float E. */ @@ -3977,143 +3649,242 @@ toe24 (x, y) 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 -/* 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 etoe24 (x, e) - const UEMUSHORT *x; - UEMUSHORT *e; + const UEMUSHORT *x; + 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]; + EMULONG exp; int rndsav; #ifdef NANS if (eisnan (x)) { - make_nan (e, eisneg (x), SFmode); + make_nan (e, eisneg (x), fmt->mode); return; } #endif + emovi (x, xi); - /* adjust exponent for offsets */ - exp = (EMULONG) xi[E] - (EXONE - 0177); + #ifdef INFINITY if (eisinf (x)) goto nonorm; #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; - rndprc = 24; + rndprc = fmt->precision; emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO); rndprc = rndsav; #ifdef INFINITY nonorm: #endif - toe24 (xi, e); + toieee (xi, e, fmt); } /* 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 -toe24 (x, y) - UEMUSHORT *x, *y; +toieee (x, y, fmt) + UEMUSHORT *x, *y; + const struct ieee_format *fmt; { - UEMUSHORT i; - UEMUSHORT *p; + UEMUSHORT maxexp; + UEMUSHORT *q; + int words; + int i; + maxexp = (1 << fmt->expbits) - 1; + words = (fmt->bits - fmt->expbits) / EMUSHORT_SIZE; + #ifdef NANS if (eiisnan (x)) { - make_nan (y, eiisneg (x), SFmode); + make_nan (y, eiisneg (x), fmt->mode); return; } #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; } - 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++; -/* Handle overflow cases. */ - if (!LARGEST_EXPONENT_IS_NORMAL (32) && i >= 255) + /* Point to the exponent. */ + if (REAL_WORDS_BIG_ENDIAN) + 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 - *y |= (UEMUSHORT) 0x7f80; -#ifdef DEC - *(--y) = 0; + *q |= maxexp << (15 - fmt->expbits); + fill = 0; +#else + *q |= (maxexp << (15 - fmt->expbits)) - 1; + fill = 0xffff; #endif -#ifdef IEEE - if (! REAL_WORDS_BIG_ENDIAN) - *(--y) = 0; - else + + if (!REAL_WORDS_BIG_ENDIAN) { - ++y; - *y = 0; + for (i = 0; i < words; i++) + *(--q) = fill; } -#endif -#else /* no INFINITY */ - *y |= (UEMUSHORT) 0x7f7f; -#ifdef DEC - *(--y) = 0xffff; -#endif -#ifdef IEEE - if (! REAL_WORDS_BIG_ENDIAN) - *(--y) = 0xffff; else { - ++y; - *y = 0xffff; + for (i = 0; i < words; i++) + *(++q) = fill; } -#endif -#ifdef ERANGE +#if defined(INFINITY) && defined(ERANGE) errno = ERANGE; #endif -#endif /* no INFINITY */ 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 { - i <<= 7; - eshift (x, 8); + /* Copy the exponent. */ + *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 -#ifdef IEEE - if (! REAL_WORDS_BIG_ENDIAN) - *(--y) = *p; else { - ++y; - *y = *p; + for (i = 0; i < words; i++) + *(--q) = x[i + M + 1]; } -#endif } -#endif /* not C4X */ -#endif /* not IBM */ + /* Compare two e type numbers. Return +1 if a > b @@ -5436,14 +5207,22 @@ read_expnt: else if (oprec == 24 || oprec == 56) lexp -= EXONE - (0x41 << 2); #else +#ifdef DEC 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; +#endif /* DEC */ #endif /* IBM */ #endif /* C4X */ -#ifdef DEC - else if (oprec == 56) - lexp -= EXONE - 0201; -#endif rndprc = oprec; emdnorm (yy, lost, 0, lexp, 64); @@ -5455,7 +5234,7 @@ read_expnt: { #ifdef DEC case 56: - todec (yy, y); /* see etodec.c */ + todec (yy, y); break; #endif #ifdef IBM @@ -5754,37 +5533,10 @@ dectoe (d, e) const UEMUSHORT *d; UEMUSHORT *e; { - UEMUSHORT y[NI]; - UEMUSHORT r, *p; - - ecleaz (y); /* start with a zero */ - 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); + if (TARGET_G_FLOAT) + ieeetoe (d, e, &dec_g); + else + ieeetoe (d, e, &dec_d); } /* Convert e type X to DEC double precision D. */ @@ -5797,13 +5549,19 @@ etodec (x, d) UEMUSHORT xi[NI]; EMULONG exp; int rndsav; + const struct ieee_format *fmt; + + if (TARGET_G_FLOAT) + fmt = &dec_g; + else + fmt = &dec_d; emovi (x, xi); /* Adjust exponent for offsets. */ - exp = (EMULONG) xi[E] - (EXONE - 0201); + exp = (EMULONG) xi[E] - fmt->adjustment; /* Round off to nearest or even. */ rndsav = rndprc; - rndprc = 56; + rndprc = fmt->precision; emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO); rndprc = rndsav; todec (xi, d); @@ -5816,42 +5574,10 @@ static void todec (x, y) UEMUSHORT *x, *y; { - UEMUSHORT i; - UEMUSHORT *p; - - p = x; - *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]; + if (TARGET_G_FLOAT) + toieee (x, y, &dec_g); + else + toieee (x, y, &dec_d); } #endif /* DEC */ @@ -6904,49 +6630,37 @@ significand_size (mode) enum machine_mode mode; { -/* Don't test the modes, but their sizes, lest this - code won't work for BITS_PER_UNIT != 8 . */ + /* Don't test the modes, but their sizes, lest this + code won't work for BITS_PER_UNIT != 8 . */ -switch (GET_MODE_BITSIZE (mode)) - { - case 32: + switch (GET_MODE_BITSIZE (mode)) + { + case 32: -#if TARGET_FLOAT_FORMAT == C4X_FLOAT_FORMAT - return 56; +#ifdef C4X + return 56; +#else + return 24; #endif - return 24; - - case 64: -#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; + case 64: +#ifdef IEEE + return 53; #else - abort (); -#endif -#endif -#endif + return 56; #endif - case 96: - return 64; + case 96: + return 64; - case 128: + case 128: #if (INTEL_EXTENDED_IEEE_FORMAT == 0) - return 113; + return 113; #else - return 64; + return 64; #endif - default: - abort (); - } + default: + abort (); + } } |