/* real.c - software floating point emulation.
   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
   2000, 2002, 2003, 2004 Free Software Foundation, Inc.
   Contributed by Stephen L. Moshier (moshier@world.std.com).
   Re-written by Richard Henderson <rth@redhat.com>

   This file is part of GCC.

   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.

   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 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 "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "toplev.h"
#include "real.h"
#include "tm_p.h"

/* 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 *);

/* Initialize R with a positive zero.  */

static inline void
get_zero (REAL_VALUE_TYPE *r, int sign)
{
  memset (r, 0, sizeof (*r));
  r->sign = sign;
}

/* Initialize R with the canonical quiet NaN.  */

static inline void
get_canonical_qnan (REAL_VALUE_TYPE *r, int sign)
{
  memset (r, 0, sizeof (*r));
  r->class = rvc_nan;
  r->sign = sign;
  r->canonical = 1;
}

static inline void
get_canonical_snan (REAL_VALUE_TYPE *r, int sign)
{
  memset (r, 0, sizeof (*r));
  r->class = rvc_nan;
  r->sign = sign;
  r->signalling = 1;
  r->canonical = 1;
}

static inline void
get_inf (REAL_VALUE_TYPE *r, int sign)
{
  memset (r, 0, sizeof (*r));
  r->class = rvc_inf;
  r->sign = sign;
}


/* Right-shift the significand of A by N bits; put the result in the
   significand of R.  If any one bits are shifted out, return true.  */

static bool
sticky_rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
			   unsigned int n)
{
  unsigned long sticky = 0;
  unsigned int i, ofs = 0;

  if (n >= HOST_BITS_PER_LONG)
    {
      for (i = 0, ofs = n / HOST_BITS_PER_LONG; i < ofs; ++i)
	sticky |= a->sig[i];
      n &= HOST_BITS_PER_LONG - 1;
    }

  if (n != 0)
    {
      sticky |= a->sig[ofs] & (((unsigned long)1 << n) - 1);
      for (i = 0; i < SIGSZ; ++i)
	{
	  r->sig[i]
	    = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n)
	       | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1])
		  << (HOST_BITS_PER_LONG - n)));
	}
    }
  else
    {
      for (i = 0; ofs + i < SIGSZ; ++i)
	r->sig[i] = a->sig[ofs + i];
      for (; i < SIGSZ; ++i)
	r->sig[i] = 0;
    }

  return sticky != 0;
}

/* Right-shift the significand of A by N bits; put the result in the
   significand of R.  */

static void
rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
		    unsigned int n)
{
  unsigned int i, ofs = n / HOST_BITS_PER_LONG;

  n &= HOST_BITS_PER_LONG - 1;
  if (n != 0)
    {
      for (i = 0; i < SIGSZ; ++i)
	{
	  r->sig[i]
	    = (((ofs + i >= SIGSZ ? 0 : a->sig[ofs + i]) >> n)
	       | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[ofs + i + 1])
		  << (HOST_BITS_PER_LONG - n)));
	}
    }
  else
    {
      for (i = 0; ofs + i < SIGSZ; ++i)
	r->sig[i] = a->sig[ofs + i];
      for (; i < SIGSZ; ++i)
	r->sig[i] = 0;
    }
}

/* Left-shift the significand of A by N bits; put the result in the
   significand of R.  */

static void
lshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
		    unsigned int n)
{
  unsigned int i, ofs = n / HOST_BITS_PER_LONG;

  n &= HOST_BITS_PER_LONG - 1;
  if (n == 0)
    {
      for (i = 0; ofs + i < SIGSZ; ++i)
	r->sig[SIGSZ-1-i] = a->sig[SIGSZ-1-i-ofs];
      for (; i < SIGSZ; ++i)
	r->sig[SIGSZ-1-i] = 0;
    }
  else
    for (i = 0; i < SIGSZ; ++i)
      {
	r->sig[SIGSZ-1-i]
	  = (((ofs + i >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs]) << n)
	     | ((ofs + i + 1 >= SIGSZ ? 0 : a->sig[SIGSZ-1-i-ofs-1])
		>> (HOST_BITS_PER_LONG - n)));
      }
}

/* Likewise, but N is specialized to 1.  */

static inline void
lshift_significand_1 (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
  unsigned int i;

  for (i = SIGSZ - 1; i > 0; --i)
    r->sig[i] = (a->sig[i] << 1) | (a->sig[i-1] >> (HOST_BITS_PER_LONG - 1));
  r->sig[0] = a->sig[0] << 1;
}

/* Add the significands of A and B, placing the result in R.  Return
   true if there was carry out of the most significant word.  */

static inline bool
add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
		  const REAL_VALUE_TYPE *b)
{
  bool carry = false;
  int i;

  for (i = 0; i < SIGSZ; ++i)
    {
      unsigned long ai = a->sig[i];
      unsigned long ri = ai + b->sig[i];

      if (carry)
	{
	  carry = ri < ai;
	  carry |= ++ri == 0;
	}
      else
	carry = ri < ai;

      r->sig[i] = ri;
    }

  return carry;
}

/* Subtract the significands of A and B, placing the result in R.  CARRY is
   true if there's a borrow incoming to the least significant word.
   Return true if there was borrow out of the most significant word.  */

static inline bool
sub_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
		  const REAL_VALUE_TYPE *b, int carry)
{
  int i;

  for (i = 0; i < SIGSZ; ++i)
    {
      unsigned long ai = a->sig[i];
      unsigned long ri = ai - b->sig[i];

      if (carry)
	{
	  carry = ri > ai;
	  carry |= ~--ri == 0;
	}
      else
	carry = ri > ai;

      r->sig[i] = ri;
    }

  return carry;
}

/* Negate the significand A, placing the result in R.  */

static inline void
neg_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
  bool carry = true;
  int i;

  for (i = 0; i < SIGSZ; ++i)
    {
      unsigned long ri, ai = a->sig[i];

      if (carry)
	{
	  if (ai)
	    {
	      ri = -ai;
	      carry = false;
	    }
	  else
	    ri = ai;
	}
      else
	ri = ~ai;

      r->sig[i] = ri;
    }
}

/* Compare significands.  Return tri-state vs zero.  */

static inline int
cmp_significands (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
{
  int i;

  for (i = SIGSZ - 1; i >= 0; --i)
    {
      unsigned long ai = a->sig[i];
      unsigned long bi = b->sig[i];

      if (ai > bi)
	return 1;
      if (ai < bi)
	return -1;
    }

  return 0;
}

/* Return true if A is nonzero.  */

static inline int
cmp_significand_0 (const REAL_VALUE_TYPE *a)
{
  int i;

  for (i = SIGSZ - 1; i >= 0; --i)
    if (a->sig[i])
      return 1;

  return 0;
}

/* Set bit N of the significand of R.  */

static inline void
set_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
  r->sig[n / HOST_BITS_PER_LONG]
    |= (unsigned long)1 << (n % HOST_BITS_PER_LONG);
}

/* Clear bit N of the significand of R.  */

static inline void
clear_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
  r->sig[n / HOST_BITS_PER_LONG]
    &= ~((unsigned long)1 << (n % HOST_BITS_PER_LONG));
}

/* Test bit N of the significand of R.  */

static inline bool
test_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
  /* ??? Compiler bug here if we return this expression directly.
     The conversion to bool strips the "&1" and we wind up testing
     e.g. 2 != 0 -> true.  Seen in gcc version 3.2 20020520.  */
  int t = (r->sig[n / HOST_BITS_PER_LONG] >> (n % HOST_BITS_PER_LONG)) & 1;
  return t;
}

/* Clear bits 0..N-1 of the significand of R.  */

static void
clear_significand_below (REAL_VALUE_TYPE *r, unsigned int n)
{
  int i, w = n / HOST_BITS_PER_LONG;

  for (i = 0; i < w; ++i)
    r->sig[i] = 0;

  r->sig[w] &= ~(((unsigned long)1 << (n % HOST_BITS_PER_LONG)) - 1);
}

/* Divide the significands of A and B, placing the result in R.  Return
   true if the division was inexact.  */

static inline bool
div_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
		  const REAL_VALUE_TYPE *b)
{
  REAL_VALUE_TYPE u;
  int i, bit = SIGNIFICAND_BITS - 1;
  unsigned long msb, inexact;

  u = *a;
  memset (r->sig, 0, sizeof (r->sig));

  msb = 0;
  goto start;
  do
    {
      msb = u.sig[SIGSZ-1] & SIG_MSB;
      lshift_significand_1 (&u, &u);
    start:
      if (msb || cmp_significands (&u, b) >= 0)
	{
	  sub_significands (&u, &u, b, 0);
	  set_significand_bit (r, bit);
	}
    }
  while (--bit >= 0);

  for (i = 0, inexact = 0; i < SIGSZ; i++)
    inexact |= u.sig[i];

  return inexact != 0;
}

/* Adjust the exponent and significand of R such that the most
   significant bit is set.  We underflow to zero and overflow to
   infinity here, without denormals.  (The intermediate representation
   exponent is large enough to handle target denormals normalized.)  */

static void
normalize (REAL_VALUE_TYPE *r)
{
  int shift = 0, exp;
  int i, j;

  /* Find the first word that is nonzero.  */
  for (i = SIGSZ - 1; i >= 0; i--)
    if (r->sig[i] == 0)
      shift += HOST_BITS_PER_LONG;
    else
      break;

  /* Zero significand flushes to zero.  */
  if (i < 0)
    {
      r->class = rvc_zero;
      r->exp = 0;
      return;
    }

  /* Find the first bit that is nonzero.  */
  for (j = 0; ; j++)
    if (r->sig[i] & ((unsigned long)1 << (HOST_BITS_PER_LONG - 1 - j)))
      break;
  shift += j;

  if (shift > 0)
    {
      exp = r->exp - shift;
      if (exp > MAX_EXP)
	get_inf (r, r->sign);
      else if (exp < -MAX_EXP)
	get_zero (r, r->sign);
      else
	{
	  r->exp = exp;
	  lshift_significand (r, r, shift);
	}
    }
}

/* Calculate R = A + (SUBTRACT_P ? -B : B).  Return true if the
   result may be inexact due to a loss of precision.  */

static bool
do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
	const REAL_VALUE_TYPE *b, int subtract_p)
{
  int dexp, sign, exp;
  REAL_VALUE_TYPE t;
  bool inexact = false;

  /* Determine if we need to add or subtract.  */
  sign = a->sign;
  subtract_p = (sign ^ b->sign) ^ subtract_p;

  switch (CLASS2 (a->class, b->class))
    {
    case CLASS2 (rvc_zero, rvc_zero):
      /* -0 + -0 = -0, -0 - +0 = -0; all other cases yield +0.  */
      get_zero (r, sign & !subtract_p);
      return false;

    case CLASS2 (rvc_zero, rvc_normal):
    case CLASS2 (rvc_zero, rvc_inf):
    case CLASS2 (rvc_zero, rvc_nan):
      /* 0 + ANY = ANY.  */
    case CLASS2 (rvc_normal, rvc_nan):
    case CLASS2 (rvc_inf, rvc_nan):
    case CLASS2 (rvc_nan, rvc_nan):
      /* ANY + NaN = NaN.  */
    case CLASS2 (rvc_normal, rvc_inf):
      /* R + Inf = Inf.  */
      *r = *b;
      r->sign = sign ^ subtract_p;
      return false;

    case CLASS2 (rvc_normal, rvc_zero):
    case CLASS2 (rvc_inf, rvc_zero):
    case CLASS2 (rvc_nan, rvc_zero):
      /* ANY + 0 = ANY.  */
    case CLASS2 (rvc_nan, rvc_normal):
    case CLASS2 (rvc_nan, rvc_inf):
      /* NaN + ANY = NaN.  */
    case CLASS2 (rvc_inf, rvc_normal):
      /* Inf + R = Inf.  */
      *r = *a;
      return false;

    case CLASS2 (rvc_inf, rvc_inf):
      if (subtract_p)
	/* Inf - Inf = NaN.  */
	get_canonical_qnan (r, 0);
      else
	/* Inf + Inf = Inf.  */
	*r = *a;
      return false;

    case CLASS2 (rvc_normal, rvc_normal):
      break;

    default:
      abort ();
    }

  /* Swap the arguments such that A has the larger exponent.  */
  dexp = a->exp - b->exp;
  if (dexp < 0)
    {
      const REAL_VALUE_TYPE *t;
      t = a, a = b, b = t;
      dexp = -dexp;
      sign ^= subtract_p;
    }
  exp = a->exp;

  /* If the exponents are not identical, we need to shift the
     significand of B down.  */
  if (dexp > 0)
    {
      /* If the exponents are too far apart, the significands
	 do not overlap, which makes the subtraction a noop.  */
      if (dexp >= SIGNIFICAND_BITS)
	{
	  *r = *a;
	  r->sign = sign;
	  return true;
	}

      inexact |= sticky_rshift_significand (&t, b, dexp);
      b = &t;
    }

  if (subtract_p)
    {
      if (sub_significands (r, a, b, inexact))
	{
	  /* We got a borrow out of the subtraction.  That means that
	     A and B had the same exponent, and B had the larger
	     significand.  We need to swap the sign and negate the
	     significand.  */
	  sign ^= 1;
	  neg_significand (r, r);
	}
    }
  else
    {
      if (add_significands (r, a, b))
	{
	  /* We got carry out of the addition.  This means we need to
	     shift the significand back down one bit and increase the
	     exponent.  */
	  inexact |= sticky_rshift_significand (r, r, 1);
	  r->sig[SIGSZ-1] |= SIG_MSB;
	  if (++exp > MAX_EXP)
	    {
	      get_inf (r, sign);
	      return true;
	    }
	}
    }

  r->class = rvc_normal;
  r->sign = sign;
  r->exp = exp;
  /* Zero out the remaining fields.  */
  r->signalling = 0;
  r->canonical = 0;

  /* Re-normalize the result.  */
  normalize (r);

  /* Special case: if the subtraction results in zero, the result
     is positive.  */
  if (r->class == rvc_zero)
    r->sign = 0;
  else
    r->sig[0] |= inexact;

  return inexact;
}

