/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
and support for XFmode IEEE extended real floating point arithmetic.
- Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2002 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 "real.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).
-To support cross compilation between IEEE, VAX and IBM floating
-point formats, define REAL_ARITHMETIC in the tm.h file.
-
-In either case the machine files (tm.h) must not contain any code
+Machine files (tm.h etc) must not contain any code
that tries to use host floating point arithmetic to convert
REAL_VALUE_TYPEs from `double' to `float', pass them to fprintf,
etc. In cross-compile situations a REAL_VALUE_TYPE may not
be intelligible to the host computer's native arithmetic.
-The emulator defaults to the host's floating point format so that
-its decimal conversion functions can be used if desired (see
-real.h).
-
The first part of this file interfaces gcc to a floating point
arithmetic suite that was not written with gcc in mind. Avoid
changing the low-level arithmetic routines unless you have suitable
point arithmetic tester, modified for this purpose, can be found on
usc.edu: /pub/C-numanal/ieeetest.zoo. Other tests, and libraries of
XFmode and TFmode transcendental functions, can be obtained by ftp from
-netlib.att.com: netlib/cephes. */
+netlib.att.com: netlib/cephes. */
\f
/* Type of computer arithmetic.
Only one of DEC, IBM, IEEE, C4X, or UNK should get defined.
If LONG_DOUBLE_TYPE_SIZE = 64 (the default, unless tm.h defines it)
then `long double' and `double' are both implemented, but they
- both mean DFmode. In this case, the software floating-point
- support available here is activated by writing
- #define REAL_ARITHMETIC
- in tm.h.
+ both mean DFmode.
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>,
These optional macros may be defined in tm.h. In real.h, they
default to WORDS_BIG_ENDIAN, etc., so there is no need to define
them for any normal host or target machine on which the floats
- and the integers have the same endian-ness. */
+ and the integers have the same endian-ness. */
/* The following converts gcc macros into the ones used by this file. */
-/* REAL_ARITHMETIC defined means that macros in real.h are
- defined to call emulator functions. */
-#ifdef REAL_ARITHMETIC
-
#if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
/* PDP-11, Pro350, VAX: */
#define DEC 1
#define REAL_WORDS_BIG_ENDIAN FLOAT_WORDS_BIG_ENDIAN
-#else
-/* REAL_ARITHMETIC not defined means that the *host's* data
- structure will be used. It may differ by endian-ness from the
- target machine's structure and will get its ends swapped
- accordingly (but not here). Probably only the decimal <-> binary
- functions in this file will actually be used in this case. */
-
-#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
-#define DEC 1
-#else /* it's not VAX */
-#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
-/* IBM System/370 style */
-#define IBM 1
-#else /* it's also not an IBM */
-#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-#define IEEE
-#else /* it's not IEEE either */
-unknown arithmetic type
-#define UNK 1
-#endif /* not IEEE */
-#endif /* not IBM */
-#endif /* not VAX */
-
-#define REAL_WORDS_BIG_ENDIAN HOST_FLOAT_WORDS_BIG_ENDIAN
-
-#endif /* REAL_ARITHMETIC not defined */
-
/* Define INFINITY for support of infinity.
Define NANS for support of Not-a-Number's (NaN's). */
#if !defined(DEC) && !defined(IBM) && !defined(C4X)
#define EMUSHORT_SIZE HOST_BITS_PER_LONG
#define EMULONG_SIZE (2 * HOST_BITS_PER_LONG)
#else
-/* You will have to modify this program to have a smaller unit size. */
-#define EMU_NON_COMPILE
+ #error "You will have to modify this program to have a smaller unit size."
#endif
#endif
#endif
#endif
+/* If no 16-bit type has been found and the compiler is GCC, try HImode. */
+#if defined(__GNUC__) && EMUSHORT_SIZE != 16
+typedef int HItype __attribute__ ((mode (HI)));
+typedef unsigned int UHItype __attribute__ ((mode (HI)));
+#undef EMUSHORT
+#undef EMUSHORT_SIZE
+#undef EMULONG_SIZE
+#define EMUSHORT HItype
+#define UEMUSHORT UHItype
+#define EMUSHORT_SIZE 16
+#define EMULONG_SIZE 32
+#else
+#define UEMUSHORT unsigned EMUSHORT
+#endif
+
#if HOST_BITS_PER_SHORT >= EMULONG_SIZE
#define EMULONG short
#else
#if HOST_BITS_PER_LONGLONG >= EMULONG_SIZE
#define EMULONG long long int
#else
-/* You will have to modify this program to have a smaller unit size. */
-#define EMU_NON_COMPILE
+ #error "You will have to modify this program to have a smaller unit size."
#endif
#endif
#endif
#endif
-
-/* The host interface doesn't work if no 16-bit size exists. */
#if EMUSHORT_SIZE != 16
-#define EMU_NON_COMPILE
-#endif
-
-/* OK to continue compilation. */
-#ifndef EMU_NON_COMPILE
+ #error "The host interface doesn't work if no 16-bit size exists."
+#endif
+
+/* Calculate the size of the generic "e" type. This always has
+ identical in-memory size to REAL_VALUE_TYPE. The sizes are supposed
+ to be the same as well, but when REAL_VALUE_TYPE_SIZE is not evenly
+ divisible by HOST_BITS_PER_WIDE_INT we have some padding in
+ REAL_VALUE_TYPE.
+ There are only two supported sizes: ten and six 16-bit words (160
+ or 96 bits). */
+
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && !INTEL_EXTENDED_IEEE_FORMAT
+/* TFmode */
+# define NE 10
+# define MAXDECEXP 4932
+# define MINDECEXP -4977
+#else
+# define NE 6
+# define MAXDECEXP 4932
+# define MINDECEXP -4956
+#endif
+
+/* Fail compilation if 2*NE is not the appropriate size.
+ If HOST_BITS_PER_WIDE_INT is 64, we're going to have padding
+ at the end of the array, because neither 96 nor 160 is
+ evenly divisible by 64. */
+struct compile_test_dummy {
+ char twice_NE_must_equal_sizeof_REAL_VALUE_TYPE
+ [(sizeof (REAL_VALUE_TYPE) >= 2*NE) ? 1 : -1];
+};
/* Construct macros to translate between REAL_VALUE_TYPE and e type.
In GET_REAL and PUT_REAL, r and e are pointers.
A REAL_VALUE_TYPE is guaranteed to occupy contiguous locations
in memory, with no holes. */
-
-#if LONG_DOUBLE_TYPE_SIZE == 96
-/* 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 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)
-#else
-#define NE 6
-#define MAXDECEXP 4932
-#define MINDECEXP -4956
-#ifdef REAL_ARITHMETIC
-/* 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]; \
- 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); \
- 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 */
-
-/* emulator uses host format */
-#define GET_REAL(r,e) e53toe ((unsigned EMUSHORT *) (r), (e))
-#define PUT_REAL(e,r) etoe53 ((e), (unsigned EMUSHORT *) (r))
-
-#endif /* not REAL_ARITHMETIC */
-#endif /* not TFmode */
-#endif /* not XFmode */
-
+#define GET_REAL(r, e) memcpy ((e), (r), 2*NE)
+#define PUT_REAL(e, r) \
+ do { \
+ memcpy (r, e, 2*NE); \
+ if (2*NE < sizeof (*r)) \
+ memset ((char *) (r) + 2*NE, 0, sizeof (*r) - 2*NE); \
+ } while (0)
/* Number of 16 bit words in internal format */
#define NI (NE+3)
/* 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[];
+extern const UEMUSHORT ezero[NE], ehalf[NE], eone[NE], etwo[NE];
+extern const UEMUSHORT elog2[NE], esqrt2[NE];
-static void endian PROTO((unsigned EMUSHORT *, long *,
+static void endian PARAMS ((const UEMUSHORT *, long *,
enum machine_mode));
-static void eclear PROTO((unsigned EMUSHORT *));
-static void emov PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void eclear PARAMS ((UEMUSHORT *));
+static void emov PARAMS ((const UEMUSHORT *, UEMUSHORT *));
#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 ((UEMUSHORT *));
+#endif
+static void eneg PARAMS ((UEMUSHORT *));
+static int eisneg PARAMS ((const UEMUSHORT *));
+static int eisinf PARAMS ((const UEMUSHORT *));
+static int eisnan PARAMS ((const UEMUSHORT *));
+static void einfin PARAMS ((UEMUSHORT *));
+#ifdef NANS
+static void enan PARAMS ((UEMUSHORT *, int));
+static void einan PARAMS ((UEMUSHORT *));
+static int eiisnan PARAMS ((const UEMUSHORT *));
+static void make_nan PARAMS ((UEMUSHORT *, int, enum machine_mode));
+#endif
+static int eiisneg PARAMS ((const UEMUSHORT *));
+static void saturate PARAMS ((UEMUSHORT *, int, int, int));
+static void emovi PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void emovo PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void ecleaz PARAMS ((UEMUSHORT *));
+static void ecleazs PARAMS ((UEMUSHORT *));
+static void emovz PARAMS ((const UEMUSHORT *, UEMUSHORT *));
#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 *,
- 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 *,
- unsigned EMUSHORT *));
-static void eadd PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- unsigned EMUSHORT *));
-static void eadd1 PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- unsigned EMUSHORT *));
-static void ediv PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- unsigned EMUSHORT *));
-static void emul PROTO((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 eiinfin PARAMS ((UEMUSHORT *));
+#endif
+#ifdef INFINITY
+static int eiisinf PARAMS ((const UEMUSHORT *));
+#endif
+static int ecmpm PARAMS ((const UEMUSHORT *, const UEMUSHORT *));
+static void eshdn1 PARAMS ((UEMUSHORT *));
+static void eshup1 PARAMS ((UEMUSHORT *));
+static void eshdn8 PARAMS ((UEMUSHORT *));
+static void eshup8 PARAMS ((UEMUSHORT *));
+static void eshup6 PARAMS ((UEMUSHORT *));
+static void eshdn6 PARAMS ((UEMUSHORT *));
+static void eaddm PARAMS ((const UEMUSHORT *, UEMUSHORT *));\f
+static void esubm PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void m16m PARAMS ((unsigned int, const UEMUSHORT *, UEMUSHORT *));
+static int edivm PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static int emulm PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void emdnorm PARAMS ((UEMUSHORT *, int, int, EMULONG, int));
+static void esub PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
+static void eadd PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
+static void eadd1 PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
+static void ediv PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
+static void emul PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
+static void e53toe PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void e64toe PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
+static void e113toe PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+#endif
+static void e24toe PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
+static void etoe113 PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void toe113 PARAMS ((UEMUSHORT *, UEMUSHORT *));
+#endif
+static void etoe64 PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void toe64 PARAMS ((UEMUSHORT *, UEMUSHORT *));
+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 int ecmp PARAMS ((const UEMUSHORT *, const UEMUSHORT *));
#if 0
-static void eround PROTO((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 *,
- unsigned EMUSHORT *));
-static void euifrac PROTO((unsigned EMUSHORT *, unsigned HOST_WIDE_INT *,
- unsigned EMUSHORT *));
-static int eshift PROTO((unsigned EMUSHORT *, int));
-static int enormlz PROTO((unsigned EMUSHORT *));
+static void eround PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+#endif
+static void ltoe PARAMS ((const HOST_WIDE_INT *, UEMUSHORT *));
+static void ultoe PARAMS ((const unsigned HOST_WIDE_INT *, UEMUSHORT *));
+static void eifrac PARAMS ((const UEMUSHORT *, HOST_WIDE_INT *,
+ UEMUSHORT *));
+static void euifrac PARAMS ((const UEMUSHORT *, unsigned HOST_WIDE_INT *,
+ UEMUSHORT *));
+static int eshift PARAMS ((UEMUSHORT *, int));
+static int enormlz PARAMS ((UEMUSHORT *));
#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 ((const UEMUSHORT *, char *, int));
+static void e53toasc PARAMS ((const UEMUSHORT *, char *, int));
+static void e64toasc PARAMS ((const UEMUSHORT *, char *, int));
+static void e113toasc PARAMS ((const UEMUSHORT *, char *, int));
#endif /* 0 */
-static void etoasc PROTO((unsigned EMUSHORT *, char *, int));
-static void asctoe24 PROTO((const char *, unsigned EMUSHORT *));
-static void asctoe53 PROTO((const char *, unsigned EMUSHORT *));
-static void asctoe64 PROTO((const char *, unsigned EMUSHORT *));
-static void asctoe113 PROTO((const char *, unsigned EMUSHORT *));
-static void asctoe PROTO((const char *, unsigned EMUSHORT *));
-static void asctoeg PROTO((const char *, unsigned EMUSHORT *, int));
-static void efloor PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
+static void etoasc PARAMS ((const UEMUSHORT *, char *, int));
+static void asctoe24 PARAMS ((const char *, UEMUSHORT *));
+static void asctoe53 PARAMS ((const char *, UEMUSHORT *));
+static void asctoe64 PARAMS ((const char *, UEMUSHORT *));
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
+static void asctoe113 PARAMS ((const char *, UEMUSHORT *));
+#endif
+static void asctoe PARAMS ((const char *, UEMUSHORT *));
+static void asctoeg PARAMS ((const char *, UEMUSHORT *, int));
+static void efloor PARAMS ((const UEMUSHORT *, UEMUSHORT *));
#if 0
-static void efrexp PROTO((unsigned EMUSHORT *, int *,
- unsigned EMUSHORT *));
+static void efrexp PARAMS ((const UEMUSHORT *, int *,
+ UEMUSHORT *));
#endif
-static void eldexp PROTO((unsigned EMUSHORT *, int, unsigned EMUSHORT *));
+static void eldexp PARAMS ((const UEMUSHORT *, int, UEMUSHORT *));
#if 0
-static void eremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- unsigned EMUSHORT *));
+static void eremain PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
+ UEMUSHORT *));
#endif
-static void eiremain PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *));
-static void mtherr PROTO((const char *, int));
+static void eiremain PARAMS ((UEMUSHORT *, UEMUSHORT *));
+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 ((const UEMUSHORT *, UEMUSHORT *));
+static void etodec PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void todec PARAMS ((UEMUSHORT *, UEMUSHORT *));
#endif
#ifdef IBM
-static void ibmtoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
-static void etoibm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
-static void toibm PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
+static void ibmtoe PARAMS ((const UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
+static void etoibm PARAMS ((const UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
+static void toibm PARAMS ((UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
#endif
#ifdef C4X
-static void c4xtoe PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
-static void etoc4x PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
-static void toc4x PROTO((unsigned EMUSHORT *, unsigned EMUSHORT *,
- enum machine_mode));
-#endif
-static void make_nan PROTO((unsigned EMUSHORT *, int, enum machine_mode));
+static void c4xtoe PARAMS ((const UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
+static void etoc4x PARAMS ((const UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
+static void toc4x PARAMS ((UEMUSHORT *, UEMUSHORT *,
+ enum machine_mode));
+#endif
#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 ((const UEMUSHORT *, UEMUSHORT *));
+static void ditoe PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void etoudi PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void etodi PARAMS ((const UEMUSHORT *, UEMUSHORT *));
+static void esqrt PARAMS ((const UEMUSHORT *, UEMUSHORT *));
#endif
\f
/* Copy 32-bit numbers obtained from array containing 16-bit numbers,
swapping ends if required, into output array of longs. The
- result is normally passed to fprintf by the ASM_OUTPUT_ macros. */
+ result is normally passed to fprintf by the ASM_OUTPUT_ macros. */
static void
endian (e, x, mode)
- unsigned EMUSHORT e[];
+ const UEMUSHORT e[];
long x[];
enum machine_mode mode;
{
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;
+#else
+ x[3] = 0;
+#endif
+ /* FALLTHRU */
case XFmode:
/* Swap halfwords in the third long. */
t = (unsigned long) e[5] & 0xffff;
t |= th << 16;
x[2] = (long) t;
- /* fall into the double case */
+ /* FALLTHRU */
case DFmode:
/* Swap halfwords in the second word. */
t = (unsigned long) e[3] & 0xffff;
t |= th << 16;
x[1] = (long) t;
- /* fall into the float case */
+ /* FALLTHRU */
case SFmode:
case HFmode:
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;
+#else
+ x[3] = 0;
+#endif
+ /* FALLTHRU */
case XFmode:
/* Pack the third long.
t = (unsigned long) e[4] & 0xffff;
t |= th << 16;
x[2] = (long) t;
- /* fall into the double case */
+ /* FALLTHRU */
case DFmode:
/* Pack the second long */
t = (unsigned long) e[2] & 0xffff;
t |= th << 16;
x[1] = (long) t;
- /* fall into the float case */
+ /* FALLTHRU */
case SFmode:
case HFmode:
REAL_VALUE_TYPE *r1;
REAL_VALUE_TYPE *r2;
{
- unsigned EMUSHORT d1[NE], d2[NE], v[NE];
+ UEMUSHORT d1[NE], d2[NE], v[NE];
enum tree_code code;
GET_REAL (r1, d1);
break;
case RDIV_EXPR:
-#ifndef REAL_INFINITY
+#ifndef INFINITY
if (ecmp (d2, ezero) == 0)
- {
-#ifdef NANS
- enan (v, eisneg (d1) ^ eisneg (d2));
- break;
-#else
abort ();
#endif
- }
-#endif
ediv (d2, d1, v); /* d1/d2 */
break;
etrunci (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT f[NE], g[NE];
+ UEMUSHORT f[NE], g[NE];
REAL_VALUE_TYPE r;
HOST_WIDE_INT l;
etruncui (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT f[NE], g[NE];
+ UEMUSHORT f[NE], g[NE];
REAL_VALUE_TYPE r;
unsigned HOST_WIDE_INT l;
const char *s;
enum machine_mode t;
{
- unsigned EMUSHORT tem[NE], e[NE];
+ UEMUSHORT tem[NE], e[NE];
REAL_VALUE_TYPE r;
switch (t)
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);
ereal_negate (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
REAL_VALUE_TYPE r;
GET_REAL (&x, e);
efixi (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT f[NE], g[NE];
+ UEMUSHORT f[NE], g[NE];
HOST_WIDE_INT l;
GET_REAL (&x, f);
efixui (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT f[NE], g[NE];
+ UEMUSHORT f[NE], g[NE];
unsigned HOST_WIDE_INT l;
GET_REAL (&x, f);
HOST_WIDE_INT i, j;
enum machine_mode mode;
{
- unsigned EMUSHORT df[NE], dg[NE];
+ UEMUSHORT df[NE], dg[NE];
HOST_WIDE_INT low, high;
int sign;
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:
}
-/* REAL_VALUE_FROM_UNSIGNED_INT macro. */
+/* REAL_VALUE_FROM_UNSIGNED_INT macro. */
void
ereal_from_uint (d, i, j, mode)
unsigned HOST_WIDE_INT i, j;
enum machine_mode mode;
{
- unsigned EMUSHORT df[NE], dg[NE];
+ UEMUSHORT df[NE], dg[NE];
unsigned HOST_WIDE_INT low, high;
if (GET_MODE_CLASS (mode) != MODE_FLOAT)
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:
HOST_WIDE_INT *low, *high;
REAL_VALUE_TYPE rr;
{
- unsigned EMUSHORT d[NE], df[NE], dg[NE], dh[NE];
+ UEMUSHORT d[NE], df[NE], dg[NE], dh[NE];
int s;
GET_REAL (&rr, d);
ediv (df, d, dg); /* dg = d / 2^32 is the high word */
euifrac (dg, (unsigned HOST_WIDE_INT *) high, dh);
emul (df, dh, dg); /* fractional part is the low word */
- euifrac (dg, (unsigned HOST_WIDE_INT *)low, dh);
+ euifrac (dg, (unsigned HOST_WIDE_INT *) low, dh);
if (s)
{
/* complement and add 1 */
REAL_VALUE_TYPE x;
int n;
{
- unsigned EMUSHORT e[NE], y[NE];
+ UEMUSHORT e[NE], y[NE];
REAL_VALUE_TYPE r;
GET_REAL (&x, e);
return (r);
}
-/* These routines are conditionally compiled because functions
- of the same names may be defined in fold-const.c. */
-
-#ifdef REAL_ARITHMETIC
-
/* Check for infinity in a REAL_VALUE_TYPE. */
int
target_isinf (x)
- REAL_VALUE_TYPE x;
+ REAL_VALUE_TYPE x ATTRIBUTE_UNUSED;
{
- unsigned EMUSHORT e[NE];
-
#ifdef INFINITY
+ UEMUSHORT e[NE];
+
GET_REAL (&x, e);
return (eisinf (e));
#else
int
target_isnan (x)
- REAL_VALUE_TYPE x;
+ REAL_VALUE_TYPE x ATTRIBUTE_UNUSED;
{
- unsigned EMUSHORT e[NE];
-
#ifdef NANS
+ UEMUSHORT e[NE];
+
GET_REAL (&x, e);
return (eisnan (e));
#else
enum machine_mode mode;
REAL_VALUE_TYPE arg;
{
- unsigned EMUSHORT e[NE], t[NE];
+ UEMUSHORT e[NE], t[NE];
REAL_VALUE_TYPE r;
GET_REAL (&arg, e);
switch (mode)
{
case TFmode:
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
etoe113 (e, t);
e113toe (t, t);
break;
+#endif
+ /* FALLTHRU */
case XFmode:
etoe64 (e, t);
return (r);
}
+/* Return true if ARG can be represented exactly in MODE. */
+
+bool
+exact_real_truncate (mode, arg)
+ enum machine_mode mode;
+ REAL_VALUE_TYPE *arg;
+{
+ REAL_VALUE_TYPE trunc;
+
+ if (target_isnan (*arg))
+ return false;
+
+ trunc = real_value_truncate (mode, *arg);
+ return ereal_cmp (*arg, trunc) == 0;
+}
+
/* Try to change R into its exact multiplicative inverse in machine mode
MODE. Return nonzero function value if successful. */
enum machine_mode mode;
REAL_VALUE_TYPE *r;
{
- unsigned EMUSHORT e[NE], einv[NE];
+ UEMUSHORT e[NE], einv[NE];
REAL_VALUE_TYPE rinv;
int i;
PUT_REAL (einv, r);
return 1;
}
-#endif /* REAL_ARITHMETIC defined */
/* Used for debugging--print the value of R in human-readable format
on stderr. */
REAL_VALUE_TYPE r;
long l[];
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
GET_REAL (&r, e);
+#if INTEL_EXTENDED_IEEE_FORMAT == 0
etoe113 (e, e);
+#else
+ etoe64 (e, e);
+#endif
endian (e, l, TFmode);
}
REAL_VALUE_TYPE r;
long l[];
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
GET_REAL (&r, e);
etoe64 (e, e);
REAL_VALUE_TYPE r;
long l[];
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
GET_REAL (&r, e);
etoe53 (e, e);
etarsingle (r)
REAL_VALUE_TYPE r;
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
long l;
GET_REAL (&r, e);
REAL_VALUE_TYPE x;
char *s;
{
- unsigned EMUSHORT e[NE];
+ UEMUSHORT e[NE];
GET_REAL (&x, e);
etoasc (e, s, 20);
}
/* Compare X and Y. Return 1 if X > Y, 0 if X == Y, -1 if X < Y,
- or -2 if either is a NaN. */
+ or -2 if either is a NaN. */
int
ereal_cmp (x, y)
REAL_VALUE_TYPE x, y;
{
- unsigned EMUSHORT ex[NE], ey[NE];
+ UEMUSHORT ex[NE], ey[NE];
GET_REAL (&x, ex);
GET_REAL (&y, ey);
ereal_isneg (x)
REAL_VALUE_TYPE x;
{
- unsigned EMUSHORT ex[NE];
+ UEMUSHORT ex[NE];
GET_REAL (&x, ex);
return (eisneg (ex));
}
-/* End of REAL_ARITHMETIC interface */
\f
/*
Extended precision IEEE binary floating point arithmetic routines
/* 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] =
+const UEMUSHORT ezero[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};
-extern unsigned EMUSHORT ezero[];
/* 5.0E-1 */
-unsigned EMUSHORT ehalf[NE] =
+const UEMUSHORT ehalf[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3ffe,};
-extern unsigned EMUSHORT ehalf[];
/* 1.0E0 */
-unsigned EMUSHORT eone[NE] =
+const UEMUSHORT eone[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};
-extern unsigned EMUSHORT eone[];
/* 2.0E0 */
-unsigned EMUSHORT etwo[NE] =
+const UEMUSHORT etwo[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000,};
-extern unsigned EMUSHORT etwo[];
/* 3.2E1 */
-unsigned EMUSHORT e32[NE] =
+const UEMUSHORT e32[NE] =
{0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4004,};
-extern unsigned EMUSHORT e32[];
/* 6.93147180559945309417232121458176568075500134360255E-1 */
-unsigned EMUSHORT elog2[NE] =
+const UEMUSHORT elog2[NE] =
{0x40f3, 0xf6af, 0x03f2, 0xb398,
0xc9e3, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};
-extern unsigned EMUSHORT elog2[];
/* 1.41421356237309504880168872420969807856967187537695E0 */
-unsigned EMUSHORT esqrt2[NE] =
+const UEMUSHORT esqrt2[NE] =
{0x1d6f, 0xbe9f, 0x754a, 0x89b3,
0x597d, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};
-extern unsigned EMUSHORT esqrt2[];
/* 3.14159265358979323846264338327950288419716939937511E0 */
-unsigned EMUSHORT epi[NE] =
+const UEMUSHORT epi[NE] =
{0x2902, 0x1cd1, 0x80dc, 0x628b,
0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};
-extern unsigned EMUSHORT epi[];
#else
/* LONG_DOUBLE_TYPE_SIZE is other than 128 */
-unsigned EMUSHORT ezero[NE] =
+const UEMUSHORT ezero[NE] =
{0, 0000000, 0000000, 0000000, 0000000, 0000000,};
-unsigned EMUSHORT ehalf[NE] =
+const UEMUSHORT ehalf[NE] =
{0, 0000000, 0000000, 0000000, 0100000, 0x3ffe,};
-unsigned EMUSHORT eone[NE] =
+const UEMUSHORT eone[NE] =
{0, 0000000, 0000000, 0000000, 0100000, 0x3fff,};
-unsigned EMUSHORT etwo[NE] =
+const UEMUSHORT etwo[NE] =
{0, 0000000, 0000000, 0000000, 0100000, 0040000,};
-unsigned EMUSHORT e32[NE] =
+const UEMUSHORT e32[NE] =
{0, 0000000, 0000000, 0000000, 0100000, 0040004,};
-unsigned EMUSHORT elog2[NE] =
+const UEMUSHORT elog2[NE] =
{0xc9e4, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};
-unsigned EMUSHORT esqrt2[NE] =
+const UEMUSHORT esqrt2[NE] =
{0x597e, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};
-unsigned EMUSHORT epi[NE] =
+const UEMUSHORT epi[NE] =
{0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};
#endif
static void
eclear (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
- register int i;
+ int i;
for (i = 0; i < NE; i++)
*x++ = 0;
static void
emov (a, b)
- register unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a;
+ UEMUSHORT *b;
{
- register int i;
+ int i;
for (i = 0; i < NE; i++)
*b++ = *a++;
static void
eabs (x)
- unsigned EMUSHORT x[];
+ UEMUSHORT x[];
{
/* sign is top bit of last word of external format */
x[NE - 1] &= 0x7fff;
static void
eneg (x)
- unsigned EMUSHORT x[];
+ UEMUSHORT x[];
{
x[NE - 1] ^= 0x8000; /* Toggle the sign bit */
static int
eisneg (x)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
{
if (x[NE - 1] & 0x8000)
static int
eisinf (x)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
{
#ifdef NANS
static int
eisnan (x)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[] ATTRIBUTE_UNUSED;
{
#ifdef NANS
int i;
for (i = 0; i < NE - 1; i++)
{
if (*x++ != 0)
- return (1);
+ return (1);
}
#endif
static void
einfin (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
- register int i;
+ int i;
#ifdef INFINITY
for (i = 0; i < NE - 1; 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;
+ UEMUSHORT *x;
int sign;
{
- register int i;
+ int i;
for (i = 0; i < NE - 2; i++)
*x++ = 0;
*x++ = 0xc000;
*x = (sign << 15) | 0x7fff;
}
+#endif /* NANS */
/* Move in an e-type number A, converting it to exploded e-type B. */
static void
emovi (a, b)
- unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a;
+ UEMUSHORT *b;
{
- register unsigned EMUSHORT *p, *q;
+ const UEMUSHORT *p;
+ UEMUSHORT *q;
int i;
q = b;
static void
emovo (a, b)
- unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a;
+ UEMUSHORT *b;
{
- register unsigned EMUSHORT *p, *q;
- unsigned EMUSHORT i;
+ const UEMUSHORT *p;
+ UEMUSHORT *q;
+ UEMUSHORT i;
int j;
p = a;
static void
ecleaz (xi)
- register unsigned EMUSHORT *xi;
+ UEMUSHORT *xi;
{
- register int i;
+ int i;
for (i = 0; i < NI; i++)
*xi++ = 0;
static void
ecleazs (xi)
- register unsigned EMUSHORT *xi;
+ UEMUSHORT *xi;
{
- register int i;
+ int i;
++xi;
for (i = 0; i < NI - 1; i++)
static void
emovz (a, b)
- register unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a;
+ UEMUSHORT *b;
{
- register int i;
+ int i;
for (i = 0; i < NI - 1; i++)
*b++ = *a++;
The explicit pattern for this is maximum exponent and
top two significant bits set. */
+#ifdef NANS
static void
einan (x)
- unsigned EMUSHORT x[];
+ UEMUSHORT x[];
{
ecleaz (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[];
+ const UEMUSHORT x[];
{
int i;
}
return (0);
}
+#endif /* NANS */
/* Return nonzero if sign of exploded e-type X is nonzero. */
static int
eiisneg (x)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
{
return x[0] != 0;
static void
eiinfin (x)
- unsigned EMUSHORT x[];
+ UEMUSHORT x[];
{
ecleaz (x);
/* Return nonzero if exploded e-type X is infinite. */
+#ifdef INFINITY
static int
eiisinf (x)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
{
#ifdef NANS
return (1);
return (0);
}
-
+#endif /* INFINITY */
/* Compare significands of numbers in internal exploded e-type format.
Guard words are included in the comparison.
static int
ecmpm (a, b)
- register unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a, *b;
{
int i;
static void
eshdn1 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
- register unsigned EMUSHORT bits;
+ UEMUSHORT bits;
int i;
x += M; /* point to significand area */
static void
eshup1 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
- register unsigned EMUSHORT bits;
+ UEMUSHORT bits;
int i;
x += NI - 1;
static void
eshdn8 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
- register unsigned EMUSHORT newbyt, oldbyt;
+ UEMUSHORT newbyt, oldbyt;
int i;
x += M;
static void
eshup8 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
int i;
- register unsigned EMUSHORT newbyt, oldbyt;
+ UEMUSHORT newbyt, oldbyt;
x += NI - 1;
oldbyt = 0;
static void
eshup6 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
int i;
- register unsigned EMUSHORT *p;
+ UEMUSHORT *p;
p = x + M;
x += M + 1;
static void
eshdn6 (x)
- register unsigned EMUSHORT *x;
+ UEMUSHORT *x;
{
int i;
- register unsigned EMUSHORT *p;
+ UEMUSHORT *p;
x += NI - 1;
p = x + 1;
static void
eaddm (x, y)
- unsigned EMUSHORT *x, *y;
+ const UEMUSHORT *x;
+ UEMUSHORT *y;
{
- register unsigned EMULONG a;
+ unsigned EMULONG a;
int i;
unsigned int carry;
carry = 1;
else
carry = 0;
- *y = (unsigned EMUSHORT) a;
+ *y = (UEMUSHORT) a;
--x;
--y;
}
static void
esubm (x, y)
- unsigned EMUSHORT *x, *y;
+ const UEMUSHORT *x;
+ UEMUSHORT *y;
{
unsigned EMULONG a;
int i;
carry = 1;
else
carry = 0;
- *y = (unsigned EMUSHORT) a;
+ *y = (UEMUSHORT) a;
--x;
--y;
}
}
-static unsigned EMUSHORT equot[NI];
+static UEMUSHORT equot[NI];
#if 0
int
edivm (den, num)
- unsigned EMUSHORT den[], num[];
+ UEMUSHORT den[], num[];
{
int i;
- register unsigned EMUSHORT *p, *q;
- unsigned EMUSHORT j;
+ UEMUSHORT *p, *q;
+ UEMUSHORT j;
p = &equot[0];
*p++ = num[0];
int
emulm (a, b)
- unsigned EMUSHORT a[], b[];
+ UEMUSHORT a[], b[];
{
- unsigned EMUSHORT *p, *q;
+ UEMUSHORT *p, *q;
int i, j, k;
equot[0] = b[0];
static void
m16m (a, b, c)
unsigned int a;
- unsigned EMUSHORT b[], c[];
+ const UEMUSHORT b[];
+ UEMUSHORT c[];
{
- register unsigned EMUSHORT *pp;
- register unsigned EMULONG carry;
- unsigned EMUSHORT *ps;
- unsigned EMUSHORT p[NI];
+ UEMUSHORT *pp;
+ unsigned EMULONG carry;
+ const UEMUSHORT *ps;
+ UEMUSHORT p[NI];
unsigned EMULONG aa, m;
int i;
{
m = (unsigned EMULONG) aa * *ps--;
carry = (m & 0xffff) + *pp;
- *pp-- = (unsigned EMUSHORT)carry;
+ *pp-- = (UEMUSHORT) carry;
carry = (carry >> 16) + (m >> 16) + *pp;
- *pp = (unsigned EMUSHORT)carry;
+ *pp = (UEMUSHORT) carry;
*(pp-1) = carry >> 16;
}
}
static int
edivm (den, num)
- unsigned EMUSHORT den[], num[];
+ const UEMUSHORT den[];
+ UEMUSHORT num[];
{
int i;
- register unsigned EMUSHORT *p;
+ UEMUSHORT *p;
unsigned EMULONG tnum;
- unsigned EMUSHORT j, tdenm, tquot;
- unsigned EMUSHORT tprod[NI+1];
+ UEMUSHORT j, tdenm, tquot;
+ UEMUSHORT tprod[NI+1];
p = &equot[0];
*p++ = num[0];
tnum = (((unsigned EMULONG) num[M]) << 16) + num[M+1];
/* Do not execute the divide instruction if it will overflow. */
- if ((tdenm * (unsigned long)0xffff) < tnum)
+ if ((tdenm * (unsigned long) 0xffff) < tnum)
tquot = 0xffff;
else
tquot = tnum / tdenm;
/* Multiply denominator by trial quotient digit. */
- m16m ((unsigned int)tquot, den, tprod);
+ m16m ((unsigned int) tquot, den, tprod);
/* The quotient digit may have been overestimated. */
if (ecmpm (tprod, num) > 0)
{
}
esubm (tprod, num);
equot[i] = tquot;
- eshup6(num);
+ eshup6 (num);
}
/* test for nonzero remainder after roundoff bit */
p = &num[M];
for (i=0; i<NI; i++)
num[i] = equot[i];
- return ((int)j);
+ return ((int) j);
}
/* Multiply significands of exploded e-type A and B, result in B. */
static int
emulm (a, b)
- unsigned EMUSHORT a[], b[];
+ const UEMUSHORT a[];
+ UEMUSHORT b[];
{
- unsigned EMUSHORT *p, *q;
- unsigned EMUSHORT pprod[NI];
- unsigned EMUSHORT j;
+ const UEMUSHORT *p;
+ UEMUSHORT *q;
+ UEMUSHORT pprod[NI];
+ UEMUSHORT j;
int i;
equot[0] = b[0];
else
{
m16m ((unsigned int) *p--, b, pprod);
- eaddm(pprod, equot);
+ eaddm (pprod, equot);
}
j |= *q;
- eshdn6(equot);
+ eshdn6 (equot);
}
for (i=0; i<NI; i++)
b[i] = equot[i];
/* return flag for lost nonzero bits */
- return ((int)j);
+ return ((int) j);
}
#endif
Data types having standard 15-bit exponents are not affected by
this, but SFmode and DFmode are affected. For example, ediv with
rndprc = 24 will not round correctly to 24-bit precision if the
- result is denormal. */
+ result is denormal. */
static int rlast = -1;
static int rw = 0;
-static unsigned EMUSHORT rmsk = 0;
-static unsigned EMUSHORT rmbit = 0;
-static unsigned EMUSHORT rebit = 0;
+static UEMUSHORT rmsk = 0;
+static UEMUSHORT rmbit = 0;
+static UEMUSHORT rebit = 0;
static int re = 0;
-static unsigned EMUSHORT rbit[NI];
+static UEMUSHORT rbit[NI];
static void
emdnorm (s, lost, subflg, exp, rcntrl)
- unsigned EMUSHORT s[];
+ UEMUSHORT s[];
int lost;
int subflg;
EMULONG exp;
int rcntrl;
{
int i, j;
- unsigned EMUSHORT r;
+ UEMUSHORT r;
/* Normalize */
j = enormlz (s);
if (exp < 0)
s[1] = 0;
else
- s[1] = (unsigned EMUSHORT) exp;
+ s[1] = (UEMUSHORT) exp;
}
/* Subtract. C = B - A, all e type numbers. */
static void
esub (a, b, c)
- unsigned EMUSHORT *a, *b, *c;
+ const UEMUSHORT *a, *b;
+ UEMUSHORT *c;
{
#ifdef NANS
static void
eadd (a, b, c)
- unsigned EMUSHORT *a, *b, *c;
+ const UEMUSHORT *a, *b;
+ UEMUSHORT *c;
{
#ifdef NANS
static void
eadd1 (a, b, c)
- unsigned EMUSHORT *a, *b, *c;
+ const UEMUSHORT *a, *b;
+ UEMUSHORT *c;
{
- unsigned EMUSHORT ai[NI], bi[NI], ci[NI];
+ UEMUSHORT ai[NI], bi[NI], ci[NI];
int i, lost, j, k;
EMULONG lt, lta, ltb;
break;
}
}
- bi[E] = (unsigned EMUSHORT) ltb;
+ bi[E] = (UEMUSHORT) ltb;
goto done;
}
if (i > 0)
esubm (ai, bi);
subflg = 1;
}
- emdnorm (bi, lost, subflg, ltb, 64);
+ emdnorm (bi, lost, subflg, ltb, !ROUND_TOWARDS_ZERO);
done:
emovo (bi, c);
static void
ediv (a, b, c)
- unsigned EMUSHORT *a, *b, *c;
+ const UEMUSHORT *a, *b;
+ UEMUSHORT *c;
{
- unsigned EMUSHORT ai[NI], bi[NI];
+ UEMUSHORT ai[NI], bi[NI];
int i, sign;
EMULONG lt, lta, ltb;
/* IEEE says if result is not a NaN, the sign is "-" if and only if
operands have opposite signs -- but flush -0 to 0 later if not IEEE. */
- sign = eisneg(a) ^ eisneg(b);
+ sign = eisneg (a) ^ eisneg (b);
#ifdef NANS
/* Return any NaN input. */
i = edivm (ai, bi);
/* calculate exponent */
lt = ltb - lta + EXONE;
- emdnorm (bi, i, 0, lt, 64);
+ emdnorm (bi, i, 0, lt, !ROUND_TOWARDS_ZERO);
emovo (bi, c);
divsign:
*(c+(NE-1)) &= ~0x8000;
}
-/* Multiply e-types A and B, return e-type product C. */
+/* Multiply e-types A and B, return e-type product C. */
static void
emul (a, b, c)
- unsigned EMUSHORT *a, *b, *c;
+ const UEMUSHORT *a, *b;
+ UEMUSHORT *c;
{
- unsigned EMUSHORT ai[NI], bi[NI];
+ UEMUSHORT ai[NI], bi[NI];
int i, j, sign;
EMULONG lt, lta, ltb;
/* IEEE says if result is not a NaN, the sign is "-" if and only if
operands have opposite signs -- but flush -0 to 0 later if not IEEE. */
- sign = eisneg(a) ^ eisneg(b);
+ sign = eisneg (a) ^ eisneg (b);
#ifdef NANS
/* NaN times anything is the same NaN. */
j = emulm (ai, bi);
/* calculate exponent */
lt = lta + ltb - (EXONE - 1);
- emdnorm (bi, j, 0, lt, 64);
+ emdnorm (bi, j, 0, lt, !ROUND_TOWARDS_ZERO);
emovo (bi, c);
mulsign:
static void
e53toe (pe, y)
- unsigned EMUSHORT *pe, *y;
+ const UEMUSHORT *pe;
+ UEMUSHORT *y;
{
#ifdef DEC
c4xtoe (pe, y, HFmode);
#else
- register unsigned EMUSHORT r;
- register unsigned EMUSHORT *e, *p;
- unsigned EMUSHORT yy[NI];
+ UEMUSHORT r;
+ const UEMUSHORT *e;
+ UEMUSHORT *p;
+ UEMUSHORT yy[NI];
int denorm, k;
e = pe;
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
- yy[E] -= (unsigned EMUSHORT) (k - 1);
+ yy[E] -= (UEMUSHORT) (k - 1);
}
emovo (yy, y);
#endif /* not C4X */
static void
e64toe (pe, y)
- unsigned EMUSHORT *pe, *y;
+ const UEMUSHORT *pe;
+ UEMUSHORT *y;
{
- unsigned EMUSHORT yy[NI];
- unsigned EMUSHORT *e, *p, *q;
+ UEMUSHORT yy[NI];
+ const UEMUSHORT *e;
+ UEMUSHORT *p, *q;
int i;
e = pe;
/* 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. */
- if((yy[NE-1] & 0x7fff) == 0 && (yy[NE-2] & 0x8000) == 0)
+ if ((yy[NE-1] & 0x7fff) == 0 && (yy[NE-2] & 0x8000) == 0)
{
- unsigned EMUSHORT temp[NI];
+ UEMUSHORT temp[NI];
- emovi(yy, temp);
- eshup1(temp);
- emovo(temp,y);
+ emovi (yy, temp);
+ eshup1 (temp);
+ emovo (temp,y);
return;
}
}
*q++ = *p++;
}
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* Convert 128-bit long double precision float PE to e type Y. */
static void
e113toe (pe, y)
- unsigned EMUSHORT *pe, *y;
+ const UEMUSHORT *pe;
+ UEMUSHORT *y;
{
- register unsigned EMUSHORT r;
- unsigned EMUSHORT *e, *p;
- unsigned EMUSHORT yy[NI];
+ UEMUSHORT r;
+ const UEMUSHORT *e;
+ UEMUSHORT *p;
+ UEMUSHORT yy[NI];
int denorm, i;
e = pe;
}
emovo (yy, y);
}
+#endif
/* Convert single precision float PE to e type Y. */
static void
e24toe (pe, y)
- unsigned EMUSHORT *pe, *y;
+ const UEMUSHORT *pe;
+ UEMUSHORT *y;
{
#ifdef IBM
#else
- register unsigned EMUSHORT r;
- register unsigned EMUSHORT *e, *p;
- unsigned EMUSHORT yy[NI];
+ UEMUSHORT r;
+ const UEMUSHORT *e;
+ UEMUSHORT *p;
+ UEMUSHORT yy[NI];
int denorm, k;
e = pe;
yy[M] = (r & 0x7f) | 0200;
r &= ~0x807f; /* strip sign and 7 significand bits */
#ifdef INFINITY
- if (r == 0x7f80)
+ if (!LARGEST_EXPONENT_IS_NORMAL (32) && r == 0x7f80)
{
#ifdef NANS
if (REAL_WORDS_BIG_ENDIAN)
if ((k = enormlz (yy)) > NBITS)
ecleazs (yy);
else
- yy[E] -= (unsigned EMUSHORT) (k - 1);
+ yy[E] -= (UEMUSHORT) (k - 1);
}
emovo (yy, y);
#endif /* not C4X */
#endif /* not IBM */
}
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
/* Convert e-type X to IEEE 128-bit long double format E. */
static void
etoe113 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 113;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe113 (xi, e);
}
static void
toe113 (a, b)
- unsigned EMUSHORT *a, *b;
+ UEMUSHORT *a, *b;
{
- register unsigned EMUSHORT *p, *q;
- unsigned EMUSHORT i;
+ UEMUSHORT *p, *q;
+ UEMUSHORT i;
#ifdef NANS
if (eiisnan (a))
*q-- = *p++;
}
}
+#endif
/* Convert e-type X to IEEE double extended format E. */
static void
etoe64 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 64;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe64 (xi, e);
}
static void
toe64 (a, b)
- unsigned EMUSHORT *a, *b;
+ UEMUSHORT *a, *b;
{
- register unsigned EMUSHORT *p, *q;
- unsigned EMUSHORT i;
+ UEMUSHORT *p, *q;
+ UEMUSHORT i;
#ifdef NANS
if (eiisnan (a))
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
static void
etoe53 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
etodec (x, e); /* see etodec.c */
}
static void
toe53 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
todec (x, y);
}
static void
etoe53 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
etoibm (x, e, DFmode);
}
static void
toe53 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
toibm (x, y, DFmode);
}
static void
etoe53 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
etoc4x (x, e, HFmode);
}
static void
toe53 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
toc4x (x, y, HFmode);
}
static void
etoe53 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 53;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe53 (xi, e);
}
static void
toe53 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
- unsigned EMUSHORT i;
- unsigned EMUSHORT *p;
+ UEMUSHORT i;
+ UEMUSHORT *p;
#ifdef NANS
if (eiisnan (x))
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++ = 0;
}
#else
- *y |= (unsigned EMUSHORT) 0x7fef;
+ *y |= (UEMUSHORT) 0x7fef;
if (! REAL_WORDS_BIG_ENDIAN)
{
*(--y) = 0xffff;
i <<= 4;
eshift (x, 5);
}
- i |= *p++ & (unsigned EMUSHORT) 0x0f; /* *p = xi[M] */
- *y |= (unsigned EMUSHORT) i; /* high order output already has sign bit set */
+ 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++;
static void
etoe24 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
etoibm (x, e, SFmode);
}
static void
toe24 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
toibm (x, y, SFmode);
}
static void
etoe24 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
etoc4x (x, e, QFmode);
}
static void
toe24 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
toc4x (x, y, QFmode);
}
static void
etoe24 (x, e)
- unsigned EMUSHORT *x, *e;
+ const UEMUSHORT *x;
+ UEMUSHORT *e;
{
EMULONG exp;
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
int rndsav;
#ifdef NANS
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 24;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
+#ifdef INFINITY
nonorm:
+#endif
toe24 (xi, e);
}
static void
toe24 (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
- unsigned EMUSHORT i;
- unsigned EMUSHORT *p;
+ UEMUSHORT i;
+ UEMUSHORT *p;
#ifdef NANS
if (eiisnan (x))
return;
}
#endif
+ if (LARGEST_EXPONENT_IS_NORMAL (32) && x[1] > 255)
+ {
+ saturate (y, eiisneg (x), 32, 1);
+ return;
+ }
p = &x[0];
#ifdef IEEE
if (! REAL_WORDS_BIG_ENDIAN)
i = *p++;
/* Handle overflow cases. */
- if (i >= 255)
+ if (!LARGEST_EXPONENT_IS_NORMAL (32) && i >= 255)
{
#ifdef INFINITY
- *y |= (unsigned EMUSHORT) 0x7f80;
+ *y |= (UEMUSHORT) 0x7f80;
#ifdef DEC
*(--y) = 0;
#endif
}
#endif
#else /* no INFINITY */
- *y |= (unsigned EMUSHORT) 0x7f7f;
+ *y |= (UEMUSHORT) 0x7f7f;
#ifdef DEC
*(--y) = 0xffff;
#endif
i <<= 7;
eshift (x, 8);
}
- i |= *p++ & (unsigned EMUSHORT) 0x7f; /* *p = xi[M] */
+ i |= *p++ & (UEMUSHORT) 0x7f; /* *p = xi[M] */
/* High order output already has sign bit set. */
*y |= i;
#ifdef DEC
static int
ecmp (a, b)
- unsigned EMUSHORT *a, *b;
+ const UEMUSHORT *a, *b;
{
- unsigned EMUSHORT ai[NI], bi[NI];
- register unsigned EMUSHORT *p, *q;
- register int i;
+ UEMUSHORT ai[NI], bi[NI];
+ UEMUSHORT *p, *q;
+ int i;
int msign;
#ifdef NANS
static void
eround (x, y)
- unsigned EMUSHORT *x, *y;
+ const UEMUSHORT *x;
+ UEMUSHORT *y;
{
eadd (ehalf, x, y);
efloor (y, y);
static void
ltoe (lp, y)
- HOST_WIDE_INT *lp;
- unsigned EMUSHORT *y;
+ const HOST_WIDE_INT *lp;
+ UEMUSHORT *y;
{
- unsigned EMUSHORT yi[NI];
+ UEMUSHORT yi[NI];
unsigned HOST_WIDE_INT ll;
int k;
}
/* move the long integer to yi significand area */
#if HOST_BITS_PER_WIDE_INT == 64
- yi[M] = (unsigned EMUSHORT) (ll >> 48);
- yi[M + 1] = (unsigned EMUSHORT) (ll >> 32);
- yi[M + 2] = (unsigned EMUSHORT) (ll >> 16);
- yi[M + 3] = (unsigned EMUSHORT) ll;
+ yi[M] = (UEMUSHORT) (ll >> 48);
+ yi[M + 1] = (UEMUSHORT) (ll >> 32);
+ yi[M + 2] = (UEMUSHORT) (ll >> 16);
+ yi[M + 3] = (UEMUSHORT) ll;
yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
#else
- yi[M] = (unsigned EMUSHORT) (ll >> 16);
- yi[M + 1] = (unsigned EMUSHORT) ll;
+ yi[M] = (UEMUSHORT) (ll >> 16);
+ yi[M + 1] = (UEMUSHORT) ll;
yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */
#endif
if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
ecleaz (yi); /* it was zero */
else
- yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
+ yi[E] -= (UEMUSHORT) k;/* subtract shift count from exponent */
emovo (yi, y); /* output the answer */
}
static void
ultoe (lp, y)
- unsigned HOST_WIDE_INT *lp;
- unsigned EMUSHORT *y;
+ const unsigned HOST_WIDE_INT *lp;
+ UEMUSHORT *y;
{
- unsigned EMUSHORT yi[NI];
+ UEMUSHORT yi[NI];
unsigned HOST_WIDE_INT ll;
int k;
/* move the long integer to ayi significand area */
#if HOST_BITS_PER_WIDE_INT == 64
- yi[M] = (unsigned EMUSHORT) (ll >> 48);
- yi[M + 1] = (unsigned EMUSHORT) (ll >> 32);
- yi[M + 2] = (unsigned EMUSHORT) (ll >> 16);
- yi[M + 3] = (unsigned EMUSHORT) ll;
+ yi[M] = (UEMUSHORT) (ll >> 48);
+ yi[M + 1] = (UEMUSHORT) (ll >> 32);
+ yi[M + 2] = (UEMUSHORT) (ll >> 16);
+ yi[M + 3] = (UEMUSHORT) ll;
yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */
#else
- yi[M] = (unsigned EMUSHORT) (ll >> 16);
- yi[M + 1] = (unsigned EMUSHORT) ll;
+ yi[M] = (UEMUSHORT) (ll >> 16);
+ yi[M + 1] = (UEMUSHORT) ll;
yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */
#endif
if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
ecleaz (yi); /* it was zero */
else
- yi[E] -= (unsigned EMUSHORT) k; /* subtract shift count from exponent */
+ yi[E] -= (UEMUSHORT) k; /* subtract shift count from exponent */
emovo (yi, y); /* output the answer */
}
static void
eifrac (x, i, frac)
- unsigned EMUSHORT *x;
+ const UEMUSHORT *x;
HOST_WIDE_INT *i;
- unsigned EMUSHORT *frac;
+ UEMUSHORT *frac;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
int j, k;
unsigned HOST_WIDE_INT ll;
*i = -(*i);
}
else
- {
- /* shift not more than 16 bits */
- eshift (xi, k);
- *i = (HOST_WIDE_INT) xi[M] & 0xffff;
- if (xi[0])
- *i = -(*i);
- }
+ {
+ /* shift not more than 16 bits */
+ eshift (xi, k);
+ *i = (HOST_WIDE_INT) xi[M] & 0xffff;
+ if (xi[0])
+ *i = -(*i);
+ }
xi[0] = 0;
xi[E] = EXONE - 1;
xi[M] = 0;
if ((k = enormlz (xi)) > NBITS)
ecleaz (xi);
else
- xi[E] -= (unsigned EMUSHORT) k;
+ xi[E] -= (UEMUSHORT) k;
emovo (xi, frac);
}
static void
euifrac (x, i, frac)
- unsigned EMUSHORT *x;
+ const UEMUSHORT *x;
unsigned HOST_WIDE_INT *i;
- unsigned EMUSHORT *frac;
+ UEMUSHORT *frac;
{
unsigned HOST_WIDE_INT ll;
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
int j, k;
emovi (x, xi);
{
/* 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);
if ((k = enormlz (xi)) > NBITS)
ecleaz (xi);
else
- xi[E] -= (unsigned EMUSHORT) k;
+ xi[E] -= (UEMUSHORT) k;
emovo (xi, frac);
}
static int
eshift (x, sc)
- unsigned EMUSHORT *x;
+ UEMUSHORT *x;
int sc;
{
- unsigned EMUSHORT lost;
- unsigned EMUSHORT *p;
+ UEMUSHORT lost;
+ UEMUSHORT *p;
if (sc == 0)
return (0);
static int
enormlz (x)
- unsigned EMUSHORT x[];
+ UEMUSHORT x[];
{
- register unsigned EMUSHORT *p;
+ UEMUSHORT *p;
int sc;
sc = 0;
#define NTEN 12
#define MAXP 4096
-#if LONG_DOUBLE_TYPE_SIZE == 128
-static unsigned EMUSHORT etens[NTEN + 1][NE] =
+#if MAX_LONG_DOUBLE_TYPE_SIZE == 128 && (INTEL_EXTENDED_IEEE_FORMAT == 0)
+static const UEMUSHORT etens[NTEN + 1][NE] =
{
{0x6576, 0x4a92, 0x804a, 0x153f,
0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
};
-static unsigned EMUSHORT emtens[NTEN + 1][NE] =
+static const UEMUSHORT emtens[NTEN + 1][NE] =
{
{0x2030, 0xcffc, 0xa1c3, 0x8123,
0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
};
#else
/* LONG_DOUBLE_TYPE_SIZE is other than 128 */
-static unsigned EMUSHORT etens[NTEN + 1][NE] =
+static const UEMUSHORT etens[NTEN + 1][NE] =
{
{0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */
{0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */
{0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */
};
-static unsigned EMUSHORT emtens[NTEN + 1][NE] =
+static const UEMUSHORT emtens[NTEN + 1][NE] =
{
{0x2de4, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */
{0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */
static void
e24toasc (x, string, ndigs)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
char *string;
int ndigs;
{
- unsigned EMUSHORT w[NI];
+ UEMUSHORT w[NI];
e24toe (x, w);
etoasc (w, string, ndigs);
static void
e53toasc (x, string, ndigs)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
char *string;
int ndigs;
{
- unsigned EMUSHORT w[NI];
+ UEMUSHORT w[NI];
e53toe (x, w);
etoasc (w, string, ndigs);
static void
e64toasc (x, string, ndigs)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
char *string;
int ndigs;
{
- unsigned EMUSHORT w[NI];
+ UEMUSHORT w[NI];
e64toe (x, w);
etoasc (w, string, ndigs);
static void
e113toasc (x, string, ndigs)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
char *string;
int ndigs;
{
- unsigned EMUSHORT w[NI];
+ UEMUSHORT w[NI];
e113toe (x, w);
etoasc (w, string, ndigs);
static void
etoasc (x, string, ndigs)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
char *string;
int ndigs;
{
EMUSHORT digit;
- unsigned EMUSHORT y[NI], t[NI], u[NI], w[NI];
- unsigned EMUSHORT *p, *r, *ten;
- unsigned EMUSHORT sign;
+ UEMUSHORT y[NI], t[NI], u[NI], w[NI];
+ const UEMUSHORT *p, *r, *ten;
+ UEMUSHORT sign;
int i, j, k, expon, rndsav;
char *s, *ss;
- unsigned EMUSHORT m;
+ UEMUSHORT m;
rndsav = rndprc;
}
else
{
- *s++ = (char)digit + '0';
+ *s++ = (char) digit + '0';
*s++ = '.';
}
/* Generate digits after the decimal point. */
/* Round up and propagate carry-outs */
roun:
--s;
- k = *s & 0x7f;
+ k = *s & CHARMASK;
/* Carry out to most significant digit? */
if (k == '.')
{
}
}
doexp:
- /*
- if (expon >= 0)
- sprintf (ss, "e+%d", expon);
- else
- sprintf (ss, "e%d", expon);
- */
+ /* Strip trailing zeros, but leave at least one. */
+ while (ss[-1] == '0' && ss[-2] != '.')
+ --ss;
sprintf (ss, "e%d", expon);
bxit:
rndprc = rndsav;
static void
asctoe24 (s, y)
const char *s;
- unsigned EMUSHORT *y;
+ UEMUSHORT *y;
{
asctoeg (s, y, 24);
}
static void
asctoe53 (s, y)
const char *s;
- unsigned EMUSHORT *y;
+ UEMUSHORT *y;
{
#if defined(DEC) || defined(IBM)
asctoeg (s, y, 56);
static void
asctoe64 (s, y)
const char *s;
- unsigned EMUSHORT *y;
+ UEMUSHORT *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)
const char *s;
- unsigned EMUSHORT *y;
+ UEMUSHORT *y;
{
asctoeg (s, y, 113);
}
+#endif
/* Convert ASCII string S to e type Y. */
static void
asctoe (s, y)
const char *s;
- unsigned EMUSHORT *y;
+ UEMUSHORT *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)
const char *ss;
- unsigned EMUSHORT *y;
+ UEMUSHORT *y;
int oprec;
{
- unsigned EMUSHORT yy[NI], xt[NI], tt[NI];
+ UEMUSHORT 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;
+ UEMUSHORT nsign;
char *sp, *s, *lstr;
int base = 10;
trail = 0;
nxtcom:
- if (*s >= '0' && *s <= '9')
- k = *s - '0';
- else if (*s >= 'a')
- k = 10 + *s - 'a';
- else
- k = 10 + *s - 'A';
+ k = hex_value (*s);
if ((k >= 0) && (k < base))
{
/* Ignore leading zeros */
if ((trail == 0) && (decflg != 0))
{
sp = s;
- while ((*sp >= '0' && *sp <= '9')
- || (base == 16 && ((*sp >= 'a' && *sp <= 'f')
- || (*sp >= 'A' && *sp <= 'F'))))
+ while (ISDIGIT (*sp) || (base == 16 && ISXDIGIT (*sp)))
++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);
}
/* Insert the current digit. */
ecleaz (xt);
- xt[NI - 2] = (unsigned EMUSHORT) k;
+ xt[NI - 2] = (UEMUSHORT) k;
eaddm (xt, yy);
}
else
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)
}
if (*s == '+')
++s;
- while ((*s >= '0') && (*s <= '9'))
+ while (ISDIGIT (*s))
{
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);
case 64:
toe64 (yy, y);
break;
+#if (INTEL_EXTENDED_IEEE_FORMAT == 0)
case 113:
toe113 (yy, y);
break;
+#endif
case NBITS:
emovo (yy, y);
break;
/* Return Y = largest integer not greater than X (truncated toward minus
infinity). */
-static unsigned EMUSHORT bmask[] =
+static const UEMUSHORT bmask[] =
{
0xffff,
0xfffe,
static void
efloor (x, y)
- unsigned EMUSHORT x[], y[];
+ const UEMUSHORT x[];
+ UEMUSHORT y[];
{
- register unsigned EMUSHORT *p;
+ UEMUSHORT *p;
int e, expon, i;
- unsigned EMUSHORT f[NE];
+ UEMUSHORT f[NE];
emov (x, f); /* leave in external format */
expon = (int) f[NE - 1];
/* truncate negatives toward minus infinity */
isitneg:
- if ((unsigned EMUSHORT) expon & (unsigned EMUSHORT) 0x8000)
+ if ((UEMUSHORT) expon & (UEMUSHORT) 0x8000)
{
for (i = 0; i < NE - 1; i++)
{
static void
efrexp (x, exp, s)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
int *exp;
- unsigned EMUSHORT s[];
+ UEMUSHORT s[];
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG li;
emovi (x, xi);
static void
eldexp (x, pwr2, y)
- unsigned EMUSHORT x[];
+ const UEMUSHORT x[];
int pwr2;
- unsigned EMUSHORT y[];
+ UEMUSHORT y[];
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG li;
int i;
li = xi[1];
li += pwr2;
i = 0;
- emdnorm (xi, i, i, li, 64);
+ emdnorm (xi, i, i, li, !ROUND_TOWARDS_ZERO);
emovo (xi, y);
}
static void
eremain (a, b, c)
- unsigned EMUSHORT a[], b[], c[];
+ const UEMUSHORT a[], b[];
+ UEMUSHORT c[];
{
- unsigned EMUSHORT den[NI], num[NI];
+ UEMUSHORT den[NI], num[NI];
#ifdef NANS
if (eisinf (b)
static void
eiremain (den, num)
- unsigned EMUSHORT den[], num[];
+ UEMUSHORT den[], num[];
{
EMULONG ld, ln;
- unsigned EMUSHORT j;
+ UEMUSHORT j;
ld = den[E];
ld -= enormlz (den);
static void
dectoe (d, e)
- unsigned EMUSHORT *d;
- unsigned EMUSHORT *e;
+ const UEMUSHORT *d;
+ UEMUSHORT *e;
{
- unsigned EMUSHORT y[NI];
- register unsigned EMUSHORT r, *p;
+ UEMUSHORT y[NI];
+ UEMUSHORT r, *p;
ecleaz (y); /* start with a zero */
p = y; /* point to our number */
static void
etodec (x, d)
- unsigned EMUSHORT *x, *d;
+ const UEMUSHORT *x;
+ UEMUSHORT *d;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
/* Round off to nearest or even. */
rndsav = rndprc;
rndprc = 56;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
todec (xi, d);
}
static void
todec (x, y)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
{
- unsigned EMUSHORT i;
- unsigned EMUSHORT *p;
+ UEMUSHORT i;
+ UEMUSHORT *p;
p = x;
*y = 0;
static void
ibmtoe (d, e, mode)
- unsigned EMUSHORT *d;
- unsigned EMUSHORT *e;
+ const UEMUSHORT *d;
+ UEMUSHORT *e;
enum machine_mode mode;
{
- unsigned EMUSHORT y[NI];
- register unsigned EMUSHORT r, *p;
- int rndsav;
+ UEMUSHORT y[NI];
+ UEMUSHORT r, *p;
ecleaz (y); /* start with a zero */
p = y; /* point to our number */
static void
etoibm (x, d, mode)
- unsigned EMUSHORT *x, *d;
+ const UEMUSHORT *x;
+ UEMUSHORT *d;
enum machine_mode mode;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
/* round off to nearest or even */
rndsav = rndprc;
rndprc = 56;
- emdnorm (xi, 0, 0, exp, 64);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
toibm (xi, d, mode);
}
static void
toibm (x, y, mode)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
enum machine_mode mode;
{
- unsigned EMUSHORT i;
- unsigned EMUSHORT *p;
+ UEMUSHORT i;
+ UEMUSHORT *p;
int r;
p = x;
static void
c4xtoe (d, e, mode)
- unsigned EMUSHORT *d;
- unsigned EMUSHORT *e;
+ const UEMUSHORT *d;
+ UEMUSHORT *e;
enum machine_mode mode;
{
- unsigned EMUSHORT y[NI];
+ UEMUSHORT y[NI];
+ UEMUSHORT dn[4];
int r;
int isnegative;
int size;
int i;
int carry;
- /* Short-circuit the zero case. */
- if ((d[0] == 0x8000)
- && (d[1] == 0x0000)
- && ((mode == QFmode) || ((d[2] == 0x0000) && (d[3] == 0x0000))))
+ dn[0] = d[0];
+ dn[1] = d[1];
+ if (mode != QFmode)
+ {
+ dn[2] = d[3] << 8;
+ dn[3] = 0;
+ }
+
+ /* Short-circuit the zero case. */
+ if ((dn[0] == 0x8000)
+ && (dn[1] == 0x0000)
+ && ((mode == QFmode) || ((dn[2] == 0x0000) && (dn[3] == 0x0000))))
{
e[0] = 0;
e[1] = 0;
}
ecleaz (y); /* start with a zero */
- r = d[0]; /* get sign/exponent part */
+ r = dn[0]; /* get sign/exponent part */
if (r & (unsigned int) 0x0080)
- {
- y[0] = 0xffff; /* fill in our sign */
- isnegative = TRUE;
- }
+ {
+ y[0] = 0xffff; /* fill in our sign */
+ isnegative = TRUE;
+ }
else
- {
- isnegative = FALSE;
- }
+ isnegative = FALSE;
r >>= 8; /* Shift exponent word down 8 bits. */
- if (r & 0x80) /* Make the exponent negative if it is. */
- {
- r = r | (~0 & ~0xff);
- }
+ if (r & 0x80) /* Make the exponent negative if it is. */
+ r = r | (~0 & ~0xff);
if (isnegative)
- {
- /* Now do the high order mantissa. We don't "or" on the high bit
- because it is 2 (not 1) and is handled a little differently
- below. */
- y[M] = d[0] & 0x7f;
+ {
+ /* Now do the high order mantissa. We don't "or" on the high bit
+ because it is 2 (not 1) and is handled a little differently
+ below. */
+ y[M] = dn[0] & 0x7f;
- y[M+1] = d[1];
- if (mode != QFmode) /* There are only 2 words in QFmode. */
- {
- y[M+2] = d[2]; /* Fill in the rest of our mantissa. */
- y[M+3] = d[3];
- size = 4;
- }
- else
- {
+ y[M+1] = dn[1];
+ if (mode != QFmode) /* There are only 2 words in QFmode. */
+ {
+ y[M+2] = dn[2]; /* Fill in the rest of our mantissa. */
+ y[M+3] = dn[3];
+ size = 4;
+ }
+ else
size = 2;
- }
- eshift(y, -8);
+ eshift (y, -8);
- /* Now do the two's complement on the data. */
+ /* Now do the two's complement on the data. */
- carry = 1; /* Initially add 1 for the two's complement. */
- for (i=size + M; i > M; i--)
- {
- if (carry && (y[i] == 0x0000))
+ carry = 1; /* Initially add 1 for the two's complement. */
+ for (i=size + M; i > M; i--)
{
- /* We overflowed into the next word, carry is the same. */
- y[i] = carry ? 0x0000 : 0xffff;
+ if (carry && (y[i] == 0x0000))
+ /* We overflowed into the next word, carry is the same. */
+ y[i] = carry ? 0x0000 : 0xffff;
+ else
+ {
+ /* No overflow, just invert and add carry. */
+ y[i] = ((~y[i]) + carry) & 0xffff;
+ carry = 0;
+ }
}
- else
+
+ if (carry)
{
- /* No overflow, just invert and add carry. */
- y[i] = ((~y[i]) + carry) & 0xffff;
- carry = 0;
+ eshift (y, -1);
+ y[M+1] |= 0x8000;
+ r++;
}
- }
-
- if (carry)
- {
- eshift(y, -1);
- y[M+1] |= 0x8000;
- r++;
- }
- y[1] = r + EXONE;
- }
+ y[1] = r + EXONE;
+ }
else
- {
- /* Add our e type exponent offset to form our exponent. */
- r += EXONE;
- y[1] = r;
+ {
+ /* Add our e type exponent offset to form our exponent. */
+ r += EXONE;
+ y[1] = r;
/* Now do the high order mantissa strip off the exponent and sign
bits and add the high 1 bit. */
- y[M] = (d[0] & 0x7f) | 0x80;
+ y[M] = (dn[0] & 0x7f) | 0x80;
- y[M+1] = d[1];
+ y[M+1] = dn[1];
if (mode != QFmode) /* There are only 2 words in QFmode. */
- {
- y[M+2] = d[2]; /* Fill in the rest of our mantissa. */
- y[M+3] = d[3];
- }
- eshift(y, -8);
- }
+ {
+ y[M+2] = dn[2]; /* Fill in the rest of our mantissa. */
+ y[M+3] = dn[3];
+ }
+ eshift (y, -8);
+ }
emovo (y, e);
}
static void
etoc4x (x, d, mode)
- unsigned EMUSHORT *x, *d;
+ const UEMUSHORT *x;
+ UEMUSHORT *d;
enum machine_mode mode;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
EMULONG exp;
int rndsav;
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);
+ emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
rndprc = rndsav;
toc4x (xi, d, mode);
}
static void
toc4x (x, y, mode)
- unsigned EMUSHORT *x, *y;
+ UEMUSHORT *x, *y;
enum machine_mode mode;
{
int i;
/* 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++ = 0x0000;
- *y++ = 0x0000;
- }
+ {
+ *y++ = 0x0000;
+ *y++ = 0x0000;
+ }
return;
}
*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
while (v > M)
{
if (x[v] == 0x0000)
- {
- x[v] = carry ? 0x0000 : 0xffff;
- }
+ x[v] = carry ? 0x0000 : 0xffff;
else
{
x[v] = ((~x[v]) + carry) & 0xffff;
/* 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. */
- eshift(x, 1);
+ high sign bit and shift the exponent. */
+ eshift (x, 1);
i--;
}
}
else
- {
- i = ((int) x[1]) - 0x7f;
- }
+ i = ((int) x[1]) - 0x7f;
if ((i < -128) || (i > 127))
{
{
y[2] = 0xffff;
y[3] = 0xffff;
+ y[3] = (y[1] << 8) | ((y[2] >> 8) & 0xff);
+ y[2] = (y[0] << 8) | ((y[1] >> 8) & 0xff);
}
#ifdef ERANGE
errno = ERANGE;
{
y[2] = x[M + 2];
y[3] = x[M + 3];
+ y[3] = (y[1] << 8) | ((y[2] >> 8) & 0xff);
+ y[2] = (y[0] << 8) | ((y[1] >> 8) & 0xff);
}
}
#endif /* C4X */
TFMODE_NAN;
#else
#ifdef IEEE
-unsigned EMUSHORT TFbignan[8] =
+static const UEMUSHORT TFbignan[8] =
{0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
-unsigned EMUSHORT TFlittlenan[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0xffff};
+static const UEMUSHORT TFlittlenan[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0xffff};
#endif
#endif
XFMODE_NAN;
#else
#ifdef IEEE
-unsigned EMUSHORT XFbignan[6] =
+static const UEMUSHORT XFbignan[6] =
{0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
-unsigned EMUSHORT XFlittlenan[6] = {0, 0, 0, 0xc000, 0xffff, 0};
+static const UEMUSHORT XFlittlenan[6] = {0, 0, 0, 0xc000, 0xffff, 0};
#endif
#endif
DFMODE_NAN;
#else
#ifdef IEEE
-unsigned EMUSHORT DFbignan[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
-unsigned EMUSHORT DFlittlenan[4] = {0, 0, 0, 0xfff8};
+static const UEMUSHORT DFbignan[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
+static const UEMUSHORT DFlittlenan[4] = {0, 0, 0, 0xfff8};
#endif
#endif
SFMODE_NAN;
#else
#ifdef IEEE
-unsigned EMUSHORT SFbignan[2] = {0x7fff, 0xffff};
-unsigned EMUSHORT SFlittlenan[2] = {0, 0xffc0};
+static const UEMUSHORT SFbignan[2] = {0x7fff, 0xffff};
+static const UEMUSHORT SFlittlenan[2] = {0, 0xffc0};
#endif
#endif
+#ifdef NANS
static void
make_nan (nan, sign, mode)
- unsigned EMUSHORT *nan;
+ UEMUSHORT *nan;
int sign;
enum machine_mode mode;
{
int n;
- unsigned EMUSHORT *p;
+ const UEMUSHORT *p;
+ int size;
+ size = GET_MODE_BITSIZE (mode);
+ if (LARGEST_EXPONENT_IS_NORMAL (size))
+ {
+ warning ("%d-bit floats cannot hold NaNs", size);
+ saturate (nan, sign, size, 0);
+ return;
+ }
switch (mode)
{
/* Possibly the `reserved operand' patterns on a VAX can be
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 */
+
+
+/* Create a saturation value for a SIZE-bit float, assuming that
+ LARGEST_EXPONENT_IS_NORMAL (SIZE).
+
+ If SIGN is true, fill X with the most negative value, otherwise fill
+ it with the most positive value. WARN is true if the function should
+ warn about overflow. */
+
+static void
+saturate (x, sign, size, warn)
+ UEMUSHORT *x;
+ int sign, size, warn;
+{
+ int i;
+
+ if (warn && extra_warnings)
+ warning ("value exceeds the range of a %d-bit float", size);
+
+ /* Create the most negative value. */
+ for (i = 0; i < size / EMUSHORT_SIZE; i++)
+ x[i] = 0xffff;
+
+ /* Make it positive, if necessary. */
+ if (!sign)
+ x[REAL_WORDS_BIG_ENDIAN? 0 : i - 1] = 0x7fff;
+}
+
/* This is the inverse of the function `etarsingle' invoked by
REAL_VALUE_TO_TARGET_SINGLE. */
long f;
{
REAL_VALUE_TYPE r;
- unsigned EMUSHORT s[2];
- unsigned EMUSHORT e[NE];
+ UEMUSHORT s[2];
+ UEMUSHORT e[NE];
/* Convert 32 bit integer to array of 16 bit pieces in target machine order.
This is the inverse operation to what the function `endian' does. */
if (REAL_WORDS_BIG_ENDIAN)
{
- s[0] = (unsigned EMUSHORT) (f >> 16);
- s[1] = (unsigned EMUSHORT) f;
+ s[0] = (UEMUSHORT) (f >> 16);
+ s[1] = (UEMUSHORT) f;
}
else
{
- s[0] = (unsigned EMUSHORT) f;
- s[1] = (unsigned EMUSHORT) (f >> 16);
+ s[0] = (UEMUSHORT) f;
+ s[1] = (UEMUSHORT) (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;
}
long d[];
{
REAL_VALUE_TYPE r;
- unsigned EMUSHORT s[4];
- unsigned EMUSHORT e[NE];
+ UEMUSHORT s[4];
+ UEMUSHORT e[NE];
/* Convert array of HOST_WIDE_INT to equivalent array of 16-bit pieces. */
if (REAL_WORDS_BIG_ENDIAN)
{
- s[0] = (unsigned EMUSHORT) (d[0] >> 16);
- s[1] = (unsigned EMUSHORT) d[0];
- s[2] = (unsigned EMUSHORT) (d[1] >> 16);
- s[3] = (unsigned EMUSHORT) d[1];
+ s[0] = (UEMUSHORT) (d[0] >> 16);
+ s[1] = (UEMUSHORT) d[0];
+ s[2] = (UEMUSHORT) (d[1] >> 16);
+ s[3] = (UEMUSHORT) d[1];
}
else
{
/* Target float words are little-endian. */
- s[0] = (unsigned EMUSHORT) d[0];
- s[1] = (unsigned EMUSHORT) (d[0] >> 16);
- s[2] = (unsigned EMUSHORT) d[1];
- s[3] = (unsigned EMUSHORT) (d[1] >> 16);
+ s[0] = (UEMUSHORT) d[0];
+ s[1] = (UEMUSHORT) (d[0] >> 16);
+ s[2] = (UEMUSHORT) d[1];
+ s[3] = (UEMUSHORT) (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;
}
HOST_WIDE_INT f;
{
REAL_VALUE_TYPE r;
- unsigned EMUSHORT s[2];
- unsigned EMUSHORT e[NE];
+ UEMUSHORT s[2];
+ UEMUSHORT e[NE];
/* Convert 32 bit integer to array of 16 bit pieces in target machine order.
This is the inverse operation to what the function `endian' does. */
if (REAL_WORDS_BIG_ENDIAN)
{
- s[0] = (unsigned EMUSHORT) (f >> 16);
- s[1] = (unsigned EMUSHORT) f;
+ s[0] = (UEMUSHORT) (f >> 16);
+ s[1] = (UEMUSHORT) f;
}
else
{
- s[0] = (unsigned EMUSHORT) f;
- s[1] = (unsigned EMUSHORT) (f >> 16);
+ s[0] = (UEMUSHORT) f;
+ s[1] = (UEMUSHORT) (f >> 16);
}
/* Convert and promote the target float to E-type. */
e24toe (s, e);
HOST_WIDE_INT d[];
{
REAL_VALUE_TYPE r;
- unsigned EMUSHORT s[4];
- unsigned EMUSHORT e[NE];
+ UEMUSHORT s[4];
+ UEMUSHORT e[NE];
/* 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];
- s[2] = (unsigned EMUSHORT) (d[1] >> 16);
- s[3] = (unsigned EMUSHORT) d[1];
+ s[0] = (UEMUSHORT) (d[0] >> 16);
+ s[1] = (UEMUSHORT) d[0];
+ s[2] = (UEMUSHORT) (d[1] >> 16);
+ s[3] = (UEMUSHORT) 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[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];
+ s[0] = (UEMUSHORT) (d[0] >> 48);
+ s[1] = (UEMUSHORT) (d[0] >> 32);
+ s[2] = (UEMUSHORT) (d[0] >> 16);
+ s[3] = (UEMUSHORT) d[0];
#endif
}
else
{
/* Target float words are little-endian. */
- s[0] = (unsigned EMUSHORT) d[0];
- s[1] = (unsigned EMUSHORT) (d[0] >> 16);
+ s[0] = (UEMUSHORT) d[0];
+ s[1] = (UEMUSHORT) (d[0] >> 16);
#if HOST_BITS_PER_WIDE_INT == 32
- s[2] = (unsigned EMUSHORT) d[1];
- s[3] = (unsigned EMUSHORT) (d[1] >> 16);
+ s[2] = (UEMUSHORT) d[1];
+ s[3] = (UEMUSHORT) (d[1] >> 16);
#else
- s[2] = (unsigned EMUSHORT) (d[0] >> 32);
- s[3] = (unsigned EMUSHORT) (d[0] >> 48);
+ s[2] = (UEMUSHORT) (d[0] >> 32);
+ s[3] = (UEMUSHORT) (d[0] >> 48);
#endif
}
/* Convert target double to E-type. */
static void
uditoe (di, e)
- unsigned EMUSHORT *di; /* Address of the 64-bit int. */
- unsigned EMUSHORT *e;
+ const UEMUSHORT *di; /* Address of the 64-bit int. */
+ UEMUSHORT *e;
{
- unsigned EMUSHORT yi[NI];
+ UEMUSHORT yi[NI];
int k;
ecleaz (yi);
if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
ecleaz (yi); /* it was zero */
else
- yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
+ yi[E] -= (UEMUSHORT) k;/* subtract shift count from exponent */
emovo (yi, e);
}
static void
ditoe (di, e)
- unsigned EMUSHORT *di; /* Address of the 64-bit int. */
- unsigned EMUSHORT *e;
+ const UEMUSHORT *di; /* Address of the 64-bit int. */
+ UEMUSHORT *e;
{
unsigned EMULONG acc;
- unsigned EMUSHORT yi[NI];
- unsigned EMUSHORT carry;
+ UEMUSHORT yi[NI];
+ UEMUSHORT carry;
int k, sign;
ecleaz (yi);
if ((k = enormlz (yi)) > NBITS)/* normalize the significand */
ecleaz (yi); /* it was zero */
else
- yi[E] -= (unsigned EMUSHORT) k;/* subtract shift count from exponent */
+ yi[E] -= (UEMUSHORT) k;/* subtract shift count from exponent */
emovo (yi, e);
if (sign)
eneg (e);
static void
etoudi (x, i)
- unsigned EMUSHORT *x;
- unsigned EMUSHORT *i;
+ const UEMUSHORT *x;
+ UEMUSHORT *i;
{
- unsigned EMUSHORT xi[NI];
+ UEMUSHORT xi[NI];
int j, k;
emovi (x, xi);
}
else
{
- /* shift not more than 16 bits */
+ /* shift not more than 16 bits */
eshift (xi, k);
noshift:
static void
etodi (x, i)
- unsigned EMUSHORT *x;
- unsigned EMUSHORT *i;
+ const UEMUSHORT *x;
+ UEMUSHORT *i;
{
unsigned EMULONG acc;
- unsigned EMUSHORT xi[NI];
- unsigned EMUSHORT carry;
- unsigned EMUSHORT *isave;
+ UEMUSHORT xi[NI];
+ UEMUSHORT carry;
+ UEMUSHORT *isave;
int j, k;
emovi (x, xi);
}
else
{
- /* shift not more than 16 bits */
+ /* shift not more than 16 bits */
eshift (xi, k);
if (WORDS_BIG_ENDIAN)
static void
esqrt (x, y)
- unsigned EMUSHORT *x, *y;
+ const UEMUSHORT *x;
+ UEMUSHORT *y;
{
- unsigned EMUSHORT temp[NI], num[NI], sq[NI], xx[NI];
+ UEMUSHORT temp[NI], num[NI], sq[NI], xx[NI];
EMULONG m, exp;
int i, j, k, n, nlups;
k |= (int) num[i];
/* Renormalize and round off. */
- emdnorm (sq, k, 0, exp, 64);
+ emdnorm (sq, k, 0, exp, !ROUND_TOWARDS_ZERO);
emovo (sq, y);
}
#endif
-#endif /* EMU_NON_COMPILE not defined */
\f
/* Return the binary precision of the significand for a given
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 ();