-/* 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).
-
-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 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
-test programs available. A special version of the PARANOIA floating
-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. */
-\f
-/* Type of computer arithmetic.
- Only one of DEC, IBM, IEEE, C4X, or UNK should get defined.
-
- `IEEE', when REAL_WORDS_BIG_ENDIAN is non-zero, refers generically
- to big-endian IEEE floating-point data structure. This definition
- should work in SFmode `float' type and DFmode `double' type on
- virtually all big-endian IEEE machines. If LONG_DOUBLE_TYPE_SIZE
- has been defined to be 96, then IEEE also invokes the particular
- XFmode (`long double' type) data structure used by the Motorola
- 680x0 series processors.
-
- `IEEE', when REAL_WORDS_BIG_ENDIAN is zero, refers generally to
- little-endian IEEE machines. In this case, if LONG_DOUBLE_TYPE_SIZE
- has been defined to be 96, then IEEE also invokes the particular
- XFmode `long double' data structure used by the Intel 80x86 series
- processors.
-
- `DEC' refers specifically to the Digital Equipment Corp PDP-11
- and VAX floating point data structure. This model currently
- supports no type wider than DFmode.
-
- `IBM' refers specifically to the IBM System/370 and compatible
- floating point data structure. This model currently supports
- no type wider than DFmode. The IBM conversions were contributed by
- frank@atom.ansto.gov.au (Frank Crawford).
-
- `C4X' refers specifically to the floating point format used on
- Texas Instruments TMS320C3x and TMS320C4x digital signal
- processors. This supports QFmode (32-bit float, double) and HFmode
- (40-bit long double) where BITS_PER_BYTE is 32. Unlike IEEE
- floats, C4x floats are not rounded to be even. The C4x conversions
- were contributed by m.hayes@elec.canterbury.ac.nz (Michael Hayes) and
- Haj.Ten.Brugge@net.HCC.nl (Herman ten Brugge).
-
- 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.
-
- The case LONG_DOUBLE_TYPE_SIZE = 128 activates TFmode support
- and may deactivate XFmode since `long double' is used to refer
- 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>,
- separate the floating point unit's endian-ness from that of
- the integer addressing. This permits one to define a big-endian
- FPU on a little-endian machine (e.g., ARM). An extension to
- BYTES_BIG_ENDIAN may be required for some machines in the future.
- 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. */
-
-
-/* The following converts gcc macros into the ones used by this file. */
-
-#if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
-/* PDP-11, Pro350, VAX: */
-#define DEC 1
-#else /* it's not VAX */
-#if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
-/* IBM System/370 style */
-#define IBM 1
-#else /* it's also not an IBM */
-#if TARGET_FLOAT_FORMAT == C4X_FLOAT_FORMAT
-/* TMS320C3x/C4x style */
-#define C4X 1
-#else /* it's also not a C4X */
-#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
-#define IEEE
-#else /* it's not IEEE either */
-/* UNKnown arithmetic. We don't support this and can't go on. */
-unknown arithmetic type
-#define UNK 1
-#endif /* not IEEE */
-#endif /* not C4X */
-#endif /* not IBM */
-#endif /* not VAX */
-
-#define REAL_WORDS_BIG_ENDIAN FLOAT_WORDS_BIG_ENDIAN
-
-/* Make sure that the endianness is correct for IBM and DEC. */
-#if defined(DEC)
-#undef LARGEST_EXPONENT_IS_NORMAL
-#define LARGEST_EXPONENT_IS_NORMAL(x) 1
-#undef REAL_WORDS_BIG_ENDIAN
-/* Strangely enough, DEC float most closely resembles big endian IEEE */
-#define REAL_WORDS_BIG_ENDIAN 1
-/* ... but the halfwords are reversed from IEEE big endian. */
-#ifndef VAX_HALFWORD_ORDER
-#define VAX_HALFWORD_ORDER 1
-#endif
-#else
-#if defined(IBM) && !REAL_WORDS_BIG_ENDIAN
- #error "Little-endian representations are not supported for IBM."
-#endif
-#endif
-
-#if defined(DEC) && !defined (TARGET_G_FLOAT)
-#define TARGET_G_FLOAT 0
-#endif
-
-#ifndef VAX_HALFWORD_ORDER
-#define VAX_HALFWORD_ORDER 0
-#endif
-
-/* Define INFINITY for support of infinity.
- Define NANS for support of Not-a-Number's (NaN's). */
-#if !defined(DEC) && !defined(IBM) && !defined(C4X)
-#define INFINITY
-#define NANS
-#endif
-
-/* Support of NaNs requires support of infinity. */
-#ifdef NANS
-#ifndef INFINITY
-#define INFINITY
-#endif
-#endif
-\f
-/* Find a host integer type that is at least 16 bits wide,
- and another type at least twice whatever that size is. */
-
-#if HOST_BITS_PER_CHAR >= 16
-#define EMUSHORT char
-#define EMUSHORT_SIZE HOST_BITS_PER_CHAR
-#define EMULONG_SIZE (2 * HOST_BITS_PER_CHAR)
-#else
-#if HOST_BITS_PER_SHORT >= 16
-#define EMUSHORT short
-#define EMUSHORT_SIZE HOST_BITS_PER_SHORT
-#define EMULONG_SIZE (2 * HOST_BITS_PER_SHORT)
-#else
-#if HOST_BITS_PER_INT >= 16
-#define EMUSHORT int
-#define EMUSHORT_SIZE HOST_BITS_PER_INT
-#define EMULONG_SIZE (2 * HOST_BITS_PER_INT)
-#else
-#if HOST_BITS_PER_LONG >= 16
-#define EMUSHORT long
-#define EMUSHORT_SIZE HOST_BITS_PER_LONG
-#define EMULONG_SIZE (2 * HOST_BITS_PER_LONG)
-#else
- #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_INT >= EMULONG_SIZE
-#define EMULONG int
-#else
-#if HOST_BITS_PER_LONG >= EMULONG_SIZE
-#define EMULONG long
-#else
-#if HOST_BITS_PER_LONGLONG >= EMULONG_SIZE
-#define EMULONG long long int
-#else
- #error "You will have to modify this program to have a smaller unit size."
-#endif
-#endif
-#endif
-#endif
-
-#if EMUSHORT_SIZE != 16
- #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. */
-#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)
-
-/* Array offset to exponent */
-#define E 1
-
-/* Array offset to high guard word */
-#define M 2
-
-/* Number of bits of precision */
-#define NBITS ((NI-4)*16)
-
-/* Maximum number of decimal digits in ASCII conversion
- * = NBITS*log10(2)
- */
-#define NDEC (NBITS*8/27)
-
-/* 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
-
-/* Information about the various IEEE precisions. At the moment, we only
- support exponents of 15 bits or less. */
-struct ieee_format
-{
- /* Precision. */
- int precision;
-
- /* Size of the exponent in bits. */
- int expbits;
-
- /* Overall size of the value in bits. */
- int bits;
-
- /* Mode used for representing the value. */
- enum machine_mode mode;
-
- /* Exponent adjustment for offsets. */
- EMULONG adjustment;
-};
-
-#ifdef IEEE
-/* IEEE float (24 bits). */
-static const struct ieee_format ieee_24 =
-{
- 24,
- 8,
- 32,
- SFmode,
- EXONE - 0x7f
-};
-
-/* IEEE double (53 bits). */
-static const struct ieee_format ieee_53 =
-{
- 53,
- 11,
- 64,
- DFmode,
- EXONE - 0x3ff
-};
-
-/* IEEE extended double (64 bits). */
-static const struct ieee_format ieee_64 =
-{
- 64,
- 15,
- 80,
- XFmode,
- 0
-};
-
-/* IEEE long double (113 bits). */
-static const struct ieee_format ieee_113 =
-{
- 113,
- 15,
- 128,
- TFmode,
- 0
-};
-#endif
-
-#ifdef DEC
-/* DEC F float (24 bits). */
-static const struct ieee_format dec_f =
-{
- 24,
- 8,
- 32,
- SFmode,
- EXONE - 0201
-};
-
-/* DEC D float (56 bits). */
-static const struct ieee_format dec_d =
-{
- 56,
- 8,
- 64,
- DFmode,
- EXONE - 0201
-};
-
-/* DEC G float (53 bits). */
-static const struct ieee_format dec_g =
-{
- 53,
- 11,
- 64,
- DFmode,
- EXONE - 1025
-};
-
-/* DEC H float (113 bits). (not yet used) */
-static const struct ieee_format dec_h =
-{
- 113,
- 15,
- 128,
- TFmode,
- EXONE - 16385
-};
-#endif
-
-extern int extra_warnings;
-extern const UEMUSHORT ezero[NE], ehalf[NE], eone[NE], etwo[NE];
-extern const UEMUSHORT elog2[NE], esqrt2[NE];
-
-static void endian PARAMS ((const UEMUSHORT *, long *,
- enum machine_mode));
-static void eclear PARAMS ((UEMUSHORT *));
-static void emov PARAMS ((const UEMUSHORT *, UEMUSHORT *));
-#if 0
-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 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 void ieeetoe PARAMS ((const UEMUSHORT *, UEMUSHORT *,
- const struct ieee_format *));
-static void etoieee PARAMS ((const UEMUSHORT *, UEMUSHORT *,
- const struct ieee_format *));
-static void toieee PARAMS ((UEMUSHORT *, UEMUSHORT *,
- const struct ieee_format *));
-static int ecmp PARAMS ((const UEMUSHORT *, const UEMUSHORT *));
-#if 0
-static void eround PARAMS ((const UEMUSHORT *, UEMUSHORT *));
-#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 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 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 PARAMS ((const UEMUSHORT *, int *,
- UEMUSHORT *));
-#endif
-static void eldexp PARAMS ((const UEMUSHORT *, int, UEMUSHORT *));
-#if 0
-static void eremain PARAMS ((const UEMUSHORT *, const UEMUSHORT *,
- UEMUSHORT *));
-#endif
-static void eiremain PARAMS ((UEMUSHORT *, UEMUSHORT *));
-static void mtherr PARAMS ((const char *, int));
-#ifdef DEC
-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 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 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 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
+/* The floating point model used internally is not exactly IEEE 754
+ compliant, and close to the description in the ISO C99 standard,
+ section 5.2.4.2.2 Characteristics of floating types.
+
+ Specifically
+
+ x = s * b^e * \sum_{k=1}^p f_k * b^{-k}
+
+ where
+ s = sign (+- 1)
+ b = base or radix, here always 2
+ e = exponent
+ p = precision (the number of base-b digits in the significand)
+ f_k = the digits of the significand.
+
+ We differ from typical IEEE 754 encodings in that the entire
+ significand is fractional. Normalized significands are in the
+ range [0.5, 1.0).
+
+ A requirement of the model is that P be larger than the largest
+ supported target floating-point type by at least 2 bits. This gives
+ us proper rounding when we truncate to the target type. In addition,
+ E must be large enough to hold the smallest supported denormal number
+ in a normalized form.
+
+ Both of these requirements are easily satisfied. The largest target
+ significand is 113 bits; we store at least 160. The smallest
+ denormal number fits in 17 exponent bits; we store 27.
+
+ Note that the decimal string conversion routines are sensitive to
+ rounding errors. Since the raw arithmetic routines do not themselves
+ have guard digits or rounding, the computation of 10**exp can
+ accumulate more than a few digits of error. The previous incarnation
+ of real.c successfully used a 144-bit fraction; given the current
+ layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits.
+
+ Target floating point models that use base 16 instead of base 2
+ (i.e. IBM 370), are handled during round_for_format, in which we
+ canonicalize the exponent to be a multiple of 4 (log2(16)), and
+ adjust the significand to match. */
+
+
+/* Used to classify two numbers simultaneously. */
+#define CLASS2(A, B) ((A) << 2 | (B))
+
+#if HOST_BITS_PER_LONG != 64 && HOST_BITS_PER_LONG != 32
+ #error "Some constant folding done by hand to avoid shift count warnings"
+#endif
+
+static void get_zero (REAL_VALUE_TYPE *, int);
+static void get_canonical_qnan (REAL_VALUE_TYPE *, int);
+static void get_canonical_snan (REAL_VALUE_TYPE *, int);
+static void get_inf (REAL_VALUE_TYPE *, int);
+static bool sticky_rshift_significand (REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, unsigned int);
+static void rshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ unsigned int);
+static void lshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ unsigned int);
+static void lshift_significand_1 (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static bool add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static bool sub_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, int);
+static void neg_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static int cmp_significands (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static int cmp_significand_0 (const REAL_VALUE_TYPE *);
+static void set_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static void clear_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static bool test_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static void clear_significand_below (REAL_VALUE_TYPE *, unsigned int);
+static bool div_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static void normalize (REAL_VALUE_TYPE *);
+
+static bool do_add (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, int);
+static bool do_multiply (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static bool do_divide (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
+static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+
+static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
+
+static const REAL_VALUE_TYPE * ten_to_ptwo (int);
+static const REAL_VALUE_TYPE * ten_to_mptwo (int);
+static const REAL_VALUE_TYPE * real_digit (int);
+static void times_pten (REAL_VALUE_TYPE *, int);
+
+static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);