/* Calculate R = A * B.  Return true if the result may be inexact.  */

static bool
do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
	     const REAL_VALUE_TYPE *b)
{
  REAL_VALUE_TYPE u, t, *rr;
  unsigned int i, j, k;
  int sign = a->sign ^ b->sign;
  bool inexact = false;

  switch (CLASS2 (a->class, b->class))
    {
    case CLASS2 (rvc_zero, rvc_zero):
    case CLASS2 (rvc_zero, rvc_normal):
    case CLASS2 (rvc_normal, rvc_zero):
      /* +-0 * ANY = 0 with appropriate sign.  */
      get_zero (r, sign);
      return false;

    case CLASS2 (rvc_zero, rvc_nan):
    case CLASS2 (rvc_normal, rvc_nan):
    case CLASS2 (rvc_inf, rvc_nan):
    case CLASS2 (rvc_nan, rvc_nan):
      /* ANY * NaN = NaN.  */
      *r = *b;
      r->sign = sign;
      return false;

    case CLASS2 (rvc_nan, rvc_zero):
    case CLASS2 (rvc_nan, rvc_normal):
    case CLASS2 (rvc_nan, rvc_inf):
      /* NaN * ANY = NaN.  */
      *r = *a;
      r->sign = sign;
      return false;

    case CLASS2 (rvc_zero, rvc_inf):
    case CLASS2 (rvc_inf, rvc_zero):
      /* 0 * Inf = NaN */
      get_canonical_qnan (r, sign);
      return false;

    case CLASS2 (rvc_inf, rvc_inf):
    case CLASS2 (rvc_normal, rvc_inf):
    case CLASS2 (rvc_inf, rvc_normal):
      /* Inf * Inf = Inf, R * Inf = Inf */
      get_inf (r, sign);
      return false;

    case CLASS2 (rvc_normal, rvc_normal):
      break;

    default:
      abort ();
    }

  if (r == a || r == b)
    rr = &t;
  else
    rr = r;
  get_zero (rr, 0);

  /* Collect all the partial products.  Since we don't have sure access
     to a widening multiply, we split each long into two half-words.

     Consider the long-hand form of a four half-word multiplication:

		 A  B  C  D
	      *  E  F  G  H
	     --------------
	        DE DF DG DH
	     CE CF CG CH
	  BE BF BG BH
       AE AF AG AH

     We construct partial products of the widened half-word products
     that are known to not overlap, e.g. DF+DH.  Each such partial
     product is given its proper exponent, which allows us to sum them
     and obtain the finished product.  */

  for (i = 0; i < SIGSZ * 2; ++i)
    {
      unsigned long ai = a->sig[i / 2];
      if (i & 1)
	ai >>= HOST_BITS_PER_LONG / 2;
      else
	ai &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;

      if (ai == 0)
	continue;

      for (j = 0; j < 2; ++j)
	{
	  int exp = (a->exp - (2*SIGSZ-1-i)*(HOST_BITS_PER_LONG/2)
		     + (b->exp - (1-j)*(HOST_BITS_PER_LONG/2)));

	  if (exp > MAX_EXP)
	    {
	      get_inf (r, sign);
	      return true;
	    }
	  if (exp < -MAX_EXP)
	    {
	      /* Would underflow to zero, which we shouldn't bother adding.  */
	      inexact = true;
	      continue;
	    }

	  memset (&u, 0, sizeof (u));
	  u.class = rvc_normal;
	  u.exp = exp;

	  for (k = j; k < SIGSZ * 2; k += 2)
	    {
	      unsigned long bi = b->sig[k / 2];
	      if (k & 1)
		bi >>= HOST_BITS_PER_LONG / 2;
	      else
		bi &= ((unsigned long)1 << (HOST_BITS_PER_LONG / 2)) - 1;

	      u.sig[k / 2] = ai * bi;
	    }

	  normalize (&u);
	  inexact |= do_add (rr, rr, &u, 0);
	}
    }

  rr->sign = sign;
  if (rr != r)
    *r = t;

  return inexact;
}

/* Calculate R = A / B.  Return true if the result may be inexact.  */

static bool
do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
	   const REAL_VALUE_TYPE *b)
{
  int exp, sign = a->sign ^ b->sign;
  REAL_VALUE_TYPE t, *rr;
  bool inexact;

  switch (CLASS2 (a->class, b->class))
    {
    case CLASS2 (rvc_zero, rvc_zero):
      /* 0 / 0 = NaN.  */
    case CLASS2 (rvc_inf, rvc_inf):
      /* Inf / Inf = NaN.  */
      get_canonical_qnan (r, sign);
      return false;

    case CLASS2 (rvc_zero, rvc_normal):
    case CLASS2 (rvc_zero, rvc_inf):
      /* 0 / ANY = 0.  */
    case CLASS2 (rvc_normal, rvc_inf):
      /* R / Inf = 0.  */
      get_zero (r, sign);
      return false;

    case CLASS2 (rvc_normal, rvc_zero):
      /* R / 0 = Inf.  */
    case CLASS2 (rvc_inf, rvc_zero):
      /* Inf / 0 = Inf.  */
      get_inf (r, sign);
      return false;

    case CLASS2 (rvc_zero, rvc_nan):
    case CLASS2 (rvc_normal, rvc_nan):
    case CLASS2 (rvc_inf, rvc_nan):
    case CLASS2 (rvc_nan, rvc_nan):
      /* ANY / NaN = NaN.  */
      *r = *b;
      r->sign = sign;
      return false;

    case CLASS2 (rvc_nan, rvc_zero):
    case CLASS2 (rvc_nan, rvc_normal):
    case CLASS2 (rvc_nan, rvc_inf):
      /* NaN / ANY = NaN.  */
      *r = *a;
      r->sign = sign;
      return false;

    case CLASS2 (rvc_inf, rvc_normal):
      /* Inf / R = Inf.  */
      get_inf (r, sign);
      return false;

    case CLASS2 (rvc_normal, rvc_normal):
      break;

    default:
      abort ();
    }

  if (r == a || r == b)
    rr = &t;
  else
    rr = r;

  /* Make sure all fields in the result are initialized.  */
  get_zero (rr, 0);
  rr->class = rvc_normal;
  rr->sign = sign;

  exp = a->exp - b->exp + 1;
  if (exp > MAX_EXP)
    {
      get_inf (r, sign);
      return true;
    }
  if (exp < -MAX_EXP)
    {
      get_zero (r, sign);
      return true;
    }
  rr->exp = exp;

  inexact = div_significands (rr, a, b);

  /* Re-normalize the result.  */
  normalize (rr);
  rr->sig[0] |= inexact;

  if (rr != r)
    *r = t;

  return inexact;
}

/* Return a tri-state comparison of A vs B.  Return NAN_RESULT if
   one of the two operands is a NaN.  */

static int
do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
	    int nan_result)
{
  int ret;

  switch (CLASS2 (a->class, b->class))
    {
    case CLASS2 (rvc_zero, rvc_zero):
      /* Sign of zero doesn't matter for compares.  */
      return 0;

    case CLASS2 (rvc_inf, rvc_zero):
    case CLASS2 (rvc_inf, rvc_normal):
    case CLASS2 (rvc_normal, rvc_zero):
      return (a->sign ? -1 : 1);

    case CLASS2 (rvc_inf, rvc_inf):
      return -a->sign - -b->sign;

    case CLASS2 (rvc_zero, rvc_normal):
    case CLASS2 (rvc_zero, rvc_inf):
    case CLASS2 (rvc_normal, rvc_inf):
      return (b->sign ? 1 : -1);

    case CLASS2 (rvc_zero, rvc_nan):
    case CLASS2 (rvc_normal, rvc_nan):
    case CLASS2 (rvc_inf, rvc_nan):
    case CLASS2 (rvc_nan, rvc_nan):
    case CLASS2 (rvc_nan, rvc_zero):
    case CLASS2 (rvc_nan, rvc_normal):
    case CLASS2 (rvc_nan, rvc_inf):
      return nan_result;

    case CLASS2 (rvc_normal, rvc_normal):
      break;

    default:
      abort ();
    }

  if (a->sign != b->sign)
    return -a->sign - -b->sign;

  if (a->exp > b->exp)
    ret = 1;
  else if (a->exp < b->exp)
    ret = -1;
  else
    ret = cmp_significands (a, b);

  return (a->sign ? -ret : ret);
}

/* Return A truncated to an integral value toward zero.  */

static void
do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
  *r = *a;

  switch (r->class)
    {
    case rvc_zero:
    case rvc_inf:
    case rvc_nan:
      break;

    case rvc_normal:
      if (r->exp <= 0)
	get_zero (r, r->sign);
      else if (r->exp < SIGNIFICAND_BITS)
	clear_significand_below (r, SIGNIFICAND_BITS - r->exp);
      break;

    default:
      abort ();
    }
}

/* Perform the binary or unary operation described by CODE.
   For a unary operation, leave OP1 NULL.  */

void
real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
		 const REAL_VALUE_TYPE *op1)
{
  enum tree_code code = icode;

  switch (code)
    {
    case PLUS_EXPR:
      do_add (r, op0, op1, 0);
      break;

    case MINUS_EXPR:
      do_add (r, op0, op1, 1);
      break;

    case MULT_EXPR:
      do_multiply (r, op0, op1);
      break;

    case RDIV_EXPR:
      do_divide (r, op0, op1);
      break;

    case MIN_EXPR:
      if (op1->class == rvc_nan)
	*r = *op1;
      else if (do_compare (op0, op1, -1) < 0)
	*r = *op0;
      else
	*r = *op1;
      break;

    case MAX_EXPR:
      if (op1->class == rvc_nan)
	*r = *op1;
      else if (do_compare (op0, op1, 1) < 0)
	*r = *op1;
      else
	*r = *op0;
      break;

    case NEGATE_EXPR:
      *r = *op0;
      r->sign ^= 1;
      break;

    case ABS_EXPR:
      *r = *op0;
      r->sign = 0;
      break;

    case FIX_TRUNC_EXPR:
      do_fix_trunc (r, op0);
      break;

    default:
      abort ();
    }
}

/* Legacy.  Similar, but return the result directly.  */

REAL_VALUE_TYPE
real_arithmetic2 (int icode, const REAL_VALUE_TYPE *op0,
		  const REAL_VALUE_TYPE *op1)
{
  REAL_VALUE_TYPE r;
  real_arithmetic (&r, icode, op0, op1);
  return r;
}

bool
real_compare (int icode, const REAL_VALUE_TYPE *op0,
	      const REAL_VALUE_TYPE *op1)
{
  enum tree_code code = icode;

  switch (code)
    {
    case LT_EXPR:
      return do_compare (op0, op1, 1) < 0;
    case LE_EXPR:
      return do_compare (op0, op1, 1) <= 0;
    case GT_EXPR:
      return do_compare (op0, op1, -1) > 0;
    case GE_EXPR:
      return do_compare (op0, op1, -1) >= 0;
    case EQ_EXPR:
      return do_compare (op0, op1, -1) == 0;
    case NE_EXPR:
      return do_compare (op0, op1, -1) != 0;
    case UNORDERED_EXPR:
      return op0->class == rvc_nan || op1->class == rvc_nan;
    case ORDERED_EXPR:
      return op0->class != rvc_nan && op1->class != rvc_nan;
    case UNLT_EXPR:
      return do_compare (op0, op1, -1) < 0;
    case UNLE_EXPR:
      return do_compare (op0, op1, -1) <= 0;
    case UNGT_EXPR:
      return do_compare (op0, op1, 1) > 0;
    case UNGE_EXPR:
      return do_compare (op0, op1, 1) >= 0;
    case UNEQ_EXPR:
      return do_compare (op0, op1, 0) == 0;

    default:
      abort ();
    }
}

/* Return floor log2(R).  */

int
real_exponent (const REAL_VALUE_TYPE *r)
{
  switch (r->class)
    {
    case rvc_zero:
      return 0;
    case rvc_inf:
    case rvc_nan:
      return (unsigned int)-1 >> 1;
    case rvc_normal:
      return r->exp;
    default:
      abort ();
    }
}

/* R = OP0 * 2**EXP.  */

void
real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
{
  *r = *op0;
  switch (r->class)
    {
    case rvc_zero:
    case rvc_inf:
    case rvc_nan:
      break;

    case rvc_normal:
      exp += op0->exp;
      if (exp > MAX_EXP)
	get_inf (r, r->sign);
      else if (exp < -MAX_EXP)
	get_zero (r, r->sign);
      else
	r->exp = exp;
      break;

    default:
      abort ();
    }
}

/* Determine whether a floating-point value X is infinite.  */

bool
real_isinf (const REAL_VALUE_TYPE *r)
{
  return (r->class == rvc_inf);
}

/* Determine whether a floating-point value X is a NaN.  */

bool
real_isnan (const REAL_VALUE_TYPE *r)
{
  return (r->class == rvc_nan);
}

/* Determine whether a floating-point value X is negative.  */

bool
real_isneg (const REAL_VALUE_TYPE *r)
{
  return r->sign;
}

/* Determine whether a floating-point value X is minus zero.  */

bool
real_isnegzero (const REAL_VALUE_TYPE *r)
{
  return r->sign && r->class == rvc_zero;
}

/* Compare two floating-point objects for bitwise identity.  */

