The case LONG_DOUBLE_TYPE_SIZE = 128 activates TFmode support
and may deactivate XFmode since `long double' is used to refer
- to both modes.
+ to both modes. Defining INTEL_EXTENDED_IEEE_FORMAT at the same
+ time enables 80387-style 80-bit floats in a 128-bit padded
+ image, as seen on IA-64.
The macros FLOAT_WORDS_BIG_ENDIAN, HOST_FLOAT_WORDS_BIG_ENDIAN,
contributed by Richard Earnshaw <Richard.Earnshaw@cl.cam.ac.uk>,
A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations
in memory, with no holes. */
-#if MAX_LONG_DOUBLE_TYPE_SIZE == 96
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 96 || \
+ (defined(INTEL_EXTENDED_IEEE_FORMAT) && MAX_LONG_DOUBLE_TYPE_SIZE == 128)
/* Number of 16 bit words in external e type format */
-#define NE 6
-#define MAXDECEXP 4932
-#define MINDECEXP -4956
-#define GET_REAL(r,e) bcopy ((char *) r, (char *) e, 2*NE)
-#define PUT_REAL(e,r) \
-do { \
- if (2*NE < sizeof(*r)) \
- bzero((char *)r, sizeof(*r)); \
- bcopy ((char *) e, (char *) r, 2*NE); \
-} while (0)
-#else /* no XFmode */
-#if MAX_LONG_DOUBLE_TYPE_SIZE == 128
-#define NE 10
-#define MAXDECEXP 4932
-#define MINDECEXP -4977
-#define GET_REAL(r,e) bcopy ((char *) r, (char *) e, 2*NE)
-#define PUT_REAL(e,r) \
-do { \
- if (2*NE < sizeof(*r)) \
- bzero((char *)r, sizeof(*r)); \
- bcopy ((char *) e, (char *) r, 2*NE); \
-} while (0)
+# define NE 6
+# define MAXDECEXP 4932
+# define MINDECEXP -4956
+# define GET_REAL(r,e) memcpy ((char *)(e), (char *)(r), 2*NE)
+# define PUT_REAL(e,r) \
+ do { \
+ memcpy ((char *)(r), (char *)(e), 2*NE); \
+ if (2*NE < sizeof(*r)) \
+ memset ((char *)(r) + 2*NE, 0, sizeof(*r) - 2*NE); \
+ } while (0)
+# else /* no XFmode */
+# if MAX_LONG_DOUBLE_TYPE_SIZE == 128
+# define NE 10
+# define MAXDECEXP 4932
+# define MINDECEXP -4977
+# define GET_REAL(r,e) memcpy ((char *)(e), (char *)(r), 2*NE)
+# define PUT_REAL(e,r) \
+ do { \
+ memcpy ((char *)(r), (char *)(e), 2*NE); \
+ if (2*NE < sizeof(*r)) \
+ memset ((char *)(r) + 2*NE, 0, sizeof(*r) - 2*NE); \
+ } while (0)
#else
#define NE 6
#define MAXDECEXP 4932
/* The exponent of 1.0 */
#define EXONE (0x3fff)
+#if defined(HOST_EBCDIC)
+/* bit 8 is significant in EBCDIC */
+#define CHARMASK 0xff
+#else
+#define CHARMASK 0x7f
+#endif
+
extern int extra_warnings;
extern unsigned EMUSHORT ezero[], ehalf[], eone[], etwo[];
extern unsigned EMUSHORT elog2[], esqrt2[];
unsigned EMUSHORT *));
static void e53toe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
static void e64toe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
static void e113toe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+#endif
static void e24toe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
static void etoe113 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
static void toe113 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
static void asctoe24 PARAMS ((const char *, unsigned EMUSHORT *));
static void asctoe53 PARAMS ((const char *, unsigned EMUSHORT *));
static void asctoe64 PARAMS ((const char *, unsigned EMUSHORT *));
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
static void asctoe113 PARAMS ((const char *, unsigned EMUSHORT *));
+#endif
static void asctoe PARAMS ((const char *, unsigned EMUSHORT *));
static void asctoeg PARAMS ((const char *, unsigned EMUSHORT *, int));
static void efloor PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
switch (mode)
{
case TFmode:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
/* Swap halfwords in the fourth long. */
th = (unsigned long) e[6] & 0xffff;
t = (unsigned long) e[7] & 0xffff;
t |= th << 16;
x[3] = (long) t;
+#endif
case XFmode:
/* Swap halfwords in the third long. */
switch (mode)
{
case TFmode:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
/* Pack the fourth long. */
th = (unsigned long) e[7] & 0xffff;
t = (unsigned long) e[6] & 0xffff;
t |= th << 16;
x[3] = (long) t;
+#endif
case XFmode:
/* Pack the third long.
e53toe (tem, e);
break;
- case XFmode:
- asctoe64 (s, tem);
- e64toe (tem, e);
- break;
-
case TFmode:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
asctoe113 (s, tem);
e113toe (tem, e);
break;
+#endif
+ /* FALLTHRU */
+
+ case XFmode:
+ asctoe64 (s, tem);
+ e64toe (tem, e);
+ break;
default:
asctoe (s, e);
break;
case 128:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
etoe113 (dg, df);
e113toe (df, dg);
+#else
+ etoe64 (dg, df);
+ e64toe (df, dg);
+#endif
break;
default:
break;
case 128:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
etoe113 (dg, df);
e113toe (df, dg);
+#else
+ etoe64 (dg, df);
+ e64toe (df, dg);
+#endif
break;
default:
switch (mode)
{
case TFmode:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
etoe113 (e, t);
e113toe (t, t);
break;
+#endif
+ /* FALLTHRU */
case XFmode:
etoe64 (e, t);
/* e type constants used by high precision check routines */
-#if MAX_LONG_DOUBLE_TYPE_SIZE == 128
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && !defined(INTEL_EXTENDED_IEEE_FORMAT)
/* 0.0 */
unsigned EMUSHORT ezero[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
*q++ = *p++;
}
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
/* Convert 128-bit long double precision float PE to e type Y. */
static void
}
emovo (yy, y);
}
+#endif
/* Convert single precision float PE to e type Y. */
else
{
q = b + 4; /* point to output exponent */
- /* The purpose of this conditional is to avoid scribbling beyond
- the end of a long double, in case the type is only 80 bits wide. */
- if (LONG_DOUBLE_TYPE_SIZE == 96)
- {
- /* Clear the last two bytes of 12-byte Intel format */
- *(q+1) = 0;
- }
+ /* 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
#define NTEN 12
#define MAXP 4096
-#if MAX_LONG_DOUBLE_TYPE_SIZE == 128
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && !defined(INTEL_EXTENDED_IEEE_FORMAT)
static unsigned EMUSHORT etens[NTEN + 1][NE] =
{
{0x6576, 0x4a92, 0x804a, 0x153f,
/* Round up and propagate carry-outs */
roun:
--s;
- k = *s & 0x7f;
+ k = *s & CHARMASK;
/* Carry out to most significant digit? */
if (k == '.')
{
asctoeg (s, y, 64);
}
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
/* Convert ASCII string S to 128-bit long double Y. */
static void
{
asctoeg (s, y, 113);
}
+#endif
/* Convert ASCII string S to e type Y. */
}
/* Convert ASCII string SS to e type Y, with a specified rounding precision
- of OPREC bits. BASE is 16 for C9X hexadecimal floating constants. */
+ of OPREC bits. BASE is 16 for C99 hexadecimal floating constants. */
static void
asctoeg (ss, y, oprec)
{
unsigned EMUSHORT yy[NI], xt[NI], tt[NI];
int esign, decflg, sgnflg, nexp, exp, prec, lost;
- int k, trail, c, rndsav;
+ int i, k, trail, c, rndsav;
EMULONG lexp;
- unsigned EMUSHORT nsign, *p;
+ unsigned EMUSHORT nsign;
char *sp, *s, *lstr;
int base = 10;
nxtcom:
if (*s >= '0' && *s <= '9')
k = *s - '0';
- else if (*s >= 'a')
+ else if (*s >= 'a' && *s <= 'f')
k = 10 + *s - 'a';
else
k = 10 + *s - 'A';
|| (*sp >= 'A' && *sp <= 'F'))))
++sp;
/* Check for syntax error */
- c = *sp & 0x7f;
+ c = *sp & CHARMASK;
if ((base != 10 || ((c != 'e') && (c != 'E')))
&& (base != 16 || ((c != 'p') && (c != 'P')))
&& (c != '\0')
&& (c != '\n') && (c != '\r') && (c != ' ')
&& (c != ','))
- goto error;
+ goto unexpected_char_error;
--sp;
while (*sp == '0')
*sp-- = 'z';
goto expnt;
case '.': /* decimal point */
if (decflg)
- goto error;
+ goto unexpected_char_error;
++decflg;
break;
case '-':
nsign = 0xffff;
if (sgnflg)
- goto error;
+ goto unexpected_char_error;
++sgnflg;
break;
case '+':
if (sgnflg)
- goto error;
+ goto unexpected_char_error;
++sgnflg;
break;
case ',':
case 'I':
goto infinite;
default:
- error:
+ unexpected_char_error:
#ifdef NANS
einan (yy);
#else
nexp -= 4096;
}
}
- p = &etens[NTEN][0];
emov (eone, xt);
exp = 1;
+ i = NTEN;
do
{
if (exp & nexp)
- emul (p, xt, xt);
- p -= NE;
+ emul (etens[i], xt, xt);
+ i--;
exp = exp + exp;
}
while (exp <= MAXP);
used like NaN's, but probably not in the same way as IEEE. */
#if !defined(DEC) && !defined(IBM) && !defined(C4X)
case TFmode:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
n = 8;
if (REAL_WORDS_BIG_ENDIAN)
p = TFbignan;
else
p = TFlittlenan;
break;
+#endif
+ /* FALLTHRU */
case XFmode:
n = 6;
case 96:
return 64;
+
case 128:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
return 113;
+#else
+ return 64;
+#endif
default:
abort ();