/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
and support for XFmode IEEE extended real floating point arithmetic.
- Copyright (C) 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
This file is part of GNU CC.
#include "system.h"
#include "tree.h"
#include "toplev.h"
+#include "tm_p.h"
/* To enable support of XFmode extended real floating point, define
LONG_DOUBLE_TYPE_SIZE 96 in the tm.h file (m68k.h or i386.h).
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 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) bcopy ((char *) e, (char *) r, 2*NE)
-#else /* no XFmode */
-#if 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) bcopy ((char *) e, (char *) r, 2*NE)
+# 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
/* Emulator uses target format internally
but host stores it in host endian-ness. */
-#define GET_REAL(r,e) \
-do { \
- if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
- e53toe ((unsigned EMUSHORT *) (r), (e)); \
- else \
- { \
- unsigned EMUSHORT w[4]; \
- w[3] = ((EMUSHORT *) r)[0]; \
- w[2] = ((EMUSHORT *) r)[1]; \
- w[1] = ((EMUSHORT *) r)[2]; \
- w[0] = ((EMUSHORT *) r)[3]; \
- e53toe (w, (e)); \
- } \
+#define GET_REAL(r,e) \
+do { \
+ if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
+ e53toe ((unsigned EMUSHORT *) (r), (e)); \
+ else \
+ { \
+ unsigned EMUSHORT w[4]; \
+ memcpy (&w[3], ((EMUSHORT *) r), sizeof (EMUSHORT)); \
+ memcpy (&w[2], ((EMUSHORT *) r) + 1, sizeof (EMUSHORT)); \
+ memcpy (&w[1], ((EMUSHORT *) r) + 2, sizeof (EMUSHORT)); \
+ memcpy (&w[0], ((EMUSHORT *) r) + 3, sizeof (EMUSHORT)); \
+ e53toe (w, (e)); \
+ } \
} while (0)
-#define PUT_REAL(e,r) \
-do { \
- if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
- etoe53 ((e), (unsigned EMUSHORT *) (r)); \
- else \
- { \
- unsigned EMUSHORT w[4]; \
- etoe53 ((e), w); \
- *((EMUSHORT *) r) = w[3]; \
- *((EMUSHORT *) r + 1) = w[2]; \
- *((EMUSHORT *) r + 2) = w[1]; \
- *((EMUSHORT *) r + 3) = w[0]; \
- } \
+#define PUT_REAL(e,r) \
+do { \
+ if (HOST_FLOAT_WORDS_BIG_ENDIAN == REAL_WORDS_BIG_ENDIAN) \
+ etoe53 ((e), (unsigned EMUSHORT *) (r)); \
+ else \
+ { \
+ unsigned EMUSHORT w[4]; \
+ etoe53 ((e), w); \
+ memcpy (((EMUSHORT *) r), &w[3], sizeof (EMUSHORT)); \
+ memcpy (((EMUSHORT *) r) + 1, &w[2], sizeof (EMUSHORT)); \
+ memcpy (((EMUSHORT *) r) + 2, &w[1], sizeof (EMUSHORT)); \
+ memcpy (((EMUSHORT *) r) + 3, &w[0], sizeof (EMUSHORT)); \
+ } \
} while (0)
#else /* not REAL_ARITHMETIC */
/* 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[];
-static void endian PROTO((unsigned EMUSHORT *, long *,
+static void endian PARAMS ((unsigned EMUSHORT *, long *,
enum machine_mode));
-static void eclear PROTO((unsigned EMUSHORT *));
-static void emov PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void eclear PARAMS ((unsigned EMUSHORT *));
+static void emov PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#if 0
-static void eabs PROTO((unsigned EMUSHORT *));
-#endif
-static void eneg PROTO((unsigned EMUSHORT *));
-static int eisneg PROTO((unsigned EMUSHORT *));
-static int eisinf PROTO((unsigned EMUSHORT *));
-static int eisnan PROTO((unsigned EMUSHORT *));
-static void einfin PROTO((unsigned EMUSHORT *));
-static void enan PROTO((unsigned EMUSHORT *, int));
-static void emovi PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void emovo PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void ecleaz PROTO((unsigned EMUSHORT *));
-static void ecleazs PROTO((unsigned EMUSHORT *));
-static void emovz PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void einan PROTO((unsigned EMUSHORT *));
-static int eiisnan PROTO((unsigned EMUSHORT *));
-static int eiisneg PROTO((unsigned EMUSHORT *));
+static void eabs PARAMS ((unsigned EMUSHORT *));
+#endif
+static void eneg PARAMS ((unsigned EMUSHORT *));
+static int eisneg PARAMS ((unsigned EMUSHORT *));
+static int eisinf PARAMS ((unsigned EMUSHORT *));
+static int eisnan PARAMS ((unsigned EMUSHORT *));
+static void einfin PARAMS ((unsigned EMUSHORT *));
+#ifdef NANS
+static void enan PARAMS ((unsigned EMUSHORT *, int));
+static void einan PARAMS ((unsigned EMUSHORT *));
+static int eiisnan PARAMS ((unsigned EMUSHORT *));
+static int eiisneg PARAMS ((unsigned EMUSHORT *));
+static void make_nan PARAMS ((unsigned EMUSHORT *, int, enum machine_mode));
+#endif
+static void emovi PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void emovo PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void ecleaz PARAMS ((unsigned EMUSHORT *));
+static void ecleazs PARAMS ((unsigned EMUSHORT *));
+static void emovz PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#if 0
-static void eiinfin PROTO((unsigned EMUSHORT *));
-#endif
-static int eiisinf PROTO((unsigned EMUSHORT *));
-static int ecmpm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void eshdn1 PROTO((unsigned EMUSHORT *));
-static void eshup1 PROTO((unsigned EMUSHORT *));
-static void eshdn8 PROTO((unsigned EMUSHORT *));
-static void eshup8 PROTO((unsigned EMUSHORT *));
-static void eshup6 PROTO((unsigned EMUSHORT *));
-static void eshdn6 PROTO((unsigned EMUSHORT *));
-static void eaddm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));\f
-static void esubm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void m16m PROTO((unsigned int, unsigned short *,
+static void eiinfin PARAMS ((unsigned EMUSHORT *));
+#endif
+#ifdef INFINITY
+static int eiisinf PARAMS ((unsigned EMUSHORT *));
+#endif
+static int ecmpm PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void eshdn1 PARAMS ((unsigned EMUSHORT *));
+static void eshup1 PARAMS ((unsigned EMUSHORT *));
+static void eshdn8 PARAMS ((unsigned EMUSHORT *));
+static void eshup8 PARAMS ((unsigned EMUSHORT *));
+static void eshup6 PARAMS ((unsigned EMUSHORT *));
+static void eshdn6 PARAMS ((unsigned EMUSHORT *));
+static void eaddm PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));\f
+static void esubm PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void m16m PARAMS ((unsigned int, unsigned short *,
unsigned short *));
-static int edivm PROTO((unsigned short *, unsigned short *));
-static int emulm PROTO((unsigned short *, unsigned short *));
-static void emdnorm PROTO((unsigned EMUSHORT *, int, int, EMULONG, int));
-static void esub PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static int edivm PARAMS ((unsigned short *, unsigned short *));
+static int emulm PARAMS ((unsigned short *, unsigned short *));
+static void emdnorm PARAMS ((unsigned EMUSHORT *, int, int, EMULONG, int));
+static void esub PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
-static void eadd PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void eadd PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
-static void eadd1 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void eadd1 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
-static void ediv PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void ediv PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
-static void emul PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void emul PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
-static void e53toe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void e64toe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void e113toe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void e24toe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etoe113 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void toe113 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etoe64 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void toe64 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etoe53 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void toe53 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etoe24 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void toe24 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static int ecmp PROTO((unsigned EMUSHORT *, 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 etoe64 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void toe64 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etoe53 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void toe53 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etoe24 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void toe24 PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static int ecmp PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#if 0
-static void eround PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void eround PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#endif
-static void ltoe PROTO((HOST_WIDE_INT *, unsigned EMUSHORT *));
-static void ultoe PROTO((unsigned HOST_WIDE_INT *, unsigned EMUSHORT *));
-static void eifrac PROTO((unsigned EMUSHORT *, HOST_WIDE_INT *,
+static void ltoe PARAMS ((HOST_WIDE_INT *, unsigned EMUSHORT *));
+static void ultoe PARAMS ((unsigned HOST_WIDE_INT *, unsigned EMUSHORT *));
+static void eifrac PARAMS ((unsigned EMUSHORT *, HOST_WIDE_INT *,
unsigned EMUSHORT *));
-static void euifrac PROTO((unsigned EMUSHORT *, unsigned HOST_WIDE_INT *,
+static void euifrac PARAMS ((unsigned EMUSHORT *, unsigned HOST_WIDE_INT *,
unsigned EMUSHORT *));
-static int eshift PROTO((unsigned EMUSHORT *, int));
-static int enormlz PROTO((unsigned EMUSHORT *));
+static int eshift PARAMS ((unsigned EMUSHORT *, int));
+static int enormlz PARAMS ((unsigned EMUSHORT *));
#if 0
-static void e24toasc PROTO((unsigned EMUSHORT *, char *, int));
-static void e53toasc PROTO((unsigned EMUSHORT *, char *, int));
-static void e64toasc PROTO((unsigned EMUSHORT *, char *, int));
-static void e113toasc PROTO((unsigned EMUSHORT *, char *, int));
+static void e24toasc PARAMS ((unsigned EMUSHORT *, char *, int));
+static void e53toasc PARAMS ((unsigned EMUSHORT *, char *, int));
+static void e64toasc PARAMS ((unsigned EMUSHORT *, char *, int));
+static void e113toasc PARAMS ((unsigned EMUSHORT *, char *, int));
#endif /* 0 */
-static void etoasc PROTO((unsigned EMUSHORT *, char *, int));
-static void asctoe24 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe53 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe64 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe113 PROTO((char *, unsigned EMUSHORT *));
-static void asctoe PROTO((char *, unsigned EMUSHORT *));
-static void asctoeg PROTO((char *, unsigned EMUSHORT *, int));
-static void efloor PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etoasc PARAMS ((unsigned EMUSHORT *, char *, int));
+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 *));
#if 0
-static void efrexp PROTO((unsigned EMUSHORT *, int *,
+static void efrexp PARAMS ((unsigned EMUSHORT *, int *,
unsigned EMUSHORT *));
#endif
-static void eldexp PROTO((unsigned EMUSHORT *, int, unsigned EMUSHORT *));
+static void eldexp PARAMS ((unsigned EMUSHORT *, int, unsigned EMUSHORT *));
#if 0
-static void eremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void eremain PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
unsigned EMUSHORT *));
#endif
-static void eiremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void mtherr PROTO((char *, int));
+static void eiremain PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void mtherr PARAMS ((const char *, int));
#ifdef DEC
-static void dectoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etodec PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void todec PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void dectoe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etodec PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void todec PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#endif
#ifdef IBM
-static void ibmtoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void ibmtoe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
-static void etoibm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void etoibm PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
-static void toibm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void toibm PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
#endif
#ifdef C4X
-static void c4xtoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void c4xtoe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
-static void etoc4x PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void etoc4x PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
-static void toc4x PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
+static void toc4x PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *,
enum machine_mode));
#endif
-static void make_nan PROTO((unsigned EMUSHORT *, int, enum machine_mode));
#if 0
-static void uditoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void ditoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etoudi PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void etodi PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void esqrt PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void uditoe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void ditoe PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etoudi PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etodi PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void esqrt PARAMS ((unsigned EMUSHORT *, unsigned EMUSHORT *));
#endif
\f
/* Copy 32-bit numbers obtained from array containing 16-bit numbers,
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.
abort ();
}
}
-
- /* If 32 bits is an entire word for the target, but not for the host,
- then sign-extend on the host so that the number will look the same
- way on the host that it would on the target. See for instance
- simplify_unary_operation. The #if is needed to avoid compiler
- warnings. */
-
-#if HOST_BITS_PER_WIDE_INT > 32
- if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == 32)
- {
- if (x[0] & ((HOST_WIDE_INT) 1 << 31))
- x[0] |= ((HOST_WIDE_INT) (-1) << 32);
-
- if (x[1] & ((HOST_WIDE_INT) 1 << 31))
- x[1] |= ((HOST_WIDE_INT) (-1) << 32);
- }
-#endif
}
REAL_VALUE_TYPE
ereal_atof (s, t)
- char *s;
+ const char *s;
enum machine_mode t;
{
unsigned EMUSHORT tem[NE], e[NE];
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:
int
target_isinf (x)
- REAL_VALUE_TYPE x;
+ REAL_VALUE_TYPE x ATTRIBUTE_UNUSED;
{
+#ifdef INFINITY
unsigned EMUSHORT e[NE];
-#ifdef INFINITY
GET_REAL (&x, e);
return (eisinf (e));
#else
int
target_isnan (x)
- REAL_VALUE_TYPE x;
+ REAL_VALUE_TYPE x ATTRIBUTE_UNUSED;
{
+#ifdef NANS
unsigned EMUSHORT e[NE];
-#ifdef NANS
GET_REAL (&x, e);
return (eisnan (e));
#else
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 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,
static int
eisnan (x)
- unsigned EMUSHORT x[];
+ unsigned EMUSHORT x[] ATTRIBUTE_UNUSED;
{
#ifdef NANS
int i;
This generates Intel's quiet NaN pattern for extended real.
The exponent is 7fff, the leading mantissa word is c000. */
+#ifdef NANS
static void
enan (x, sign)
register unsigned EMUSHORT *x;
*x++ = 0xc000;
*x = (sign << 15) | 0x7fff;
}
+#endif /* NANS */
/* Move in an e-type number A, converting it to exploded e-type B. */
The explicit pattern for this is maximum exponent and
top two significant bits set. */
+#ifdef NANS
static void
einan (x)
unsigned EMUSHORT x[];
x[E] = 0x7fff;
x[M + 1] = 0xc000;
}
+#endif /* NANS */
/* Return nonzero if exploded e-type X is a NaN. */
+#ifdef NANS
static int
eiisnan (x)
unsigned EMUSHORT x[];
}
return (0);
}
+#endif /* NANS */
/* Return nonzero if sign of exploded e-type X is nonzero. */
+#ifdef NANS
static int
eiisneg (x)
unsigned EMUSHORT x[];
return x[0] != 0;
}
+#endif /* NANS */
#if 0
/* Fill exploded e-type X with infinity pattern.
/* Return nonzero if exploded e-type X is infinite. */
+#ifdef INFINITY
static int
eiisinf (x)
unsigned EMUSHORT x[];
return (1);
return (0);
}
-
+#endif /* INFINITY */
/* Compare significands of numbers in internal exploded e-type format.
Guard words are included in the comparison.
*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. */
rndprc = 113;
emdnorm (xi, 0, 0, exp, 64);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe113 (xi, e);
}
rndprc = 64;
emdnorm (xi, 0, 0, exp, 64);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe64 (xi, e);
}
else
{
q = b + 4; /* point to output exponent */
-#if LONG_DOUBLE_TYPE_SIZE == 96
- /* Clear the last two bytes of 12-byte Intel format */
+ /* 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
}
#endif
rndprc = 53;
emdnorm (xi, 0, 0, exp, 64);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe53 (xi, e);
}
rndprc = 24;
emdnorm (xi, 0, 0, exp, 64);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe24 (xi, e);
}
#define NTEN 12
#define MAXP 4096
-#if 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 == '.')
{
static void
asctoe24 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 24);
static void
asctoe53 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
#if defined(DEC) || defined(IBM)
static void
asctoe64 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 64);
}
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
/* Convert ASCII string S to 128-bit long double Y. */
static void
asctoe113 (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, 113);
}
+#endif
/* Convert ASCII string S to e type Y. */
static void
asctoe (s, y)
- char *s;
+ const char *s;
unsigned EMUSHORT *y;
{
asctoeg (s, y, NBITS);
}
/* 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)
- char *ss;
+ const char *ss;
unsigned EMUSHORT *y;
int 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;
/* Copy the input string. */
lstr = (char *) alloca (strlen (ss) + 1);
- s = ss;
- while (*s == ' ') /* skip leading spaces */
- ++s;
+ while (*ss == ' ') /* skip leading spaces */
+ ++ss;
sp = lstr;
- while ((*sp++ = *s++) != '\0')
+ while ((*sp++ = *ss++) != '\0')
;
s = lstr;
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';
else
{
if (decflg)
- nexp += 1; /* count digits after decimal point */
+ nexp += 1; /* count digits after decimal point */
- eshup1 (yy); /* multiply current number by 10 */
+ eshup1 (yy); /* multiply current number by 10 */
emovz (yy, xt);
eshup1 (xt);
eshup1 (xt);
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
exp *= 10;
exp += *s++ - '0';
if (exp > 999999)
- break;
+ break;
}
if (esign < 0)
exp = -exp;
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);
}
/* Report an error condition CODE encountered in function NAME.
- CODE is one of the following:
Mnemonic Value Significance
The order of appearance of the following messages is bound to the
error codes defined above. */
-#define NMSGS 8
-static char *ermsg[NMSGS] =
-{
- "unknown", /* error code 0 */
- "domain", /* error code 1 */
- "singularity", /* et seq. */
- "overflow",
- "underflow",
- "total loss of precision",
- "partial loss of precision",
- "invalid operation"
-};
-
int merror = 0;
extern int merror;
static void
mtherr (name, code)
- char *name;
+ const char *name;
int code;
{
- char errstr[80];
-
/* The string passed by the calling program is supposed to be the
name of the function in which the error occurred.
The code argument selects which error message string will be printed. */
- if ((code <= 0) || (code >= NMSGS))
- code = 0;
- sprintf (errstr, " %s %s error", name, ermsg[code]);
+ if (strcmp (name, "esub") == 0)
+ name = "subtraction";
+ else if (strcmp (name, "ediv") == 0)
+ name = "division";
+ else if (strcmp (name, "emul") == 0)
+ name = "multiplication";
+ else if (strcmp (name, "enormlz") == 0)
+ name = "normalization";
+ else if (strcmp (name, "etoasc") == 0)
+ name = "conversion to text";
+ else if (strcmp (name, "asctoe") == 0)
+ name = "parsing";
+ else if (strcmp (name, "eremain") == 0)
+ name = "modulus";
+ else if (strcmp (name, "esqrt") == 0)
+ name = "square root";
if (extra_warnings)
- warning (errstr);
+ {
+ switch (code)
+ {
+ case DOMAIN: warning ("%s: argument domain error" , name); break;
+ case SING: warning ("%s: function singularity" , name); break;
+ case OVERFLOW: warning ("%s: overflow range error" , name); break;
+ case UNDERFLOW: warning ("%s: underflow range error" , name); break;
+ case TLOSS: warning ("%s: total loss of precision" , name); break;
+ case PLOSS: warning ("%s: partial loss of precision", name); break;
+ case INVALID: warning ("%s: NaN - producing operation", name); break;
+ default: abort ();
+ }
+ }
+
/* Set global error message word */
merror = code + 1;
}
{
unsigned EMUSHORT y[NI];
register unsigned EMUSHORT r, *p;
- int rndsav;
ecleaz (y); /* start with a zero */
p = y; /* point to our number */
#endif
+#ifdef NANS
static void
make_nan (nan, sign, mode)
unsigned EMUSHORT *nan;
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;
if (! REAL_WORDS_BIG_ENDIAN)
*nan = (sign << 15) | (*p & 0x7fff);
}
+#endif /* NANS */
/* This is the inverse of the function `etarsingle' invoked by
REAL_VALUE_TO_TARGET_SINGLE. */
/* Convert array of HOST_WIDE_INT to equivalent array of 16-bit pieces. */
if (REAL_WORDS_BIG_ENDIAN)
{
+#if HOST_BITS_PER_WIDE_INT == 32
s[0] = (unsigned EMUSHORT) (d[0] >> 16);
s[1] = (unsigned EMUSHORT) d[0];
-#if HOST_BITS_PER_WIDE_INT == 32
s[2] = (unsigned EMUSHORT) (d[1] >> 16);
s[3] = (unsigned EMUSHORT) d[1];
#else
/* In this case the entire target double is contained in the
first array element. The second element of the input is
ignored. */
- s[2] = (unsigned EMUSHORT) (d[0] >> 48);
- s[3] = (unsigned EMUSHORT) (d[0] >> 32);
+ s[0] = (unsigned EMUSHORT) (d[0] >> 48);
+ s[1] = (unsigned EMUSHORT) (d[0] >> 32);
+ s[2] = (unsigned EMUSHORT) (d[0] >> 16);
+ s[3] = (unsigned EMUSHORT) d[0];
#endif
}
else
floating point mode. The mode can hold an integer value
that many bits wide, without losing any bits. */
-int
+unsigned int
significand_size (mode)
enum machine_mode mode;
{
case 96:
return 64;
+
case 128:
+#ifndef INTEL_EXTENDED_IEEE_FORMAT
return 113;
+#else
+ return 64;
+#endif
default:
abort ();