bool
real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
{
  int i;

  if (a->class != b->class)
    return false;
  if (a->sign != b->sign)
    return false;

  switch (a->class)
    {
    case rvc_zero:
    case rvc_inf:
      return true;

    case rvc_normal:
      if (a->exp != b->exp)
	return false;
      break;

    case rvc_nan:
      if (a->signalling != b->signalling)
	return false;
      /* The significand is ignored for canonical NaNs.  */
      if (a->canonical || b->canonical)
	return a->canonical == b->canonical;
      break;

    default:
      abort ();
    }

  for (i = 0; i < SIGSZ; ++i)
    if (a->sig[i] != b->sig[i])
      return false;

  return true;
}

/* Try to change R into its exact multiplicative inverse in machine
   mode MODE.  Return true if successful.  */

bool
exact_real_inverse (enum machine_mode mode, REAL_VALUE_TYPE *r)
{
  const REAL_VALUE_TYPE *one = real_digit (1);
  REAL_VALUE_TYPE u;
  int i;

  if (r->class != rvc_normal)
    return false;

  /* Check for a power of two: all significand bits zero except the MSB.  */
  for (i = 0; i < SIGSZ-1; ++i)
    if (r->sig[i] != 0)
      return false;
  if (r->sig[SIGSZ-1] != SIG_MSB)
    return false;

  /* Find the inverse and truncate to the required mode.  */
  do_divide (&u, one, r);
  real_convert (&u, mode, &u);

  /* The rounding may have overflowed.  */
  if (u.class != rvc_normal)
    return false;
  for (i = 0; i < SIGSZ-1; ++i)
    if (u.sig[i] != 0)
      return false;
  if (u.sig[SIGSZ-1] != SIG_MSB)
    return false;

  *r = u;
  return true;
}

/* Render R as an integer.  */

HOST_WIDE_INT
real_to_integer (const REAL_VALUE_TYPE *r)
{
  unsigned HOST_WIDE_INT i;

  switch (r->class)
    {
    case rvc_zero:
    underflow:
      return 0;

    case rvc_inf:
    case rvc_nan:
    overflow:
      i = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
      if (!r->sign)
	i--;
      return i;

    case rvc_normal:
      if (r->exp <= 0)
	goto underflow;
      /* Only force overflow for unsigned overflow.  Signed overflow is
	 undefined, so it doesn't matter what we return, and some callers
	 expect to be able to use this routine for both signed and
	 unsigned conversions.  */
      if (r->exp > HOST_BITS_PER_WIDE_INT)
	goto overflow;

      if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
	i = r->sig[SIGSZ-1];
      else if (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG)
	{
	  i = r->sig[SIGSZ-1];
	  i = i << (HOST_BITS_PER_LONG - 1) << 1;
	  i |= r->sig[SIGSZ-2];
	}
      else
	abort ();

      i >>= HOST_BITS_PER_WIDE_INT - r->exp;

      if (r->sign)
	i = -i;
      return i;

    default:
      abort ();
    }
}

/* Likewise, but to an integer pair, HI+LOW.  */

void
real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
		  const REAL_VALUE_TYPE *r)
{
  REAL_VALUE_TYPE t;
  HOST_WIDE_INT low, high;
  int exp;

  switch (r->class)
    {
    case rvc_zero:
    underflow:
      low = high = 0;
      break;

    case rvc_inf:
    case rvc_nan:
    overflow:
      high = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
      if (r->sign)
	low = 0;
      else
	{
	  high--;
	  low = -1;
	}
      break;

    case rvc_normal:
      exp = r->exp;
      if (exp <= 0)
	goto underflow;
      /* Only force overflow for unsigned overflow.  Signed overflow is
	 undefined, so it doesn't matter what we return, and some callers
	 expect to be able to use this routine for both signed and
	 unsigned conversions.  */
      if (exp > 2*HOST_BITS_PER_WIDE_INT)
	goto overflow;

      rshift_significand (&t, r, 2*HOST_BITS_PER_WIDE_INT - exp);
      if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
	{
	  high = t.sig[SIGSZ-1];
	  low = t.sig[SIGSZ-2];
	}
      else if (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG)
	{
	  high = t.sig[SIGSZ-1];
	  high = high << (HOST_BITS_PER_LONG - 1) << 1;
	  high |= t.sig[SIGSZ-2];

	  low = t.sig[SIGSZ-3];
	  low = low << (HOST_BITS_PER_LONG - 1) << 1;
	  low |= t.sig[SIGSZ-4];
	}
      else
	abort ();

      if (r->sign)
	{
	  if (low == 0)
	    high = -high;
	  else
	    low = -low, high = ~high;
	}
      break;

    default:
      abort ();
    }

  *plow = low;
  *phigh = high;
}

/* A subroutine of real_to_decimal.  Compute the quotient and remainder
   of NUM / DEN.  Return the quotient and place the remainder in NUM.
   It is expected that NUM / DEN are close enough that the quotient is
   small.  */

static unsigned long
rtd_divmod (REAL_VALUE_TYPE *num, REAL_VALUE_TYPE *den)
{
  unsigned long q, msb;
  int expn = num->exp, expd = den->exp;

  if (expn < expd)
    return 0;

  q = msb = 0;
  goto start;
  do
    {
      msb = num->sig[SIGSZ-1] & SIG_MSB;
      q <<= 1;
      lshift_significand_1 (num, num);
    start:
      if (msb || cmp_significands (num, den) >= 0)
	{
	  sub_significands (num, num, den, 0);
	  q |= 1;
	}
    }
  while (--expn >= expd);

  num->exp = expd;
  normalize (num);

  return q;
}

/* Render R as a decimal floating point constant.  Emit DIGITS significant
   digits in the result, bounded by BUF_SIZE.  If DIGITS is 0, choose the
   maximum for the representation.  If CROP_TRAILING_ZEROS, strip trailing
   zeros.  */

#define M_LOG10_2	0.30102999566398119521

void
real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
		 size_t digits, int crop_trailing_zeros)
{
  const REAL_VALUE_TYPE *one, *ten;
  REAL_VALUE_TYPE r, pten, u, v;
  int dec_exp, cmp_one, digit;
  size_t max_digits;
  char *p, *first, *last;
  bool sign;

  r = *r_orig;
  switch (r.class)
    {
    case rvc_zero:
      strcpy (str, (r.sign ? "-0.0" : "0.0"));
      return;
    case rvc_normal:
      break;
    case rvc_inf:
      strcpy (str, (r.sign ? "-Inf" : "+Inf"));
      return;
    case rvc_nan:
      /* ??? Print the significand as well, if not canonical?  */
      strcpy (str, (r.sign ? "-NaN" : "+NaN"));
      return;
    default:
      abort ();
    }

  /* Bound the number of digits printed by the size of the representation.  */
  max_digits = SIGNIFICAND_BITS * M_LOG10_2;
  if (digits == 0 || digits > max_digits)
    digits = max_digits;

  /* Estimate the decimal exponent, and compute the length of the string it
     will print as.  Be conservative and add one to account for possible
     overflow or rounding error.  */
  dec_exp = r.exp * M_LOG10_2;
  for (max_digits = 1; dec_exp ; max_digits++)
    dec_exp /= 10;

  /* Bound the number of digits printed by the size of the output buffer.  */
  max_digits = buf_size - 1 - 1 - 2 - max_digits - 1;
  if (max_digits > buf_size)
    abort ();
  if (digits > max_digits)
    digits = max_digits;

  one = real_digit (1);
  ten = ten_to_ptwo (0);

  sign = r.sign;
  r.sign = 0;

  dec_exp = 0;
  pten = *one;

  cmp_one = do_compare (&r, one, 0);
  if (cmp_one > 0)
    {
      int m;

      /* Number is greater than one.  Convert significand to an integer
	 and strip trailing decimal zeros.  */

      u = r;
      u.exp = SIGNIFICAND_BITS - 1;

      /* Largest M, such that 10**2**M fits within SIGNIFICAND_BITS.  */
      m = floor_log2 (max_digits);

      /* Iterate over the bits of the possible powers of 10 that might
	 be present in U and eliminate them.  That is, if we find that
	 10**2**M divides U evenly, keep the division and increase
	 DEC_EXP by 2**M.  */
      do
	{
	  REAL_VALUE_TYPE t;

	  do_divide (&t, &u, ten_to_ptwo (m));
	  do_fix_trunc (&v, &t);
	  if (cmp_significands (&v, &t) == 0)
	    {
	      u = t;
	      dec_exp += 1 << m;
	    }
	}
      while (--m >= 0);

      /* Revert the scaling to integer that we performed earlier.  */
      u.exp += r.exp - (SIGNIFICAND_BITS - 1);
      r = u;

      /* Find power of 10.  Do this by dividing out 10**2**M when
	 this is larger than the current remainder.  Fill PTEN with
	 the power of 10 that we compute.  */
      if (r.exp > 0)
	{
	  m = floor_log2 ((int)(r.exp * M_LOG10_2)) + 1;
	  do
	    {
	      const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
	      if (do_compare (&u, ptentwo, 0) >= 0)
	        {
	          do_divide (&u, &u, ptentwo);
	          do_multiply (&pten, &pten, ptentwo);
	          dec_exp += 1 << m;
	        }
	    }
          while (--m >= 0);
	}
      else
	/* We managed to divide off enough tens in the above reduction
	   loop that we've now got a negative exponent.  Fall into the
	   less-than-one code to compute the proper value for PTEN.  */
	cmp_one = -1;
    }
  if (cmp_one < 0)
    {
      int m;

      /* Number is less than one.  Pad significand with leading
	 decimal zeros.  */

      v = r;
      while (1)
	{
	  /* Stop if we'd shift bits off the bottom.  */
	  if (v.sig[0] & 7)
	    break;

	  do_multiply (&u, &v, ten);

	  /* Stop if we're now >= 1.  */
	  if (u.exp > 0)
	    break;

	  v = u;
	  dec_exp -= 1;
	}
      r = v;

      /* Find power of 10.  Do this by multiplying in P=10**2**M when
	 the current remainder is smaller than 1/P.  Fill PTEN with the
	 power of 10 that we compute.  */
      m = floor_log2 ((int)(-r.exp * M_LOG10_2)) + 1;
      do
	{
	  const REAL_VALUE_TYPE *ptentwo = ten_to_ptwo (m);
	  const REAL_VALUE_TYPE *ptenmtwo = ten_to_mptwo (m);

	  if (do_compare (&v, ptenmtwo, 0) <= 0)
	    {
	      do_multiply (&v, &v, ptentwo);
	      do_multiply (&pten, &pten, ptentwo);
	      dec_exp -= 1 << m;
	    }
	}
      while (--m >= 0);

      /* Invert the positive power of 10 that we've collected so far.  */
      do_divide (&pten, one, &pten);
    }

  p = str;
  if (sign)
    *p++ = '-';
  first = p++;

  /* At this point, PTEN should contain the nearest power of 10 smaller
     than R, such that this division produces the first digit.

     Using a divide-step primitive that returns the complete integral
     remainder avoids the rounding error that would be produced if
     we were to use do_divide here and then simply multiply by 10 for
     each subsequent digit.  */

  digit = rtd_divmod (&r, &pten);

  /* Be prepared for error in that division via underflow ...  */
  if (digit == 0 && cmp_significand_0 (&r))
    {
      /* Multiply by 10 and try again.  */
      do_multiply (&r, &r, ten);
      digit = rtd_divmod (&r, &pten);
      dec_exp -= 1;
      if (digit == 0)
	abort ();
    }

  /* ... or overflow.  */
  if (digit == 10)
    {
      *p++ = '1';
      if (--digits > 0)
	*p++ = '0';
      dec_exp += 1;
    }
  else if (digit > 10)
    abort ();
  else
    *p++ = digit + '0';

  /* Generate subsequent digits.  */
  while (--digits > 0)
    {
      do_multiply (&r, &r, ten);
      digit = rtd_divmod (&r, &pten);
      *p++ = digit + '0';
    }
  last = p;

  /* Generate one more digit with which to do rounding.  */
  do_multiply (&r, &r, ten);
  digit = rtd_divmod (&r, &pten);

  /* Round the result.  */
  if (digit == 5)
    {
      /* Round to nearest.  If R is nonzero there are additional
	 nonzero digits to be extracted.  */
      if (cmp_significand_0 (&r))
	digit++;
      /* Round to even.  */
      else if ((p[-1] - '0') & 1)
	digit++;
    }
  if (digit > 5)
    {
      while (p > first)
	{
	  digit = *--p;
	  if (digit == '9')
	    *p = '0';
	  else
	    {
	      *p = digit + 1;
	      break;
	    }
	}

      /* Carry out of the first digit.  This means we had all 9's and
	 now have all 0's.  "Prepend" a 1 by overwriting the first 0.  */
      if (p == first)
	{
	  first[1] = '1';
	  dec_exp++;
	}
    }

  /* Insert the decimal point.  */
  first[0] = first[1];
  first[1] = '.';

  /* If requested, drop trailing zeros.  Never crop past "1.0".  */
  if (crop_trailing_zeros)
    while (last > first + 3 && last[-1] == '0')
      last--;

  /* Append the exponent.  */
  sprintf (last, "e%+d", dec_exp);
}

/* Render R as a hexadecimal floating point constant.  Emit DIGITS
   significant digits in the result, bounded by BUF_SIZE.  If DIGITS is 0,
   choose the maximum for the representation.  If CROP_TRAILING_ZEROS,
   strip trailing zeros.  */

