/* 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.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "config.h"
#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 to non-zero
+ 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 || \
+ ((INTEL_EXTENDED_IEEE_FORMAT != 0) && 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 *));
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
+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 *));
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
+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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* 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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* 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. */
-
- 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);
- }
}
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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
etoe113 (dg, df);
e113toe (df, dg);
+#else
+ etoe64 (dg, df);
+ e64toe (df, dg);
+#endif
break;
default:
break;
case 128:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
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 && (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* 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++;
}
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* 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);
}
{
/* Long integer overflow: output large integer
and correct fraction.
- Note, the BSD microvax compiler says that ~(0UL)
+ Note, the BSD MicroVAX compiler says that ~(0UL)
is a syntax error. */
*i = ~(0L);
eshift (xi, k);
#define NTEN 12
#define MAXP 4096
-#if LONG_DOUBLE_TYPE_SIZE == 128
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && (INTEL_EXTENDED_IEEE_FORMAT == 0)
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);
}
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* 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
/* Exponent interpretation */
expnt:
- /* 0.0eXXX is zero, regardless of XXX. Check for the 0.0. */
+ /* 0.0eXXX is zero, regardless of XXX. Check for the 0.0. */
for (k = 0; k < NI; k++)
{
if (yy[k] != 0)
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 */
int i;
int carry;
- /* Short-circuit the zero case. */
+ /* Short-circuit the zero case. */
if ((d[0] == 0x8000)
&& (d[1] == 0x0000)
&& ((mode == QFmode) || ((d[2] == 0x0000) && (d[3] == 0x0000))))
}
r >>= 8; /* Shift exponent word down 8 bits. */
- if (r & 0x80) /* Make the exponent negative if it is. */
+ if (r & 0x80) /* Make the exponent negative if it is. */
{
r = r | (~0 & ~0xff);
}
/* Now do the two's complement on the data. */
- carry = 1; /* Initially add 1 for the two's complement. */
+ carry = 1; /* Initially add 1 for the two's complement. */
for (i=size + M; i > M; i--)
{
if (carry && (y[i] == 0x0000))
emovi (x, xi);
- /* Adjust exponent for offsets. */
+ /* Adjust exponent for offsets. */
exp = (EMULONG) xi[E] - (EXONE - 0x7f);
- /* Round off to nearest or even. */
+ /* Round off to nearest or even. */
rndsav = rndprc;
rndprc = mode == QFmode ? 24 : 32;
emdnorm (xi, 0, 0, exp, 64);
/* Only check for double if necessary */
&& ((mode == QFmode) || ((x[M+2] == 0) && (x[M+3] == 0))))
{
- /* We have a zero. Put it into the output and return. */
+ /* We have a zero. Put it into the output and return. */
*y++ = 0x8000;
*y++ = 0x0000;
if (mode != QFmode)
*y = 0;
/* Negative number require a two's complement conversion of the
- mantissa. */
+ mantissa. */
if (x[0])
{
*y = 0x0080;
i = ((int) x[1]) - 0x7f;
- /* Now add 1 to the inverted data to do the two's complement. */
+ /* Now add 1 to the inverted data to do the two's complement. */
if (mode != QFmode)
v = 4 + M;
else
/* The following is a special case. The C4X negative float requires
a zero in the high bit (because the format is (2 - x) x 2^m), so
if a one is in that bit, we have to shift left one to get rid
- of it. This only occurs if the number is -1 x 2^m. */
+ of it. This only occurs if the number is -1 x 2^m. */
if (x[M+1] & 0x8000)
{
/* This is the case of -1 x 2^m, we have to rid ourselves of the
- high sign bit and shift the exponent. */
+ high sign bit and shift the exponent. */
eshift(x, 1);
i--;
}
#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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
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. */
s[0] = (unsigned EMUSHORT) f;
s[1] = (unsigned EMUSHORT) (f >> 16);
}
- /* Convert and promote the target float to E-type. */
+ /* Convert and promote the target float to E-type. */
e24toe (s, e);
- /* Output E-type to REAL_VALUE_TYPE. */
+ /* Output E-type to REAL_VALUE_TYPE. */
PUT_REAL (e, &r);
return r;
}
s[2] = (unsigned EMUSHORT) d[1];
s[3] = (unsigned EMUSHORT) (d[1] >> 16);
}
- /* Convert target double to E-type. */
+ /* Convert target double to E-type. */
e53toe (s, e);
- /* Output E-type to REAL_VALUE_TYPE. */
+ /* Output E-type to REAL_VALUE_TYPE. */
PUT_REAL (e, &r);
return r;
}
/* 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:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
return 113;
+#else
+ return 64;
+#endif
default:
abort ();