void
real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size,
		     size_t digits, int crop_trailing_zeros)
{
  int i, j, exp = r->exp;
  char *p, *first;
  char exp_buf[16];
  size_t max_digits;

  switch (r->class)
    {
    case rvc_zero:
      exp = 0;
      break;
    case rvc_normal:
      break;
    case rvc_inf:
      strcpy (str, (r->sign ? "-Inf" : "+Inf"));
      return;
    case rvc_nan:
      /* ??? Print the significand as well, if not canonical?  */
      strcpy (str, (r->sign ? "-NaN" : "+NaN"));
      return;
    default:
      abort ();
    }

  if (digits == 0)
    digits = SIGNIFICAND_BITS / 4;

  /* Bound the number of digits printed by the size of the output buffer.  */

  sprintf (exp_buf, "p%+d", exp);
  max_digits = buf_size - strlen (exp_buf) - r->sign - 4 - 1;
  if (max_digits > buf_size)
    abort ();
  if (digits > max_digits)
    digits = max_digits;

  p = str;
  if (r->sign)
    *p++ = '-';
  *p++ = '0';
  *p++ = 'x';
  *p++ = '0';
  *p++ = '.';
  first = p;

  for (i = SIGSZ - 1; i >= 0; --i)
    for (j = HOST_BITS_PER_LONG - 4; j >= 0; j -= 4)
      {
	*p++ = "0123456789abcdef"[(r->sig[i] >> j) & 15];
	if (--digits == 0)
	  goto out;
      }

 out:
  if (crop_trailing_zeros)
    while (p > first + 1 && p[-1] == '0')
      p--;

  sprintf (p, "p%+d", exp);
}

/* Initialize R from a decimal or hexadecimal string.  The string is
   assumed to have been syntax checked already.  */

void
real_from_string (REAL_VALUE_TYPE *r, const char *str)
{
  int exp = 0;
  bool sign = false;

  get_zero (r, 0);

  if (*str == '-')
    {
      sign = true;
      str++;
    }
  else if (*str == '+')
    str++;

  if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
    {
      /* Hexadecimal floating point.  */
      int pos = SIGNIFICAND_BITS - 4, d;

      str += 2;

      while (*str == '0')
	str++;
      while (1)
	{
	  d = hex_value (*str);
	  if (d == _hex_bad)
	    break;
	  if (pos >= 0)
	    {
	      r->sig[pos / HOST_BITS_PER_LONG]
		|= (unsigned long) d << (pos % HOST_BITS_PER_LONG);
	      pos -= 4;
	    }
	  exp += 4;
	  str++;
	}
      if (*str == '.')
	{
	  str++;
	  if (pos == SIGNIFICAND_BITS - 4)
	    {
	      while (*str == '0')
		str++, exp -= 4;
	    }
	  while (1)
	    {
	      d = hex_value (*str);
	      if (d == _hex_bad)
		break;
	      if (pos >= 0)
		{
		  r->sig[pos / HOST_BITS_PER_LONG]
		    |= (unsigned long) d << (pos % HOST_BITS_PER_LONG);
		  pos -= 4;
		}
	      str++;
	    }
	}
      if (*str == 'p' || *str == 'P')
	{
	  bool exp_neg = false;

	  str++;
	  if (*str == '-')
	    {
	      exp_neg = true;
	      str++;
	    }
	  else if (*str == '+')
	    str++;

	  d = 0;
	  while (ISDIGIT (*str))
	    {
	      d *= 10;
	      d += *str - '0';
	      if (d > MAX_EXP)
		{
		  /* Overflowed the exponent.  */
		  if (exp_neg)
		    goto underflow;
		  else
		    goto overflow;
		}
	      str++;
	    }
	  if (exp_neg)
	    d = -d;

	  exp += d;
	}

      r->class = rvc_normal;
      r->exp = exp;

      normalize (r);
    }
  else
    {
      /* Decimal floating point.  */
      const REAL_VALUE_TYPE *ten = ten_to_ptwo (0);
      int d;

      while (*str == '0')
	str++;
      while (ISDIGIT (*str))
	{
	  d = *str++ - '0';
	  do_multiply (r, r, ten);
	  if (d)
	    do_add (r, r, real_digit (d), 0);
	}
      if (*str == '.')
	{
	  str++;
	  if (r->class == rvc_zero)
	    {
	      while (*str == '0')
		str++, exp--;
	    }
	  while (ISDIGIT (*str))
	    {
	      d = *str++ - '0';
	      do_multiply (r, r, ten);
	      if (d)
	        do_add (r, r, real_digit (d), 0);
	      exp--;
	    }
	}

      if (*str == 'e' || *str == 'E')
	{
	  bool exp_neg = false;

	  str++;
	  if (*str == '-')
	    {
	      exp_neg = true;
	      str++;
	    }
	  else if (*str == '+')
	    str++;

	  d = 0;
	  while (ISDIGIT (*str))
	    {
	      d *= 10;
	      d += *str - '0';
	      if (d > MAX_EXP)
		{
		  /* Overflowed the exponent.  */
		  if (exp_neg)
		    goto underflow;
		  else
		    goto overflow;
		}
	      str++;
	    }
	  if (exp_neg)
	    d = -d;
	  exp += d;
	}

      if (exp)
	times_pten (r, exp);
    }

  r->sign = sign;
  return;

 underflow:
  get_zero (r, sign);
  return;

 overflow:
  get_inf (r, sign);
  return;
}

/* Legacy.  Similar, but return the result directly.  */

REAL_VALUE_TYPE
real_from_string2 (const char *s, enum machine_mode mode)
{
  REAL_VALUE_TYPE r;

  real_from_string (&r, s);
  if (mode != VOIDmode)
    real_convert (&r, mode, &r);

  return r;
}

/* Initialize R from the integer pair HIGH+LOW.  */

void
real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
		   unsigned HOST_WIDE_INT low, HOST_WIDE_INT high,
		   int unsigned_p)
{
  if (low == 0 && high == 0)
    get_zero (r, 0);
  else
    {
      memset (r, 0, sizeof (*r));
      r->class = rvc_normal;
      r->sign = high < 0 && !unsigned_p;
      r->exp = 2 * HOST_BITS_PER_WIDE_INT;

      if (r->sign)
	{
	  high = ~high;
	  if (low == 0)
	    high += 1;
	  else
	    low = -low;
	}

      if (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT)
	{
	  r->sig[SIGSZ-1] = high;
	  r->sig[SIGSZ-2] = low;
	}
      else if (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT)
	{
	  r->sig[SIGSZ-1] = high >> (HOST_BITS_PER_LONG - 1) >> 1;
	  r->sig[SIGSZ-2] = high;
	  r->sig[SIGSZ-3] = low >> (HOST_BITS_PER_LONG - 1) >> 1;
	  r->sig[SIGSZ-4] = low;
	}
      else
	abort ();

      normalize (r);
    }

  if (mode != VOIDmode)
    real_convert (r, mode, r);
}

/* Returns 10**2**N.  */

static const REAL_VALUE_TYPE *
ten_to_ptwo (int n)
{
  static REAL_VALUE_TYPE tens[EXP_BITS];

  if (n < 0 || n >= EXP_BITS)
    abort ();

  if (tens[n].class == rvc_zero)
    {
      if (n < (HOST_BITS_PER_WIDE_INT == 64 ? 5 : 4))
	{
	  HOST_WIDE_INT t = 10;
	  int i;

	  for (i = 0; i < n; ++i)
	    t *= t;

	  real_from_integer (&tens[n], VOIDmode, t, 0, 1);
	}
      else
	{
	  const REAL_VALUE_TYPE *t = ten_to_ptwo (n - 1);
	  do_multiply (&tens[n], t, t);
	}
    }

  return &tens[n];
}

/* Returns 10**(-2**N).  */

static const REAL_VALUE_TYPE *
ten_to_mptwo (int n)
{
  static REAL_VALUE_TYPE tens[EXP_BITS];

  if (n < 0 || n >= EXP_BITS)
    abort ();

  if (tens[n].class == rvc_zero)
    do_divide (&tens[n], real_digit (1), ten_to_ptwo (n));

  return &tens[n];
}

/* Returns N.  */

static const REAL_VALUE_TYPE *
real_digit (int n)
{
  static REAL_VALUE_TYPE num[10];

  if (n < 0 || n > 9)
    abort ();

  if (n > 0 && num[n].class == rvc_zero)
    real_from_integer (&num[n], VOIDmode, n, 0, 1);

  return &num[n];
}

/* Multiply R by 10**EXP.  */

static void
times_pten (REAL_VALUE_TYPE *r, int exp)
{
  REAL_VALUE_TYPE pten, *rr;
  bool negative = (exp < 0);
  int i;

  if (negative)
    {
      exp = -exp;
      pten = *real_digit (1);
      rr = &pten;
    }
  else
    rr = r;

  for (i = 0; exp > 0; ++i, exp >>= 1)
    if (exp & 1)
      do_multiply (rr, rr, ten_to_ptwo (i));

  if (negative)
    do_divide (r, r, &pten);
}

/* Fills R with +Inf.  */

void
real_inf (REAL_VALUE_TYPE *r)
{
  get_inf (r, 0);
}

/* Fills R with a NaN whose significand is described by STR.  If QUIET,
   we force a QNaN, else we force an SNaN.  The string, if not empty,
   is parsed as a number and placed in the significand.  Return true
   if the string was successfully parsed.  */

bool
real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
	  enum machine_mode mode)
{
  const struct real_format *fmt;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    abort ();

  if (*str == 0)
    {
      if (quiet)
	get_canonical_qnan (r, 0);
      else
	get_canonical_snan (r, 0);
    }
  else
    {
      int base = 10, d;
      bool neg = false;

      memset (r, 0, sizeof (*r));
      r->class = rvc_nan;

      /* Parse akin to strtol into the significand of R.  */

      while (ISSPACE (*str))
	str++;
      if (*str == '-')
	str++, neg = true;
      else if (*str == '+')
	str++;
      if (*str == '0')
	{
	  if (*++str == 'x')
	    str++, base = 16;
	  else
	    base = 8;
	}

      while ((d = hex_value (*str)) < base)
	{
	  REAL_VALUE_TYPE u;

	  switch (base)
	    {
	    case 8:
	      lshift_significand (r, r, 3);
	      break;
	    case 16:
	      lshift_significand (r, r, 4);
	      break;
	    case 10:
	      lshift_significand_1 (&u, r);
	      lshift_significand (r, r, 3);
	      add_significands (r, r, &u);
	      break;
	    default:
	      abort ();
	    }

	  get_zero (&u, 0);
	  u.sig[0] = d;
	  add_significands (r, r, &u);

	  str++;
	}

      /* Must have consumed the entire string for success.  */
      if (*str != 0)
	return false;

      /* Shift the significand into place such that the bits
	 are in the most significant bits for the format.  */
      lshift_significand (r, r, SIGNIFICAND_BITS - fmt->pnan);

      /* Our MSB is always unset for NaNs.  */
      r->sig[SIGSZ-1] &= ~SIG_MSB;

      /* Force quiet or signalling NaN.  */
      r->signalling = !quiet;
    }

  return true;
}

/* Fills R with the largest finite value representable in mode MODE.
   If SIGN is nonzero, R is set to the most negative finite value.  */

void
real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
{
  const struct real_format *fmt;
  int np2;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    abort ();

  r->class = rvc_normal;
  r->sign = sign;
  r->signalling = 0;
  r->canonical = 0;
  r->exp = fmt->emax * fmt->log2_b;

  np2 = SIGNIFICAND_BITS - fmt->p * fmt->log2_b;
  memset (r->sig, -1, SIGSZ * sizeof (unsigned long));
  clear_significand_below (r, np2);
}

/* Fills R with 2**N.  */

void
real_2expN (REAL_VALUE_TYPE *r, int n)
{
  memset (r, 0, sizeof (*r));

  n++;
  if (n > MAX_EXP)
    r->class = rvc_inf;
  else if (n < -MAX_EXP)
    ;
  else
    {
      r->class = rvc_normal;
      r->exp = n;
      r->sig[SIGSZ-1] = SIG_MSB;
    }
}


static void
round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
{
  int p2, np2, i, w;
  unsigned long sticky;
  bool guard, lsb;
  int emin2m1, emax2;

  p2 = fmt->p * fmt->log2_b;
  emin2m1 = (fmt->emin - 1) * fmt->log2_b;
  emax2 = fmt->emax * fmt->log2_b;

  np2 = SIGNIFICAND_BITS - p2;
  switch (r->class)
    {
    underflow:
      get_zero (r, r->sign);
    case rvc_zero:
      if (!fmt->has_signed_zero)
	r->sign = 0;
      return;

    overflow:
      get_inf (r, r->sign);
    case rvc_inf:
      return;

    case rvc_nan:
      clear_significand_below (r, np2);
      return;

    case rvc_normal:
      break;

    default:
      abort ();
    }

  /* If we're not base2, normalize the exponent to a multiple of
     the true base.  */
  if (fmt->log2_b != 1)
    {
      int shift = r->exp & (fmt->log2_b - 1);
      if (shift)
	{
	  shift = fmt->log2_b - shift;
	  r->sig[0] |= sticky_rshift_significand (r, r, shift);
	  r->exp += shift;
	}
    }

  /* Check the range of the exponent.  If we're out of range,
     either underflow or overflow.  */
  if (r->exp > emax2)
    goto overflow;
  else if (r->exp <= emin2m1)
    {
      int diff;

      if (!fmt->has_denorm)
	{
	  /* Don't underflow completely until we've had a chance to round.  */
	  if (r->exp < emin2m1)
	    goto underflow;
	}
      else
	{
	  diff = emin2m1 - r->exp + 1;
	  if (diff > p2)
	    goto underflow;

	  /* De-normalize the significand.  */
	  r->sig[0] |= sticky_rshift_significand (r, r, diff);
	  r->exp += diff;
	}
    }

  /* There are P2 true significand bits, followed by one guard bit,
     followed by one sticky bit, followed by stuff.  Fold nonzero
     stuff into the sticky bit.  */

  sticky = 0;
  for (i = 0, w = (np2 - 1) / HOST_BITS_PER_LONG; i < w; ++i)
    sticky |= r->sig[i];
  sticky |=
    r->sig[w] & (((unsigned long)1 << ((np2 - 1) % HOST_BITS_PER_LONG)) - 1);

  guard = test_significand_bit (r, np2 - 1);
  lsb = test_significand_bit (r, np2);

  /* Round to even.  */
  if (guard && (sticky || lsb))
    {
      REAL_VALUE_TYPE u;
      get_zero (&u, 0);
      set_significand_bit (&u, np2);

      if (add_significands (r, r, &u))
	{
	  /* Overflow.  Means the significand had been all ones, and
	     is now all zeros.  Need to increase the exponent, and
	     possibly re-normalize it.  */
	  if (++r->exp > emax2)
	    goto overflow;
	  r->sig[SIGSZ-1] = SIG_MSB;

	  if (fmt->log2_b != 1)
	    {
	      int shift = r->exp & (fmt->log2_b - 1);
	      if (shift)
		{
		  shift = fmt->log2_b - shift;
		  rshift_significand (r, r, shift);
		  r->exp += shift;
		  if (r->exp > emax2)
		    goto overflow;
		}
	    }
	}
    }

  /* Catch underflow that we deferred until after rounding.  */
  if (r->exp <= emin2m1)
    goto underflow;

  /* Clear out trailing garbage.  */
  clear_significand_below (r, np2);
}

/* Extend or truncate to a new mode.  */

void
real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
	      const REAL_VALUE_TYPE *a)
{
  const struct real_format *fmt;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    abort ();

  *r = *a;
  round_for_format (fmt, r);

  /* round_for_format de-normalizes denormals.  Undo just that part.  */
  if (r->class == rvc_normal)
    normalize (r);
}

/* Legacy.  Likewise, except return the struct directly.  */

REAL_VALUE_TYPE
real_value_truncate (enum machine_mode mode, REAL_VALUE_TYPE a)
{
  REAL_VALUE_TYPE r;
  real_convert (&r, mode, &a);
  return r;
}

/* Return true if truncating to MODE is exact.  */

bool
exact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a)
{
  REAL_VALUE_TYPE t;
  real_convert (&t, mode, a);
  return real_identical (&t, a);
}

/* Write R to the given target format.  Place the words of the result
   in target word order in BUF.  There are always 32 bits in each
   long, no matter the size of the host long.

   Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE.  */

long
real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
		    const struct real_format *fmt)
{
  REAL_VALUE_TYPE r;
  long buf1;

  r = *r_orig;
  round_for_format (fmt, &r);

  if (!buf)
    buf = &buf1;
  (*fmt->encode) (fmt, buf, &r);

  return *buf;
}

/* Similar, but look up the format from MODE.  */

long
real_to_target (long *buf, const REAL_VALUE_TYPE *r, enum machine_mode mode)
{
  const struct real_format *fmt;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    abort ();

  return real_to_target_fmt (buf, r, fmt);
}

/* Read R from the given target format.  Read the words of the result
   in target word order in BUF.  There are always 32 bits in each
   long, no matter the size of the host long.  */

void
real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
		      const struct real_format *fmt)
{
  (*fmt->decode) (fmt, r, buf);
}

/* Similar, but look up the format from MODE.  */

void
real_from_target (REAL_VALUE_TYPE *r, const long *buf, enum machine_mode mode)
{
  const struct real_format *fmt;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    abort ();

  (*fmt->decode) (fmt, r, buf);
}

/* Return the number of bits in the significand for MODE.  */
/* ??? Legacy.  Should get access to real_format directly.  */

int
significand_size (enum machine_mode mode)
{
  const struct real_format *fmt;

  fmt = REAL_MODE_FORMAT (mode);
  if (fmt == NULL)
    return 0;

  return fmt->p * fmt->log2_b;
}

/* Return a hash value for the given real value.  */
/* ??? The "unsigned int" return value is intended to be hashval_t,
   but I didn't want to pull hashtab.h into real.h.  */

unsigned int
real_hash (const REAL_VALUE_TYPE *r)
{
  unsigned int h;
  size_t i;

  h = r->class | (r->sign << 2);
  switch (r->class)
    {
    case rvc_zero:
    case rvc_inf:
      return h;

    case rvc_normal:
      h |= r->exp << 3;
      break;

    case rvc_nan:
      if (r->signalling)
	h ^= (unsigned int)-1;
      if (r->canonical)
	return h;
      break;

    default:
      abort ();
    }

  if (sizeof(unsigned long) > sizeof(unsigned int))
    for (i = 0; i < SIGSZ; ++i)
      {
	unsigned long s = r->sig[i];
	h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2));
      }
  else
    for (i = 0; i < SIGSZ; ++i)
      h ^= r->sig[i];

  return h;
}

/* IEEE single-precision format.  */

static void encode_ieee_single (const struct real_format *fmt,
				long *, const REAL_VALUE_TYPE *);
static void decode_ieee_single (const struct real_format *,
				REAL_VALUE_TYPE *, const long *);

static void
encode_ieee_single (const struct real_format *fmt, long *buf,
		    const REAL_VALUE_TYPE *r)
{
  unsigned long image, sig, exp;
  unsigned long sign = r->sign;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;

  image = sign << 31;
  sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;

  switch (r->class)
    {
    case rvc_zero:
      break;

    case rvc_inf:
      if (fmt->has_inf)
	image |= 255 << 23;
      else
	image |= 0x7fffffff;
      break;

    case rvc_nan:
      if (fmt->has_nans)
	{
	  if (r->canonical)
	    sig = 0;
	  if (r->signalling == fmt->qnan_msb_set)
	    sig &= ~(1 << 22);
	  else
	    sig |= 1 << 22;
	  /* We overload qnan_msb_set here: it's only clear for
	     mips_ieee_single, which wants all mantissa bits but the
	     quiet/signalling one set in canonical NaNs (at least
	     Quiet ones).  */
	  if (r->canonical && !fmt->qnan_msb_set)
	    sig |= (1 << 22) - 1;
	  else if (sig == 0)
	    sig = 1 << 21;

	  image |= 255 << 23;
	  image |= sig;
	}
      else
	image |= 0x7fffffff;
      break;

    case rvc_normal:
      /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
	 whereas the intermediate representation is 0.F x 2**exp.
	 Which means we're off by one.  */
      if (denormal)
	exp = 0;
      else
      exp = r->exp + 127 - 1;
      image |= exp << 23;
      image |= sig;
      break;

    default:
      abort ();
    }

  buf[0] = image;
}

static void
decode_ieee_single (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		    const long *buf)
{
  unsigned long image = buf[0] & 0xffffffff;
  bool sign = (image >> 31) & 1;
  int exp = (image >> 23) & 0xff;

  memset (r, 0, sizeof (*r));
  image <<= HOST_BITS_PER_LONG - 24;
  image &= ~SIG_MSB;

  if (exp == 0)
    {
      if (image && fmt->has_denorm)
	{
	  r->class = rvc_normal;
	  r->sign = sign;
	  r->exp = -126;
	  r->sig[SIGSZ-1] = image << 1;
	  normalize (r);
	}
      else if (fmt->has_signed_zero)
	r->sign = sign;
    }
  else if (exp == 255 && (fmt->has_nans || fmt->has_inf))
    {
      if (image)
	{
	  r->class = rvc_nan;
	  r->sign = sign;
	  r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
			   ^ fmt->qnan_msb_set);
	  r->sig[SIGSZ-1] = image;
	}
      else
	{
	  r->class = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = exp - 127 + 1;
      r->sig[SIGSZ-1] = image | SIG_MSB;
    }
}

const struct real_format ieee_single_format =
  {
    encode_ieee_single,
    decode_ieee_single,
    2,
    1,
    24,
    24,
    -125,
    128,
    31,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format mips_single_format =
  {
    encode_ieee_single,
    decode_ieee_single,
    2,
    1,
    24,
    24,
    -125,
    128,
    31,
    true,
    true,
    true,
    true,
    false
  };


/* IEEE double-precision format.  */

static void encode_ieee_double (const struct real_format *fmt,
				long *, const REAL_VALUE_TYPE *);
static void decode_ieee_double (const struct real_format *,
				REAL_VALUE_TYPE *, const long *);

static void
encode_ieee_double (const struct real_format *fmt, long *buf,
		    const REAL_VALUE_TYPE *r)
{
  unsigned long image_lo, image_hi, sig_lo, sig_hi, exp;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;

  image_hi = r->sign << 31;
  image_lo = 0;

  if (HOST_BITS_PER_LONG == 64)
    {
      sig_hi = r->sig[SIGSZ-1];
      sig_lo = (sig_hi >> (64 - 53)) & 0xffffffff;
      sig_hi = (sig_hi >> (64 - 53 + 1) >> 31) & 0xfffff;
    }
  else
    {
      sig_hi = r->sig[SIGSZ-1];
      sig_lo = r->sig[SIGSZ-2];
      sig_lo = (sig_hi << 21) | (sig_lo >> 11);
      sig_hi = (sig_hi >> 11) & 0xfffff;
    }

  switch (r->class)
    {
    case rvc_zero:
      break;

    case rvc_inf:
      if (fmt->has_inf)
	image_hi |= 2047 << 20;
      else
	{
	  image_hi |= 0x7fffffff;
	  image_lo = 0xffffffff;
	}
      break;

    case rvc_nan:
      if (fmt->has_nans)
	{
	  if (r->canonical)
	    sig_hi = sig_lo = 0;
	  if (r->signalling == fmt->qnan_msb_set)
	    sig_hi &= ~(1 << 19);
	  else
	    sig_hi |= 1 << 19;
	  /* We overload qnan_msb_set here: it's only clear for
	     mips_ieee_single, which wants all mantissa bits but the
	     quiet/signalling one set in canonical NaNs (at least
	     Quiet ones).  */
	  if (r->canonical && !fmt->qnan_msb_set)
	    {
	      sig_hi |= (1 << 19) - 1;
	      sig_lo = 0xffffffff;
	    }
	  else if (sig_hi == 0 && sig_lo == 0)
	    sig_hi = 1 << 18;

	  image_hi |= 2047 << 20;
	  image_hi |= sig_hi;
	  image_lo = sig_lo;
	}
      else
	{
	  image_hi |= 0x7fffffff;
	  image_lo = 0xffffffff;
	}
      break;

    case rvc_normal:
      /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
	 whereas the intermediate representation is 0.F x 2**exp.
	 Which means we're off by one.  */
      if (denormal)
	exp = 0;
      else
	exp = r->exp + 1023 - 1;
      image_hi |= exp << 20;
      image_hi |= sig_hi;
      image_lo = sig_lo;
      break;

    default:
      abort ();
    }

  if (FLOAT_WORDS_BIG_ENDIAN)
    buf[0] = image_hi, buf[1] = image_lo;
  else
    buf[0] = image_lo, buf[1] = image_hi;
}

static void
decode_ieee_double (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		    const long *buf)
{
  unsigned long image_hi, image_lo;
  bool sign;
  int exp;

  if (FLOAT_WORDS_BIG_ENDIAN)
    image_hi = buf[0], image_lo = buf[1];
  else
    image_lo = buf[0], image_hi = buf[1];
  image_lo &= 0xffffffff;
  image_hi &= 0xffffffff;

  sign = (image_hi >> 31) & 1;
  exp = (image_hi >> 20) & 0x7ff;

  memset (r, 0, sizeof (*r));

  image_hi <<= 32 - 21;
  image_hi |= image_lo >> 21;
  image_hi &= 0x7fffffff;
  image_lo <<= 32 - 21;

  if (exp == 0)
    {
      if ((image_hi || image_lo) && fmt->has_denorm)
	{
	  r->class = rvc_normal;
	  r->sign = sign;
	  r->exp = -1022;
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      image_hi = (image_hi << 1) | (image_lo >> 31);
	      image_lo <<= 1;
	      r->sig[SIGSZ-1] = image_hi;
	      r->sig[SIGSZ-2] = image_lo;
	    }
	  else
	    {
	      image_hi = (image_hi << 31 << 2) | (image_lo << 1);
	      r->sig[SIGSZ-1] = image_hi;
	    }
	  normalize (r);
	}
      else if (fmt->has_signed_zero)
	r->sign = sign;
    }
  else if (exp == 2047 && (fmt->has_nans || fmt->has_inf))
    {
      if (image_hi || image_lo)
	{
	  r->class = rvc_nan;
	  r->sign = sign;
	  r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set;
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      r->sig[SIGSZ-1] = image_hi;
	      r->sig[SIGSZ-2] = image_lo;
	    }
	  else
	    r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo;
	}
      else
	{
	  r->class = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = exp - 1023 + 1;
      if (HOST_BITS_PER_LONG == 32)
	{
	  r->sig[SIGSZ-1] = image_hi | SIG_MSB;
	  r->sig[SIGSZ-2] = image_lo;
	}
      else
	r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo | SIG_MSB;
    }
}

const struct real_format ieee_double_format =
  {
    encode_ieee_double,
    decode_ieee_double,
    2,
    1,
    53,
    53,
    -1021,
    1024,
    63,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format mips_double_format =
  {
    encode_ieee_double,
    decode_ieee_double,
    2,
    1,
    53,
    53,
    -1021,
    1024,
    63,
    true,
    true,
    true,
    true,
    false
  };


/* IEEE extended real format.  This comes in three flavors: Intel's as
   a 12 byte image, Intel's as a 16 byte image, and Motorola's.  Intel
   12- and 16-byte images may be big- or little endian; Motorola's is
   always big endian.  */

/* Helper subroutine which converts from the internal format to the
   12-byte little-endian Intel format.  Functions below adjust this
   for the other possible formats.  */
static void
encode_ieee_extended (const struct real_format *fmt, long *buf,
		      const REAL_VALUE_TYPE *r)
{
  unsigned long image_hi, sig_hi, sig_lo;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;

  image_hi = r->sign << 15;
  sig_hi = sig_lo = 0;

  switch (r->class)
    {
    case rvc_zero:
      break;

    case rvc_inf:
      if (fmt->has_inf)
	{
	  image_hi |= 32767;

	  /* Intel requires the explicit integer bit to be set, otherwise
	     it considers the value a "pseudo-infinity".  Motorola docs
	     say it doesn't care.  */
	  sig_hi = 0x80000000;
	}
      else
	{
	  image_hi |= 32767;
	  sig_lo = sig_hi = 0xffffffff;
	}
      break;

    case rvc_nan:
      if (fmt->has_nans)
	{
	  image_hi |= 32767;
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      sig_hi = r->sig[SIGSZ-1];
	      sig_lo = r->sig[SIGSZ-2];
	    }
	  else
	    {
	      sig_lo = r->sig[SIGSZ-1];
	      sig_hi = sig_lo >> 31 >> 1;
	      sig_lo &= 0xffffffff;
	    }
	  if (r->signalling == fmt->qnan_msb_set)
	    sig_hi &= ~(1 << 30);
	  else
	    sig_hi |= 1 << 30;
	  if ((sig_hi & 0x7fffffff) == 0 && sig_lo == 0)
	    sig_hi = 1 << 29;

	  /* Intel requires the explicit integer bit to be set, otherwise
	     it considers the value a "pseudo-nan".  Motorola docs say it
	     doesn't care.  */
	  sig_hi |= 0x80000000;
	}
      else
	{
	  image_hi |= 32767;
	  sig_lo = sig_hi = 0xffffffff;
	}
      break;

    case rvc_normal:
      {
	int exp = r->exp;

	/* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
	   whereas the intermediate representation is 0.F x 2**exp.
	   Which means we're off by one.

	   Except for Motorola, which consider exp=0 and explicit
	   integer bit set to continue to be normalized.  In theory
	   this discrepancy has been taken care of by the difference
	   in fmt->emin in round_for_format.  */

	if (denormal)
	  exp = 0;
	else
	  {
	    exp += 16383 - 1;
	    if (exp < 0)
	      abort ();
	  }
	image_hi |= exp;

	if (HOST_BITS_PER_LONG == 32)
	  {
	    sig_hi = r->sig[SIGSZ-1];
	    sig_lo = r->sig[SIGSZ-2];
	  }
	else
	  {
	    sig_lo = r->sig[SIGSZ-1];
	    sig_hi = sig_lo >> 31 >> 1;
	    sig_lo &= 0xffffffff;
	  }
      }
      break;

    default:
      abort ();
    }

  buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
}

/* Convert from the internal format to the 12-byte Motorola format
   for an IEEE extended real.  */
static void
encode_ieee_extended_motorola (const struct real_format *fmt, long *buf,
			       const REAL_VALUE_TYPE *r)
{
  long intermed[3];
  encode_ieee_extended (fmt, intermed, r);

  /* Motorola chips are assumed always to be big-endian.  Also, the
     padding in a Motorola extended real goes between the exponent and
     the mantissa.  At this point the mantissa is entirely within
     elements 0 and 1 of intermed, and the exponent entirely within
     element 2, so all we have to do is swap the order around, and
     shift element 2 left 16 bits.  */
  buf[0] = intermed[2] << 16;
  buf[1] = intermed[1];
  buf[2] = intermed[0];
}

/* Convert from the internal format to the 12-byte Intel format for
   an IEEE extended real.  */
static void
encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf,
			       const REAL_VALUE_TYPE *r)
{
  if (FLOAT_WORDS_BIG_ENDIAN)
    {
      /* All the padding in an Intel-format extended real goes at the high
	 end, which in this case is after the mantissa, not the exponent.
	 Therefore we must shift everything down 16 bits.  */
      long intermed[3];
      encode_ieee_extended (fmt, intermed, r);
      buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16));
      buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16));
      buf[2] =  (intermed[0] << 16);
    }
  else
    /* encode_ieee_extended produces what we want directly.  */
    encode_ieee_extended (fmt, buf, r);
}

/* Convert from the internal format to the 16-byte Intel format for
   an IEEE extended real.  */
static void
encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf,
				const REAL_VALUE_TYPE *r)
{
  /* All the padding in an Intel-format extended real goes at the high end.  */
  encode_ieee_extended_intel_96 (fmt, buf, r);
  buf[3] = 0;
}

/* As above, we have a helper function which converts from 12-byte
   little-endian Intel format to internal format.  Functions below
   adjust for the other possible formats.  */
static void
decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		      const long *buf)
{
  unsigned long image_hi, sig_hi, sig_lo;
  bool sign;
  int exp;

  sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
  sig_lo &= 0xffffffff;
  sig_hi &= 0xffffffff;
  image_hi &= 0xffffffff;

  sign = (image_hi >> 15) & 1;
  exp = image_hi & 0x7fff;

  memset (r, 0, sizeof (*r));

  if (exp == 0)
    {
      if ((sig_hi || sig_lo) && fmt->has_denorm)
	{
	  r->class = rvc_normal;
	  r->sign = sign;

	  /* When the IEEE format contains a hidden bit, we know that
	     it's zero at this point, and so shift up the significand
	     and decrease the exponent to match.  In this case, Motorola
	     defines the explicit integer bit to be valid, so we don't
	     know whether the msb is set or not.  */
	  r->exp = fmt->emin;
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      r->sig[SIGSZ-1] = sig_hi;
	      r->sig[SIGSZ-2] = sig_lo;
	    }
	  else
	    r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;

	  normalize (r);
	}
      else if (fmt->has_signed_zero)
	r->sign = sign;
    }
  else if (exp == 32767 && (fmt->has_nans || fmt->has_inf))
    {
      /* See above re "pseudo-infinities" and "pseudo-nans".
	 Short summary is that the MSB will likely always be
	 set, and that we don't care about it.  */
      sig_hi &= 0x7fffffff;

      if (sig_hi || sig_lo)
	{
	  r->class = rvc_nan;
	  r->sign = sign;
	  r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set;
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      r->sig[SIGSZ-1] = sig_hi;
	      r->sig[SIGSZ-2] = sig_lo;
	    }
	  else
	    r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
	}
      else
	{
	  r->class = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = exp - 16383 + 1;
      if (HOST_BITS_PER_LONG == 32)
	{
	  r->sig[SIGSZ-1] = sig_hi;
	  r->sig[SIGSZ-2] = sig_lo;
	}
      else
	r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
    }
}

/* Convert from the internal format to the 12-byte Motorola format
   for an IEEE extended real.  */
static void
decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r,
			       const long *buf)
{
  long intermed[3];

  /* Motorola chips are assumed always to be big-endian.  Also, the
     padding in a Motorola extended real goes between the exponent and
     the mantissa; remove it.  */
  intermed[0] = buf[2];
  intermed[1] = buf[1];
  intermed[2] = (unsigned long)buf[0] >> 16;

  decode_ieee_extended (fmt, r, intermed);
}

/* Convert from the internal format to the 12-byte Intel format for
   an IEEE extended real.  */
static void
decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
			       const long *buf)
{
  if (FLOAT_WORDS_BIG_ENDIAN)
    {
      /* All the padding in an Intel-format extended real goes at the high
	 end, which in this case is after the mantissa, not the exponent.
	 Therefore we must shift everything up 16 bits.  */
      long intermed[3];

      intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16));
      intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16));
      intermed[2] =  ((unsigned long)buf[0] >> 16);

      decode_ieee_extended (fmt, r, intermed);
    }
  else
    /* decode_ieee_extended produces what we want directly.  */
    decode_ieee_extended (fmt, r, buf);
}

/* Convert from the internal format to the 16-byte Intel format for
   an IEEE extended real.  */
static void
decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
				const long *buf)
{
  /* All the padding in an Intel-format extended real goes at the high end.  */
  decode_ieee_extended_intel_96 (fmt, r, buf);
}

const struct real_format ieee_extended_motorola_format =
  {
    encode_ieee_extended_motorola,
    decode_ieee_extended_motorola,
    2,
    1,
    64,
    64,
    -16382,
    16384,
    95,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format ieee_extended_intel_96_format =
  {
    encode_ieee_extended_intel_96,
    decode_ieee_extended_intel_96,
    2,
    1,
    64,
    64,
    -16381,
    16384,
    79,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format ieee_extended_intel_128_format =
  {
    encode_ieee_extended_intel_128,
    decode_ieee_extended_intel_128,
    2,
    1,
    64,
    64,
    -16381,
    16384,
    79,
    true,
    true,
    true,
    true,
    true
  };

/* The following caters to i386 systems that set the rounding precision
   to 53 bits instead of 64, e.g. FreeBSD.  */
const struct real_format ieee_extended_intel_96_round_53_format =
  {
    encode_ieee_extended_intel_96,
    decode_ieee_extended_intel_96,
    2,
    1,
    53,
    53,
    -16381,
    16384,
    79,
    true,
    true,
    true,
    true,
    true
  };

/* IBM 128-bit extended precision format: a pair of IEEE double precision
   numbers whose sum is equal to the extended precision value.  The number
   with greater magnitude is first.  This format has the same magnitude
   range as an IEEE double precision value, but effectively 106 bits of
   significand precision.  Infinity and NaN are represented by their IEEE
   double precision value stored in the first number, the second number is
   ignored.  Zeroes, Infinities, and NaNs are set in both doubles
   due to precedent.  */

static void encode_ibm_extended (const struct real_format *fmt,
				 long *, const REAL_VALUE_TYPE *);
static void decode_ibm_extended (const struct real_format *,
				 REAL_VALUE_TYPE *, const long *);

static void
encode_ibm_extended (const struct real_format *fmt, long *buf,
		     const REAL_VALUE_TYPE *r)
{
  REAL_VALUE_TYPE u, normr, v;
  const struct real_format *base_fmt;

  base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;

  /* Renormlize R before doing any arithmetic on it.  */
  normr = *r;
  if (normr.class == rvc_normal)
    normalize (&normr);

  /* u = IEEE double precision portion of significand.  */
  u = normr;
  round_for_format (base_fmt, &u);
  encode_ieee_double (base_fmt, &buf[0], &u);

  if (u.class == rvc_normal)
    {
      do_add (&v, &normr, &u, 1);
      /* Call round_for_format since we might need to denormalize.  */
      round_for_format (base_fmt, &v);
      encode_ieee_double (base_fmt, &buf[2], &v);
    }
  else
    {
      /* Inf, NaN, 0 are all representable as doubles, so the
	 least-significant part can be 0.0.  */
      buf[2] = 0;
      buf[3] = 0;
    }
}

static void
decode_ibm_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, REAL_VALUE_TYPE *r,
		     const long *buf)
{
  REAL_VALUE_TYPE u, v;
  const struct real_format *base_fmt;

  base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
  decode_ieee_double (base_fmt, &u, &buf[0]);

  if (u.class != rvc_zero && u.class != rvc_inf && u.class != rvc_nan)
    {
      decode_ieee_double (base_fmt, &v, &buf[2]);
      do_add (r, &u, &v, 0);
    }
  else
    *r = u;
}

const struct real_format ibm_extended_format =
  {
    encode_ibm_extended,
    decode_ibm_extended,
    2,
    1,
    53 + 53,
    53,
    -1021 + 53,
    1024,
    -1,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format mips_extended_format =
  {
    encode_ibm_extended,
    decode_ibm_extended,
    2,
    1,
    53 + 53,
    53,
    -1021 + 53,
    1024,
    -1,
    true,
    true,
    true,
    true,
    false
  };


/* IEEE quad precision format.  */

static void encode_ieee_quad (const struct real_format *fmt,
			      long *, const REAL_VALUE_TYPE *);
static void decode_ieee_quad (const struct real_format *,
			      REAL_VALUE_TYPE *, const long *);

static void
encode_ieee_quad (const struct real_format *fmt, long *buf,
		  const REAL_VALUE_TYPE *r)
{
  unsigned long image3, image2, image1, image0, exp;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
  REAL_VALUE_TYPE u;

  image3 = r->sign << 31;
  image2 = 0;
  image1 = 0;
  image0 = 0;

  rshift_significand (&u, r, SIGNIFICAND_BITS - 113);

  switch (r->class)
    {
    case rvc_zero:
      break;

    case rvc_inf:
      if (fmt->has_inf)
	image3 |= 32767 << 16;
      else
	{
	  image3 |= 0x7fffffff;
	  image2 = 0xffffffff;
	  image1 = 0xffffffff;
	  image0 = 0xffffffff;
	}
      break;

    case rvc_nan:
      if (fmt->has_nans)
	{
	  image3 |= 32767 << 16;

	  if (r->canonical)
	    {
	      /* Don't use bits from the significand.  The
		 initialization above is right.  */
	    }
	  else if (HOST_BITS_PER_LONG == 32)
	    {
	      image0 = u.sig[0];
	      image1 = u.sig[1];
	      image2 = u.sig[2];
	      image3 |= u.sig[3] & 0xffff;
	    }
	  else
	    {
	      image0 = u.sig[0];
	      image1 = image0 >> 31 >> 1;
	      image2 = u.sig[1];
	      image3 |= (image2 >> 31 >> 1) & 0xffff;
	      image0 &= 0xffffffff;
	      image2 &= 0xffffffff;
	    }
	  if (r->signalling == fmt->qnan_msb_set)
	    image3 &= ~0x8000;
	  else
	    image3 |= 0x8000;
	  /* We overload qnan_msb_set here: it's only clear for
	     mips_ieee_single, which wants all mantissa bits but the
	     quiet/signalling one set in canonical NaNs (at least
	     Quiet ones).  */
	  if (r->canonical && !fmt->qnan_msb_set)
	    {
	      image3 |= 0x7fff;
	      image2 = image1 = image0 = 0xffffffff;
	    }
	  else if (((image3 & 0xffff) | image2 | image1 | image0) == 0)
	    image3 |= 0x4000;
	}
      else
	{
	  image3 |= 0x7fffffff;
	  image2 = 0xffffffff;
	  image1 = 0xffffffff;
	  image0 = 0xffffffff;
	}
      break;

    case rvc_normal:
      /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
	 whereas the intermediate representation is 0.F x 2**exp.
	 Which means we're off by one.  */
      if (denormal)
	exp = 0;
      else
	exp = r->exp + 16383 - 1;
      image3 |= exp << 16;

      if (HOST_BITS_PER_LONG == 32)
	{
	  image0 = u.sig[0];
	  image1 = u.sig[1];
	  image2 = u.sig[2];
	  image3 |= u.sig[3] & 0xffff;
	}
      else
	{
	  image0 = u.sig[0];
	  image1 = image0 >> 31 >> 1;
	  image2 = u.sig[1];
	  image3 |= (image2 >> 31 >> 1) & 0xffff;
	  image0 &= 0xffffffff;
	  image2 &= 0xffffffff;
	}
      break;

    default:
      abort ();
    }

  if (FLOAT_WORDS_BIG_ENDIAN)
    {
      buf[0] = image3;
      buf[1] = image2;
      buf[2] = image1;
      buf[3] = image0;
    }
  else
    {
      buf[0] = image0;
      buf[1] = image1;
      buf[2] = image2;
      buf[3] = image3;
    }
}

static void
decode_ieee_quad (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		  const long *buf)
{
  unsigned long image3, image2, image1, image0;
  bool sign;
  int exp;

  if (FLOAT_WORDS_BIG_ENDIAN)
    {
      image3 = buf[0];
      image2 = buf[1];
      image1 = buf[2];
      image0 = buf[3];
    }
  else
    {
      image0 = buf[0];
      image1 = buf[1];
      image2 = buf[2];
      image3 = buf[3];
    }
  image0 &= 0xffffffff;
  image1 &= 0xffffffff;
  image2 &= 0xffffffff;

  sign = (image3 >> 31) & 1;
  exp = (image3 >> 16) & 0x7fff;
  image3 &= 0xffff;

  memset (r, 0, sizeof (*r));

  if (exp == 0)
    {
      if ((image3 | image2 | image1 | image0) && fmt->has_denorm)
	{
	  r->class = rvc_normal;
	  r->sign = sign;

	  r->exp = -16382 + (SIGNIFICAND_BITS - 112);
	  if (HOST_BITS_PER_LONG == 32)
	    {
	      r->sig[0] = image0;
	      r->sig[1] = image1;
	      r->sig[2] = image2;
	      r->sig[3] = image3;
	    }
	  else
	    {
	      r->sig[0] = (image1 << 31 << 1) | image0;
	      r->sig[1] = (image3 << 31 << 1) | image2;
	    }

	  normalize (r);
	}
      else if (fmt->has_signed_zero)
	r->sign = sign;
    }
  else if (exp == 32767 && (fmt->has_nans || fmt->has_inf))
    {
      if (image3 | image2 | image1 | image0)
	{
	  r->class = rvc_nan;
	  r->sign = sign;
	  r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set;

	  if (HOST_BITS_PER_LONG == 32)
	    {
	      r->sig[0] = image0;
	      r->sig[1] = image1;
	      r->sig[2] = image2;
	      r->sig[3] = image3;
	    }
	  else
	    {
	      r->sig[0] = (image1 << 31 << 1) | image0;
	      r->sig[1] = (image3 << 31 << 1) | image2;
	    }
	  lshift_significand (r, r, SIGNIFICAND_BITS - 113);
	}
      else
	{
	  r->class = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = exp - 16383 + 1;

      if (HOST_BITS_PER_LONG == 32)
	{
	  r->sig[0] = image0;
	  r->sig[1] = image1;
	  r->sig[2] = image2;
	  r->sig[3] = image3;
	}
      else
	{
	  r->sig[0] = (image1 << 31 << 1) | image0;
	  r->sig[1] = (image3 << 31 << 1) | image2;
	}
      lshift_significand (r, r, SIGNIFICAND_BITS - 113);
      r->sig[SIGSZ-1] |= SIG_MSB;
    }
}

const struct real_format ieee_quad_format =
  {
    encode_ieee_quad,
    decode_ieee_quad,
    2,
    1,
    113,
    113,
    -16381,
    16384,
    127,
    true,
    true,
    true,
    true,
    true
  };

const struct real_format mips_quad_format =
  {
    encode_ieee_quad,
    decode_ieee_quad,
    2,
    1,
    113,
    113,
    -16381,
    16384,
    127,
    true,
    true,
    true,
    true,
    false
  };

/* Descriptions of VAX floating point formats can be found beginning at

   http://h71000.www7.hp.com/doc/73FINAL/4515/4515pro_013.html#f_floating_point_format

   The thing to remember is that they're almost IEEE, except for word
   order, exponent bias, and the lack of infinities, nans, and denormals.

   We don't implement the H_floating format here, simply because neither
   the VAX or Alpha ports use it.  */

static void encode_vax_f (const struct real_format *fmt,
			  long *, const REAL_VALUE_TYPE *);
static void decode_vax_f (const struct real_format *,
			  REAL_VALUE_TYPE *, const long *);
static void encode_vax_d (const struct real_format *fmt,
			  long *, const REAL_VALUE_TYPE *);
static void decode_vax_d (const struct real_format *,
			  REAL_VALUE_TYPE *, const long *);
static void encode_vax_g (const struct real_format *fmt,
			  long *, const REAL_VALUE_TYPE *);
static void decode_vax_g (const struct real_format *,
			  REAL_VALUE_TYPE *, const long *);

static void
encode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
	      const REAL_VALUE_TYPE *r)
{
  unsigned long sign, exp, sig, image;

  sign = r->sign << 15;

  switch (r->class)
    {
    case rvc_zero:
      image = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      image = 0xffff7fff | sign;
      break;

    case rvc_normal:
      sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
      exp = r->exp + 128;

      image = (sig << 16) & 0xffff0000;
      image |= sign;
      image |= exp << 7;
      image |= sig >> 16;
      break;

    default:
      abort ();
    }

  buf[0] = image;
}

static void
decode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
	      REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long image = buf[0] & 0xffffffff;
  int exp = (image >> 7) & 0xff;

  memset (r, 0, sizeof (*r));

  if (exp != 0)
    {
      r->class = rvc_normal;
      r->sign = (image >> 15) & 1;
      r->exp = exp - 128;

      image = ((image & 0x7f) << 16) | ((image >> 16) & 0xffff);
      r->sig[SIGSZ-1] = (image << (HOST_BITS_PER_LONG - 24)) | SIG_MSB;
    }
}

static void
encode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
	      const REAL_VALUE_TYPE *r)
{
  unsigned long image0, image1, sign = r->sign << 15;

  switch (r->class)
    {
    case rvc_zero:
      image0 = image1 = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      image0 = 0xffff7fff | sign;
      image1 = 0xffffffff;
      break;

    case rvc_normal:
      /* Extract the significand into straight hi:lo.  */
      if (HOST_BITS_PER_LONG == 64)
	{
	  image0 = r->sig[SIGSZ-1];
	  image1 = (image0 >> (64 - 56)) & 0xffffffff;
	  image0 = (image0 >> (64 - 56 + 1) >> 31) & 0x7fffff;
	}
      else
	{
	  image0 = r->sig[SIGSZ-1];
	  image1 = r->sig[SIGSZ-2];
	  image1 = (image0 << 24) | (image1 >> 8);
	  image0 = (image0 >> 8) & 0xffffff;
	}

      /* Rearrange the half-words of the significand to match the
	 external format.  */
      image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff007f;
      image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff;

      /* Add the sign and exponent.  */
      image0 |= sign;
      image0 |= (r->exp + 128) << 7;
      break;

    default:
      abort ();
    }

  if (FLOAT_WORDS_BIG_ENDIAN)
    buf[0] = image1, buf[1] = image0;
  else
    buf[0] = image0, buf[1] = image1;
}

static void
decode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
	      REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long image0, image1;
  int exp;

  if (FLOAT_WORDS_BIG_ENDIAN)
    image1 = buf[0], image0 = buf[1];
  else
    image0 = buf[0], image1 = buf[1];
  image0 &= 0xffffffff;
  image1 &= 0xffffffff;

  exp = (image0 >> 7) & 0xff;

  memset (r, 0, sizeof (*r));

  if (exp != 0)
    {
      r->class = rvc_normal;
      r->sign = (image0 >> 15) & 1;
      r->exp = exp - 128;

      /* Rearrange the half-words of the external format into
	 proper ascending order.  */
      image0 = ((image0 & 0x7f) << 16) | ((image0 >> 16) & 0xffff);
      image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff);

      if (HOST_BITS_PER_LONG == 64)
	{
	  image0 = (image0 << 31 << 1) | image1;
	  image0 <<= 64 - 56;
	  image0 |= SIG_MSB;
	  r->sig[SIGSZ-1] = image0;
	}
      else
	{
	  r->sig[SIGSZ-1] = image0;
	  r->sig[SIGSZ-2] = image1;
	  lshift_significand (r, r, 2*HOST_BITS_PER_LONG - 56);
	  r->sig[SIGSZ-1] |= SIG_MSB;
	}
    }
}

static void
encode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
	      const REAL_VALUE_TYPE *r)
{
  unsigned long image0, image1, sign = r->sign << 15;

  switch (r->class)
    {
    case rvc_zero:
      image0 = image1 = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      image0 = 0xffff7fff | sign;
      image1 = 0xffffffff;
      break;

    case rvc_normal:
      /* Extract the significand into straight hi:lo.  */
      if (HOST_BITS_PER_LONG == 64)
	{
	  image0 = r->sig[SIGSZ-1];
	  image1 = (image0 >> (64 - 53)) & 0xffffffff;
	  image0 = (image0 >> (64 - 53 + 1) >> 31) & 0xfffff;
	}
      else
	{
	  image0 = r->sig[SIGSZ-1];
	  image1 = r->sig[SIGSZ-2];
	  image1 = (image0 << 21) | (image1 >> 11);
	  image0 = (image0 >> 11) & 0xfffff;
	}

      /* Rearrange the half-words of the significand to match the
	 external format.  */
      image0 = ((image0 << 16) | (image0 >> 16)) & 0xffff000f;
      image1 = ((image1 << 16) | (image1 >> 16)) & 0xffffffff;

      /* Add the sign and exponent.  */
      image0 |= sign;
      image0 |= (r->exp + 1024) << 4;
      break;

    default:
      abort ();
    }

  if (FLOAT_WORDS_BIG_ENDIAN)
    buf[0] = image1, buf[1] = image0;
  else
    buf[0] = image0, buf[1] = image1;
}

static void
decode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED,
	      REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long image0, image1;
  int exp;

  if (FLOAT_WORDS_BIG_ENDIAN)
    image1 = buf[0], image0 = buf[1];
  else
    image0 = buf[0], image1 = buf[1];
  image0 &= 0xffffffff;
  image1 &= 0xffffffff;

  exp = (image0 >> 4) & 0x7ff;

  memset (r, 0, sizeof (*r));

  if (exp != 0)
    {
      r->class = rvc_normal;
      r->sign = (image0 >> 15) & 1;
      r->exp = exp - 1024;

      /* Rearrange the half-words of the external format into
	 proper ascending order.  */
      image0 = ((image0 & 0xf) << 16) | ((image0 >> 16) & 0xffff);
      image1 = ((image1 & 0xffff) << 16) | ((image1 >> 16) & 0xffff);

      if (HOST_BITS_PER_LONG == 64)
	{
	  image0 = (image0 << 31 << 1) | image1;
	  image0 <<= 64 - 53;
	  image0 |= SIG_MSB;
	  r->sig[SIGSZ-1] = image0;
	}
      else
	{
	  r->sig[SIGSZ-1] = image0;
	  r->sig[SIGSZ-2] = image1;
	  lshift_significand (r, r, 64 - 53);
	  r->sig[SIGSZ-1] |= SIG_MSB;
	}
    }
}

const struct real_format vax_f_format =
  {
    encode_vax_f,
    decode_vax_f,
    2,
    1,
    24,
    24,
    -127,
    127,
    15,
    false,
    false,
    false,
    false,
    false
  };

const struct real_format vax_d_format =
  {
    encode_vax_d,
    decode_vax_d,
    2,
    1,
    56,
    56,
    -127,
    127,
    15,
    false,
    false,
    false,
    false,
    false
  };

const struct real_format vax_g_format =
  {
    encode_vax_g,
    decode_vax_g,
    2,
    1,
    53,
    53,
    -1023,
    1023,
    15,
    false,
    false,
    false,
    false,
    false
  };

/* A good reference for these can be found in chapter 9 of
   "ESA/390 Principles of Operation", IBM document number SA22-7201-01.
   An on-line version can be found here:

   http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR001/9.1?DT=19930923083613
*/

static void encode_i370_single (const struct real_format *fmt,
				long *, const REAL_VALUE_TYPE *);
static void decode_i370_single (const struct real_format *,
				REAL_VALUE_TYPE *, const long *);
static void encode_i370_double (const struct real_format *fmt,
				long *, const REAL_VALUE_TYPE *);
static void decode_i370_double (const struct real_format *,
				REAL_VALUE_TYPE *, const long *);

static void
encode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
		    long *buf, const REAL_VALUE_TYPE *r)
{
  unsigned long sign, exp, sig, image;

  sign = r->sign << 31;

  switch (r->class)
    {
    case rvc_zero:
      image = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      image = 0x7fffffff | sign;
      break;

    case rvc_normal:
      sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0xffffff;
      exp = ((r->exp / 4) + 64) << 24;
      image = sign | exp | sig;
      break;

    default:
      abort ();
    }

  buf[0] = image;
}

static void
decode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
		    REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long sign, sig, image = buf[0];
  int exp;

  sign = (image >> 31) & 1;
  exp = (image >> 24) & 0x7f;
  sig = image & 0xffffff;

  memset (r, 0, sizeof (*r));

  if (exp || sig)
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = (exp - 64) * 4;
      r->sig[SIGSZ-1] = sig << (HOST_BITS_PER_LONG - 24);
      normalize (r);
    }
}

static void
encode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
		    long *buf, const REAL_VALUE_TYPE *r)
{
  unsigned long sign, exp, image_hi, image_lo;

  sign = r->sign << 31;

  switch (r->class)
    {
    case rvc_zero:
      image_hi = image_lo = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      image_hi = 0x7fffffff | sign;
      image_lo = 0xffffffff;
      break;

    case rvc_normal:
      if (HOST_BITS_PER_LONG == 64)
	{
	  image_hi = r->sig[SIGSZ-1];
	  image_lo = (image_hi >> (64 - 56)) & 0xffffffff;
	  image_hi = (image_hi >> (64 - 56 + 1) >> 31) & 0xffffff;
	}
      else
	{
	  image_hi = r->sig[SIGSZ-1];
	  image_lo = r->sig[SIGSZ-2];
	  image_lo = (image_lo >> 8) | (image_hi << 24);
	  image_hi >>= 8;
	}

      exp = ((r->exp / 4) + 64) << 24;
      image_hi |= sign | exp;
      break;

    default:
      abort ();
    }

  if (FLOAT_WORDS_BIG_ENDIAN)
    buf[0] = image_hi, buf[1] = image_lo;
  else
    buf[0] = image_lo, buf[1] = image_hi;
}

static void
decode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
		    REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long sign, image_hi, image_lo;
  int exp;

  if (FLOAT_WORDS_BIG_ENDIAN)
    image_hi = buf[0], image_lo = buf[1];
  else
    image_lo = buf[0], image_hi = buf[1];

  sign = (image_hi >> 31) & 1;
  exp = (image_hi >> 24) & 0x7f;
  image_hi &= 0xffffff;
  image_lo &= 0xffffffff;

  memset (r, 0, sizeof (*r));

  if (exp || image_hi || image_lo)
    {
      r->class = rvc_normal;
      r->sign = sign;
      r->exp = (exp - 64) * 4 + (SIGNIFICAND_BITS - 56);

      if (HOST_BITS_PER_LONG == 32)
	{
	  r->sig[0] = image_lo;
	  r->sig[1] = image_hi;
	}
      else
	r->sig[0] = image_lo | (image_hi << 31 << 1);

      normalize (r);
    }
}

const struct real_format i370_single_format =
  {
    encode_i370_single,
    decode_i370_single,
    16,
    4,
    6,
    6,
    -64,
    63,
    31,
    false,
    false,
    false, /* ??? The encoding does allow for "unnormals".  */
    false, /* ??? The encoding does allow for "unnormals".  */
    false
  };

const struct real_format i370_double_format =
  {
    encode_i370_double,
    decode_i370_double,
    16,
    4,
    14,
    14,
    -64,
    63,
    63,
    false,
    false,
    false, /* ??? The encoding does allow for "unnormals".  */
    false, /* ??? The encoding does allow for "unnormals".  */
    false
  };

/* The "twos-complement" c4x format is officially defined as

	x = s(~s).f * 2**e

   This is rather misleading.  One must remember that F is signed.
   A better description would be

	x = -1**s * ((s + 1 + .f) * 2**e

   So if we have a (4 bit) fraction of .1000 with a sign bit of 1,
   that's -1 * (1+1+(-.5)) == -1.5.  I think.

   The constructions here are taken from Tables 5-1 and 5-2 of the
   TMS320C4x User's Guide wherein step-by-step instructions for
   conversion from IEEE are presented.  That's close enough to our
   internal representation so as to make things easy.

   See http://www-s.ti.com/sc/psheets/spru063c/spru063c.pdf  */

static void encode_c4x_single (const struct real_format *fmt,
			       long *, const REAL_VALUE_TYPE *);
static void decode_c4x_single (const struct real_format *,
			       REAL_VALUE_TYPE *, const long *);
static void encode_c4x_extended (const struct real_format *fmt,
				 long *, const REAL_VALUE_TYPE *);
static void decode_c4x_extended (const struct real_format *,
				 REAL_VALUE_TYPE *, const long *);

static void
encode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
		   long *buf, const REAL_VALUE_TYPE *r)
{
  unsigned long image, exp, sig;

  switch (r->class)
    {
    case rvc_zero:
      exp = -128;
      sig = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      exp = 127;
      sig = 0x800000 - r->sign;
      break;

    case rvc_normal:
      exp = r->exp - 1;
      sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
      if (r->sign)
	{
	  if (sig)
	    sig = -sig;
	  else
	    exp--;
	  sig |= 0x800000;
	}
      break;

    default:
      abort ();
    }

  image = ((exp & 0xff) << 24) | (sig & 0xffffff);
  buf[0] = image;
}

static void
decode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
		   REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long image = buf[0];
  unsigned long sig;
  int exp, sf;

  exp = (((image >> 24) & 0xff) ^ 0x80) - 0x80;
  sf = ((image & 0xffffff) ^ 0x800000) - 0x800000;

  memset (r, 0, sizeof (*r));

  if (exp != -128)
    {
      r->class = rvc_normal;

      sig = sf & 0x7fffff;
      if (sf < 0)
	{
	  r->sign = 1;
	  if (sig)
	    sig = -sig;
	  else
	    exp++;
	}
      sig = (sig << (HOST_BITS_PER_LONG - 24)) | SIG_MSB;

      r->exp = exp + 1;
      r->sig[SIGSZ-1] = sig;
    }
}

static void
encode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED,
		     long *buf, const REAL_VALUE_TYPE *r)
{
  unsigned long exp, sig;

  switch (r->class)
    {
    case rvc_zero:
      exp = -128;
      sig = 0;
      break;

    case rvc_inf:
    case rvc_nan:
      exp = 127;
      sig = 0x80000000 - r->sign;
      break;

    case rvc_normal:
      exp = r->exp - 1;

      sig = r->sig[SIGSZ-1];
      if (HOST_BITS_PER_LONG == 64)
	sig = sig >> 1 >> 31;
      sig &= 0x7fffffff;

      if (r->sign)
	{
	  if (sig)
	    sig = -sig;
	  else
	    exp--;
	  sig |= 0x80000000;
	}
      break;

    default:
      abort ();
    }

  exp = (exp & 0xff) << 24;
  sig &= 0xffffffff;

  if (FLOAT_WORDS_BIG_ENDIAN)
    buf[0] = exp, buf[1] = sig;
  else
    buf[0] = sig, buf[0] = exp;
}

static void
decode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED,
		     REAL_VALUE_TYPE *r, const long *buf)
{
  unsigned long sig;
  int exp, sf;

  if (FLOAT_WORDS_BIG_ENDIAN)
    exp = buf[0], sf = buf[1];
  else
    sf = buf[0], exp = buf[1];

  exp = (((exp >> 24) & 0xff) & 0x80) - 0x80;
  sf = ((sf & 0xffffffff) ^ 0x80000000) - 0x80000000;

  memset (r, 0, sizeof (*r));

  if (exp != -128)
    {
      r->class = rvc_normal;

      sig = sf & 0x7fffffff;
      if (sf < 0)
	{
	  r->sign = 1;
	  if (sig)
	    sig = -sig;
	  else
	    exp++;
	}
      if (HOST_BITS_PER_LONG == 64)
	sig = sig << 1 << 31;
      sig |= SIG_MSB;

      r->exp = exp + 1;
      r->sig[SIGSZ-1] = sig;
    }
}

const struct real_format c4x_single_format =
  {
    encode_c4x_single,
    decode_c4x_single,
    2,
    1,
    24,
    24,
    -126,
    128,
    -1,
    false,
    false,
    false,
    false,
    false
  };

const struct real_format c4x_extended_format =
  {
    encode_c4x_extended,
    decode_c4x_extended,
    2,
    1,
    32,
    32,
    -126,
    128,
    -1,
    false,
    false,
    false,
    false,
    false
  };


/* A synthetic "format" for internal arithmetic.  It's the size of the
   internal significand minus the two bits needed for proper rounding.
   The encode and decode routines exist only to satisfy our paranoia
   harness.  */

static void encode_internal (const struct real_format *fmt,
			     long *, const REAL_VALUE_TYPE *);
static void decode_internal (const struct real_format *,
			     REAL_VALUE_TYPE *, const long *);

static void
encode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
		 const REAL_VALUE_TYPE *r)
{
  memcpy (buf, r, sizeof (*r));
}

static void
decode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED,
		 REAL_VALUE_TYPE *r, const long *buf)
{
  memcpy (r, buf, sizeof (*r));
}

const struct real_format real_internal_format =
  {
    encode_internal,
    decode_internal,
    2,
    1,
    SIGNIFICAND_BITS - 2,
    SIGNIFICAND_BITS - 2,
    -MAX_EXP,
    MAX_EXP,
    -1,
    true,
    true,
    false,
    true,
    true
  };

/* Calculate the square root of X in mode MODE, and store the result
   in R.  Return TRUE if the operation does not raise an exception.
   For details see "High Precision Division and Square Root",
   Alan H. Karp and Peter Markstein, HP Lab Report 93-93-42, June
   1993.  http://www.hpl.hp.com/techreports/93/HPL-93-42.pdf.  */

bool
real_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode,
	   const REAL_VALUE_TYPE *x)
{
  static REAL_VALUE_TYPE halfthree;
  static bool init = false;
  REAL_VALUE_TYPE h, t, i;
  int iter, exp;

  /* sqrt(-0.0) is -0.0.  */
  if (real_isnegzero (x))
    {
      *r = *x;
      return false;
    }

  /* Negative arguments return NaN.  */
  if (real_isneg (x))
    {
      get_canonical_qnan (r, 0);
      return false;
    }

  /* Infinity and NaN return themselves.  */
  if (real_isinf (x) || real_isnan (x))
    {
      *r = *x;
      return false;
    }

  if (!init)
    {
      do_add (&halfthree, &dconst1, &dconsthalf, 0);
      init = true;
    }

  /* Initial guess for reciprocal sqrt, i.  */
  exp = real_exponent (x);
  real_ldexp (&i, &dconst1, -exp/2);

  /* Newton's iteration for reciprocal sqrt, i.  */
  for (iter = 0; iter < 16; iter++)
    {
      /* i(n+1) = i(n) * (1.5 - 0.5*i(n)*i(n)*x).  */
      do_multiply (&t, x, &i);
      do_multiply (&h, &t, &i);
      do_multiply (&t, &h, &dconsthalf);
      do_add (&h, &halfthree, &t, 1);
      do_multiply (&t, &i, &h);

      /* Check for early convergence.  */
      if (iter >= 6 && real_identical (&i, &t))
	break;

      /* ??? Unroll loop to avoid copying.  */
      i = t;
    }

  /* Final iteration: r = i*x + 0.5*i*x*(1.0 - i*(i*x)).  */
  do_multiply (&t, x, &i);
  do_multiply (&h, &t, &i);
  do_add (&i, &dconst1, &h, 1);
  do_multiply (&h, &t, &i);
  do_multiply (&i, &dconsthalf, &h);
  do_add (&h, &t, &i, 0);

  /* ??? We need a Tuckerman test to get the last bit.  */

  real_convert (r, mode, &h);
  return true;
}

/* Calculate X raised to the integer exponent N in mode MODE and store
   the result in R.  Return true if the result may be inexact due to
   loss of precision.  The algorithm is the classic "left-to-right binary
   method" described in section 4.6.3 of Donald Knuth's "Seminumerical
   Algorithms", "The Art of Computer Programming", Volume 2.  */

bool
real_powi (REAL_VALUE_TYPE *r, enum machine_mode mode,
	   const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
{
  unsigned HOST_WIDE_INT bit;
  REAL_VALUE_TYPE t;
  bool inexact = false;
  bool init = false;
  bool neg;
  int i;

  if (n == 0)
    {
      *r = dconst1;
      return false;
    }
  else if (n < 0)
    {
      /* Don't worry about overflow, from now on n is unsigned.  */
      neg = true;
      n = -n;
    }
  else
    neg = false;

  t = *x;
  bit = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
  for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
    {
      if (init)
	{
	  inexact |= do_multiply (&t, &t, &t);
	  if (n & bit)
	    inexact |= do_multiply (&t, &t, x);
	}
      else if (n & bit)
	init = true;
      bit >>= 1;
    }

  if (neg)
    inexact |= do_divide (&t, &dconst1, &t);

  real_convert (r, mode, &t);
  return inexact;
}

/* Round X to the nearest integer not larger in absolute value, i.e.
   towards zero, placing the result in R in mode MODE.  */

void
real_trunc (REAL_VALUE_TYPE *r, enum machine_mode mode,
	    const REAL_VALUE_TYPE *x)
{
  do_fix_trunc (r, x);
  if (mode != VOIDmode)
    real_convert (r, mode, r);
}

/* Round X to the largest integer not greater in value, i.e. round
   down, placing the result in R in mode MODE.  */

void
real_floor (REAL_VALUE_TYPE *r, enum machine_mode mode,
	    const REAL_VALUE_TYPE *x)
{
  do_fix_trunc (r, x);
  if (! real_identical (r, x) && r->sign)
    do_add (r, r, &dconstm1, 0);
  if (mode != VOIDmode)
    real_convert (r, mode, r);
}

/* Round X to the smallest integer not less then argument, i.e. round
   up, placing the result in R in mode MODE.  */

void
real_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode,
	   const REAL_VALUE_TYPE *x)
{
  do_fix_trunc (r, x);
  if (! real_identical (r, x) && ! r->sign)
    do_add (r, r, &dconst1, 0);
  if (mode != VOIDmode)
    real_convert (r, mode, r);
}
