/* real.c - software floating point emulation.
   Copyright (C) 1993-2021 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 3, 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 COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "realmpfr.h"
#include "dfp.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 26.  */


/* 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 void decimal_from_integer (REAL_VALUE_TYPE *);
static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
				    size_t);

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->cl = 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->cl = 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->cl = 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;

  /* We are actually passing N == SIGNIFICAND_BITS which would result
     in an out-of-bound access below.  */
  if (n % HOST_BITS_PER_LONG != 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;

  if (r->decimal)
    return;

  /* 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->cl = rvc_zero;
      SET_REAL_EXP (r, 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 = REAL_EXP (r) - shift;
      if (exp > MAX_EXP)
	get_inf (r, r->sign);
      else if (exp < -MAX_EXP)
	get_zero (r, r->sign);
      else
	{
	  SET_REAL_EXP (r, 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->cl, b->cl))
    {
    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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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:
      gcc_unreachable ();
    }

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

  /* 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->cl = rvc_normal;
  r->sign = sign;
  SET_REAL_EXP (r, exp);
  /* Zero out the remaining fields.  */
  r->signalling = 0;
  r->canonical = 0;
  r->decimal = 0;

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

  /* Special case: if the subtraction results in zero, the result
     is positive.  */
  if (r->cl == 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->cl, b->cl))
    {
    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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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:
      gcc_unreachable ();
    }

  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 = (REAL_EXP (a) - (2*SIGSZ-1-i)*(HOST_BITS_PER_LONG/2)
		     + (REAL_EXP (b) - (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.cl = rvc_normal;
	  SET_REAL_EXP (&u, 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->cl, b->cl))
    {
    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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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;
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      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:
      gcc_unreachable ();
    }

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

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

  exp = REAL_EXP (a) - REAL_EXP (b) + 1;
  if (exp > MAX_EXP)
    {
      get_inf (r, sign);
      return true;
    }
  if (exp < -MAX_EXP)
    {
      get_zero (r, sign);
      return true;
    }
  SET_REAL_EXP (rr, 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->cl, b->cl))
    {
    case CLASS2 (rvc_zero, rvc_zero):
      /* Sign of zero doesn't matter for compares.  */
      return 0;

    case CLASS2 (rvc_normal, rvc_zero):
      /* Decimal float zero is special and uses rvc_normal, not rvc_zero.  */
      if (a->decimal)
	return decimal_do_compare (a, b, nan_result);
      /* Fall through.  */
    case CLASS2 (rvc_inf, rvc_zero):
    case CLASS2 (rvc_inf, rvc_normal):
      return (a->sign ? -1 : 1);

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

    case CLASS2 (rvc_zero, rvc_normal):
      /* Decimal float zero is special and uses rvc_normal, not rvc_zero.  */
      if (b->decimal)
	return decimal_do_compare (a, b, nan_result);
      /* Fall through.  */
    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:
      gcc_unreachable ();
    }

  if (a->decimal || b->decimal)
    return decimal_do_compare (a, b, nan_result);

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

  if (REAL_EXP (a) > REAL_EXP (b))
    ret = 1;
  else if (REAL_EXP (a) < REAL_EXP (b))
    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->cl)
    {
    case rvc_zero:
    case rvc_inf:
    case rvc_nan:
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      break;

    case rvc_normal:
      if (r->decimal)
	{
	  decimal_do_fix_trunc (r, a);
	  return;
	}
      if (REAL_EXP (r) <= 0)
	get_zero (r, r->sign);
      else if (REAL_EXP (r) < SIGNIFICAND_BITS)
	clear_significand_below (r, SIGNIFICAND_BITS - REAL_EXP (r));
      break;

    default:
      gcc_unreachable ();
    }
}

/* Perform the binary or unary operation described by CODE.
   For a unary operation, leave OP1 NULL.  This function returns
   true if the result may be inexact due to loss of precision.  */

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

  if (op0->decimal || (op1 && op1->decimal))
    return decimal_real_arithmetic (r, code, op0, op1);

  switch (code)
    {
    case PLUS_EXPR:
      /* Clear any padding areas in *r if it isn't equal to one of the
	 operands so that we can later do bitwise comparisons later on.  */
      if (r != op0 && r != op1)
	memset (r, '\0', sizeof (*r));
      return do_add (r, op0, op1, 0);

    case MINUS_EXPR:
      if (r != op0 && r != op1)
	memset (r, '\0', sizeof (*r));
      return do_add (r, op0, op1, 1);

    case MULT_EXPR:
      if (r != op0 && r != op1)
	memset (r, '\0', sizeof (*r));
      return do_multiply (r, op0, op1);

    case RDIV_EXPR:
      if (r != op0 && r != op1)
	memset (r, '\0', sizeof (*r));
      return do_divide (r, op0, op1);

    case MIN_EXPR:
      if (op1->cl == rvc_nan)
      {
	*r = *op1;
	/* Make resulting NaN value to be qNaN. The caller has the
	   responsibility to avoid the operation if flag_signaling_nans
           is on.  */
	r->signalling = 0;
      }
      else if (do_compare (op0, op1, -1) < 0)
	*r = *op0;
      else
	*r = *op1;
      break;

    case MAX_EXPR:
      if (op1->cl == rvc_nan)
      {
	*r = *op1;
	/* Make resulting NaN value to be qNaN. The caller has the
	   responsibility to avoid the operation if flag_signaling_nans
           is on.  */
	r->signalling = 0;
      }
      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:
      gcc_unreachable ();
    }
  return false;
}

REAL_VALUE_TYPE
real_value_negate (const REAL_VALUE_TYPE *op0)
{
  REAL_VALUE_TYPE r;
  real_arithmetic (&r, NEGATE_EXPR, op0, NULL);
  return r;
}

REAL_VALUE_TYPE
real_value_abs (const REAL_VALUE_TYPE *op0)
{
  REAL_VALUE_TYPE r;
  real_arithmetic (&r, ABS_EXPR, op0, NULL);
  return r;
}

/* Return whether OP0 == OP1.  */

bool
real_equal (const REAL_VALUE_TYPE *op0, const REAL_VALUE_TYPE *op1)
{
  return do_compare (op0, op1, -1) == 0;
}

/* Return whether OP0 < OP1.  */

bool
real_less (const REAL_VALUE_TYPE *op0, const REAL_VALUE_TYPE *op1)
{
  return do_compare (op0, op1, 1) < 0;
}

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

  switch (code)
    {
    case LT_EXPR:
      return real_less (op0, op1);
    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 real_equal (op0, op1);
    case NE_EXPR:
      return do_compare (op0, op1, -1) != 0;
    case UNORDERED_EXPR:
      return op0->cl == rvc_nan || op1->cl == rvc_nan;
    case ORDERED_EXPR:
      return op0->cl != rvc_nan && op1->cl != 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;
    case LTGT_EXPR:
      return do_compare (op0, op1, 0) != 0;

    default:
      gcc_unreachable ();
    }
}

/* Return floor log2(R).  */

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

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

void
real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
{
  *r = *op0;
  switch (r->cl)
    {
    case rvc_zero:
    case rvc_inf:
    case rvc_nan:
      /* Make resulting NaN value to be qNaN. The caller has the
         responsibility to avoid the operation if flag_signaling_nans
         is on.  */
      r->signalling = 0;
      break;

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

    default:
      gcc_unreachable ();
    }
}

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

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

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

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

/* Determine whether a floating-point value X is a signaling NaN.  */ 
bool real_issignaling_nan (const REAL_VALUE_TYPE *r)
{
  return real_isnan (r) && r->signalling;
}

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

bool
real_isfinite (const REAL_VALUE_TYPE *r)
{
  return (r->cl != rvc_nan) && (r->cl != rvc_inf);
}

/* 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->cl == 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->cl != b->cl)
    return false;
  if (a->sign != b->sign)
    return false;

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

    case rvc_normal:
      if (a->decimal != b->decimal)
        return false;
      if (REAL_EXP (a) != REAL_EXP (b))
	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:
      gcc_unreachable ();
    }

  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 format FMT.
   Return true if successful.  */

bool
exact_real_inverse (format_helper fmt, REAL_VALUE_TYPE *r)
{
  const REAL_VALUE_TYPE *one = real_digit (1);
  REAL_VALUE_TYPE u;
  int i;

  if (r->cl != 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 format.  */
  do_divide (&u, one, r);
  real_convert (&u, fmt, &u);

  /* The rounding may have overflowed.  */
  if (u.cl != 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;
}

/* Return true if arithmetic on values in IMODE that were promoted
   from values in TMODE is equivalent to direct arithmetic on values
   in TMODE.  */

bool
real_can_shorten_arithmetic (machine_mode imode, machine_mode tmode)
{
  const struct real_format *tfmt, *ifmt;
  tfmt = REAL_MODE_FORMAT (tmode);
  ifmt = REAL_MODE_FORMAT (imode);
  /* These conditions are conservative rather than trying to catch the
     exact boundary conditions; the main case to allow is IEEE float
     and double.  */
  return (ifmt->b == tfmt->b
	  && ifmt->p > 2 * tfmt->p
	  && ifmt->emin < 2 * tfmt->emin - tfmt->p - 2
	  && ifmt->emin < tfmt->emin - tfmt->emax - tfmt->p - 2
	  && ifmt->emax > 2 * tfmt->emax + 2
	  && ifmt->emax > tfmt->emax - tfmt->emin + tfmt->p + 2
	  && ifmt->round_towards_zero == tfmt->round_towards_zero
	  && (ifmt->has_sign_dependent_rounding
	      == tfmt->has_sign_dependent_rounding)
	  && ifmt->has_nans >= tfmt->has_nans
	  && ifmt->has_inf >= tfmt->has_inf
	  && ifmt->has_signed_zero >= tfmt->has_signed_zero
	  && !MODE_COMPOSITE_P (tmode)
	  && !MODE_COMPOSITE_P (imode));
}

/* Render R as an integer.  */

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

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

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

    case rvc_normal:
      if (r->decimal)
	return decimal_real_to_integer (r);

      if (REAL_EXP (r) <= 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 (REAL_EXP (r) > HOST_BITS_PER_WIDE_INT)
	goto overflow;

      if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
	i = r->sig[SIGSZ-1];
      else
	{
	  gcc_assert (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];
	}

      i >>= HOST_BITS_PER_WIDE_INT - REAL_EXP (r);

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

    default:
      gcc_unreachable ();
    }
}

/* Likewise, but producing a wide-int of PRECISION.  If the value cannot
   be represented in precision, *FAIL is set to TRUE.  */

wide_int
real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision)
{
  HOST_WIDE_INT val[2 * WIDE_INT_MAX_ELTS];
  int exp;
  int words, w;
  wide_int result;

  switch (r->cl)
    {
    case rvc_zero:
    underflow:
      return wi::zero (precision);

    case rvc_inf:
    case rvc_nan:
    overflow:
      *fail = true;

      if (r->sign)
	return wi::set_bit_in_zero (precision - 1, precision);
      else
	return ~wi::set_bit_in_zero (precision - 1, precision);

    case rvc_normal:
      if (r->decimal)
	return decimal_real_to_integer (r, fail, precision);

      exp = REAL_EXP (r);
      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 > precision)
	goto overflow;

      /* Put the significand into a wide_int that has precision W, which
	 is the smallest HWI-multiple that has at least PRECISION bits.
	 This ensures that the top bit of the significand is in the
	 top bit of the wide_int.  */
      words = (precision + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT;
      w = words * HOST_BITS_PER_WIDE_INT;

#if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
      for (int i = 0; i < words; i++)
	{
	  int j = SIGSZ - words + i;
	  val[i] = (j < 0) ? 0 : r->sig[j];
	}
#else
      gcc_assert (HOST_BITS_PER_WIDE_INT == 2 * HOST_BITS_PER_LONG);
      for (int i = 0; i < words; i++)
	{
	  int j = SIGSZ - (words * 2) + (i * 2);
	  if (j < 0)
	    val[i] = 0;
	  else
	    val[i] = r->sig[j];
	  j += 1;
	  if (j >= 0)
	    val[i] |= (unsigned HOST_WIDE_INT) r->sig[j] << HOST_BITS_PER_LONG;
	}
#endif
      /* Shift the value into place and truncate to the desired precision.  */
      result = wide_int::from_array (val, words, w);
      result = wi::lrshift (result, w - exp);
      result = wide_int::from (result, precision, UNSIGNED);

      if (r->sign)
	return -result;
      else
	return result;

    default:
      gcc_unreachable ();
    }
}

/* 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 = REAL_EXP (num), expd = REAL_EXP (den);

  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);

  SET_REAL_EXP (num, 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.  If MODE is VOIDmode, round to nearest value.  Otherwise, round
   to a string that, when parsed back in mode MODE, yields the same value.  */

#define M_LOG10_2	0.30102999566398119521

void
real_to_decimal_for_mode (char *str, const REAL_VALUE_TYPE *r_orig,
			  size_t buf_size, size_t digits,
			  int crop_trailing_zeros, machine_mode mode)
{
  const struct real_format *fmt = NULL;
  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;
  bool round_up;

  if (mode != VOIDmode)
   {
     fmt = REAL_MODE_FORMAT (mode);
     gcc_assert (fmt);
   }

  r = *r_orig;
  switch (r.cl)
    {
    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?  */
      sprintf (str, "%c%cNaN", (r_orig->sign ? '-' : '+'),
	       (r_orig->signalling ? 'S' : 'Q'));
      return;
    default:
      gcc_unreachable ();
    }

  if (r.decimal)
    {
      decimal_real_to_decimal (str, &r, buf_size, digits, crop_trailing_zeros);
      return;
    }

  /* 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 = REAL_EXP (&r) * 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;
  gcc_assert (max_digits <= buf_size);
  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;
      SET_REAL_EXP (&u, 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.  */
      SET_REAL_EXP (&u, REAL_EXP (&u) + REAL_EXP (&r)
		    - (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 (REAL_EXP (&r) > 0)
	{
	  m = floor_log2 ((int)(REAL_EXP (&r) * 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 or zero.  */
	  if (REAL_EXP (&u) > 0 || u.cl == rvc_zero)
	    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)(-REAL_EXP (&r) * 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;
      gcc_assert (digit != 0);
    }

  /* ... or overflow.  */
  if (digit == 10)
    {
      *p++ = '1';
      if (--digits > 0)
	*p++ = '0';
      dec_exp += 1;
    }
  else
    {
      gcc_assert (digit <= 10);
      *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 (fmt && fmt->round_towards_zero)
    {
      /* If the format uses round towards zero when parsing the string
	 back in, we need to always round away from zero here.  */
      if (cmp_significand_0 (&r))
	digit++;
      round_up = digit > 0;
    }
  else
    {
      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++;
	}

      round_up = digit > 5;
    }

  if (round_up)
    {
      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);

  /* Verify that we can read the original value back in.  */
  if (flag_checking && mode != VOIDmode)
    {
      real_from_string (&r, str);
      real_convert (&r, mode, &r);
      gcc_assert (real_identical (&r, r_orig));
    }
}

/* Likewise, except always uses round-to-nearest.  */

void
real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
		 size_t digits, int crop_trailing_zeros)
{
  real_to_decimal_for_mode (str, r_orig, buf_size,
			    digits, crop_trailing_zeros, VOIDmode);
}

/* 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 = REAL_EXP (r);
  char *p, *first;
  char exp_buf[16];
  size_t max_digits;

  switch (r->cl)
    {
    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?  */
      sprintf (str, "%c%cNaN", (r->sign ? '-' : '+'),
	       (r->signalling ? 'S' : 'Q'));
      return;
    default:
      gcc_unreachable ();
    }

  if (r->decimal)
    {
      /* Hexadecimal format for decimal floats is not interesting. */
      strcpy (str, "N/A");
      return;
    }

  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;
  gcc_assert (max_digits <= buf_size);
  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.  Return -1 if the
   value underflows, +1 if overflows, and 0 otherwise. */

int
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 (startswith (str, "QNaN"))
    {
      get_canonical_qnan (r, sign);
      return 0;
    }
  else if (startswith (str, "SNaN"))
    {
      get_canonical_snan (r, sign);
      return 0;
    }
  else if (startswith (str, "Inf"))
    {
      get_inf (r, sign);
      return 0;
    }

  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;
	    }
	  else if (d)
	    /* Ensure correct rounding by setting last bit if there is
	       a subsequent nonzero digit.  */
	    r->sig[0] |= 1;
	  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;
		}
	      else if (d)
		/* Ensure correct rounding by setting last bit if there is
		   a subsequent nonzero digit.  */
		r->sig[0] |= 1;
	      str++;
	    }
	}

      /* If the mantissa is zero, ignore the exponent.  */
      if (!cmp_significand_0 (r))
	goto is_a_zero;

      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->cl = rvc_normal;
      SET_REAL_EXP (r, exp);

      normalize (r);
    }
  else
    {
      /* Decimal floating point.  */
      const char *cstr = str;
      mpfr_t m;
      bool inexact;

      while (*cstr == '0')
	cstr++;
      if (*cstr == '.')
	{
	  cstr++;
	  while (*cstr == '0')
	    cstr++;
	}

      /* If the mantissa is zero, ignore the exponent.  */
      if (!ISDIGIT (*cstr))
	goto is_a_zero;

      /* Nonzero value, possibly overflowing or underflowing.  */
      mpfr_init2 (m, SIGNIFICAND_BITS);
      inexact = mpfr_strtofr (m, str, NULL, 10, MPFR_RNDZ);
      /* The result should never be a NaN, and because the rounding is
	 toward zero should never be an infinity.  */
      gcc_assert (!mpfr_nan_p (m) && !mpfr_inf_p (m));
      if (mpfr_zero_p (m) || mpfr_get_exp (m) < -MAX_EXP + 4)
	{
	  mpfr_clear (m);
	  goto underflow;
	}
      else if (mpfr_get_exp (m) > MAX_EXP - 4)
	{
	  mpfr_clear (m);
	  goto overflow;
	}
      else
	{
	  real_from_mpfr (r, m, NULL_TREE, MPFR_RNDZ);
	  /* 1 to 3 bits may have been shifted off (with a sticky bit)
	     because the hex digits used in real_from_mpfr did not
	     start with a digit 8 to f, but the exponent bounds above
	     should have avoided underflow or overflow.  */
	  gcc_assert (r->cl == rvc_normal);
	  /* Set a sticky bit if mpfr_strtofr was inexact.  */
	  r->sig[0] |= inexact;
	  mpfr_clear (m);
	}
    }

  r->sign = sign;
  return 0;

 is_a_zero:
  get_zero (r, sign);
  return 0;

 underflow:
  get_zero (r, sign);
  return -1;

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

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

REAL_VALUE_TYPE
real_from_string2 (const char *s, format_helper fmt)
{
  REAL_VALUE_TYPE r;

  real_from_string (&r, s);
  if (fmt)
    real_convert (&r, fmt, &r);

  return r;
}

/* Initialize R from string S and desired format FMT. */

void
real_from_string3 (REAL_VALUE_TYPE *r, const char *s, format_helper fmt)
{
  if (fmt.decimal_p ())
    decimal_real_from_string (r, s);
  else
    real_from_string (r, s);

  if (fmt)
    real_convert (r, fmt, r);
}

/* Initialize R from the wide_int VAL_IN.  Round it to format FMT if
   FMT is nonnull.  */

void
real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
		   const wide_int_ref &val_in, signop sgn)
{
  if (val_in == 0)
    get_zero (r, 0);
  else
    {
      unsigned int len = val_in.get_precision ();
      int i, j, e = 0;
      int maxbitlen = MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT;
      const unsigned int realmax = (SIGNIFICAND_BITS / HOST_BITS_PER_WIDE_INT
				    * HOST_BITS_PER_WIDE_INT);

      memset (r, 0, sizeof (*r));
      r->cl = rvc_normal;
      r->sign = wi::neg_p (val_in, sgn);

      /* We have to ensure we can negate the largest negative number.  */
      wide_int val = wide_int::from (val_in, maxbitlen, sgn);

      if (r->sign)
	val = -val;

      /* Ensure a multiple of HOST_BITS_PER_WIDE_INT, ceiling, as elt
	 won't work with precisions that are not a multiple of
	 HOST_BITS_PER_WIDE_INT.  */
      len += HOST_BITS_PER_WIDE_INT - 1;

      /* Ensure we can represent the largest negative number.  */
      len += 1;

      len = len/HOST_BITS_PER_WIDE_INT * HOST_BITS_PER_WIDE_INT;

      /* Cap the size to the size allowed by real.h.  */
      if (len > realmax)
	{
	  HOST_WIDE_INT cnt_l_z;
	  cnt_l_z = wi::clz (val);

	  if (maxbitlen - cnt_l_z > realmax)
	    {
	      e = maxbitlen - cnt_l_z - realmax;

	      /* This value is too large, we must shift it right to
		 preserve all the bits we can, and then bump the
		 exponent up by that amount.  */
	      val = wi::lrshift (val, e);
	    }
	  len = realmax;
	}

      /* Clear out top bits so elt will work with precisions that aren't
	 a multiple of HOST_BITS_PER_WIDE_INT.  */
      val = wide_int::from (val, len, sgn);
      len = len / HOST_BITS_PER_WIDE_INT;

      SET_REAL_EXP (r, len * HOST_BITS_PER_WIDE_INT + e);

      j = SIGSZ - 1;
      if (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT)
	for (i = len - 1; i >= 0; i--)
	  {
	    r->sig[j--] = val.elt (i);
	    if (j < 0)
	      break;
	  }
      else
	{
	  gcc_assert (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT);
	  for (i = len - 1; i >= 0; i--)
	    {
	      HOST_WIDE_INT e = val.elt (i);
	      r->sig[j--] = e >> (HOST_BITS_PER_LONG - 1) >> 1;
	      if (j < 0)
		break;
	      r->sig[j--] = e;
	      if (j < 0)
		break;
	    }
	}

      normalize (r);
    }

  if (fmt.decimal_p ())
    decimal_from_integer (r);
  if (fmt)
    real_convert (r, fmt, r);
}

/* Render R, an integral value, as a floating point constant with no
   specified exponent.  */

static void
decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
			size_t buf_size)
{
  int dec_exp, digit, digits;
  REAL_VALUE_TYPE r, pten;
  char *p;
  bool sign;

  r = *r_orig;

  if (r.cl == rvc_zero)
    {
      strcpy (str, "0.");
      return;
    }

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

  dec_exp = REAL_EXP (&r) * M_LOG10_2;
  digits = dec_exp + 1;
  gcc_assert ((digits + 2) < (int)buf_size);

  pten = *real_digit (1);
  times_pten (&pten, dec_exp);

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

  digit = rtd_divmod (&r, &pten);
  gcc_assert (digit >= 0 && digit <= 9);
  *p++ = digit + '0';
  while (--digits > 0)
    {
      times_pten (&r, 1);
      digit = rtd_divmod (&r, &pten);
      *p++ = digit + '0';
    }
  *p++ = '.';
  *p++ = '\0';
}

/* Convert a real with an integral value to decimal float.  */

static void
decimal_from_integer (REAL_VALUE_TYPE *r)
{
  char str[256];

  decimal_integer_string (str, r, sizeof (str) - 1);
  decimal_real_from_string (r, str);
}

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

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

  gcc_assert (n >= 0);
  gcc_assert (n < EXP_BITS);

  if (tens[n].cl == 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, UNSIGNED);
	}
      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];

  gcc_assert (n >= 0);
  gcc_assert (n < EXP_BITS);

  if (tens[n].cl == 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];

  gcc_assert (n >= 0);
  gcc_assert (n <= 9);

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

  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);
}

/* Returns the special REAL_VALUE_TYPE corresponding to 'e'.  */

const REAL_VALUE_TYPE *
dconst_e_ptr (void)
{
  static REAL_VALUE_TYPE value;

  /* Initialize mathematical constants for constant folding builtins.
     These constants need to be given to at least 160 bits precision.  */
  if (value.cl == rvc_zero)
    {
      mpfr_t m;
      mpfr_init2 (m, SIGNIFICAND_BITS);
      mpfr_set_ui (m, 1, MPFR_RNDN);
      mpfr_exp (m, m, MPFR_RNDN);
      real_from_mpfr (&value, m, NULL_TREE, MPFR_RNDN);
      mpfr_clear (m);

    }
  return &value;
}

/* Returns a cached REAL_VALUE_TYPE corresponding to 1/n, for various n.  */

#define CACHED_FRACTION(NAME, N)					\
  const REAL_VALUE_TYPE *						\
  NAME (void)								\
  {									\
    static REAL_VALUE_TYPE value;					\
									\
    /* Initialize mathematical constants for constant folding builtins.	\
       These constants need to be given to at least 160 bits		\
       precision.  */							\
    if (value.cl == rvc_zero)						\
      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (N));	\
    return &value;							\
  }

CACHED_FRACTION (dconst_third_ptr, 3)
CACHED_FRACTION (dconst_quarter_ptr, 4)
CACHED_FRACTION (dconst_sixth_ptr, 6)
CACHED_FRACTION (dconst_ninth_ptr, 9)

/* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */

const REAL_VALUE_TYPE *
dconst_sqrt2_ptr (void)
{
  static REAL_VALUE_TYPE value;

  /* Initialize mathematical constants for constant folding builtins.
     These constants need to be given to at least 160 bits precision.  */
  if (value.cl == rvc_zero)
    {
      mpfr_t m;
      mpfr_init2 (m, SIGNIFICAND_BITS);
      mpfr_sqrt_ui (m, 2, MPFR_RNDN);
      real_from_mpfr (&value, m, NULL_TREE, MPFR_RNDN);
      mpfr_clear (m);
    }
  return &value;
}

/* 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,
	  format_helper fmt)
{
  if (*str == 0)
    {
      if (quiet)
	get_canonical_qnan (r, 0);
      else
	get_canonical_snan (r, 0);
    }
  else
    {
      int base = 10, d;

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

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

      while (ISSPACE (*str))
	str++;
      if (*str == '-')
	str++;
      else if (*str == '+')
	str++;
      if (*str == '0')
	{
	  str++;
	  if (*str == 'x' || *str == 'X')
	    {
	      base = 16;
	      str++;
	    }
	  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:
	      gcc_unreachable ();
	    }

	  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 signaling 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, machine_mode mode)
{
  const struct real_format *fmt;
  int np2;

  fmt = REAL_MODE_FORMAT (mode);
  gcc_assert (fmt);
  memset (r, 0, sizeof (*r));

  if (fmt->b == 10)
    decimal_real_maxval (r, sign, mode);
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, fmt->emax);

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

      if (fmt->pnan < fmt->p)
	/* This is an IBM extended double format made up of two IEEE
	   doubles.  The value of the long double is the sum of the
	   values of the two parts.  The most significant part is
	   required to be the value of the long double rounded to the
	   nearest double.  Rounding means we need a slightly smaller
	   value for LDBL_MAX.  */
	clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan - 1);
    }
}

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

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

  n++;
  if (n > MAX_EXP)
    r->cl = rvc_inf;
  else if (n < -MAX_EXP)
    ;
  else
    {
      r->cl = rvc_normal;
      SET_REAL_EXP (r, n);
      r->sig[SIGSZ-1] = SIG_MSB;
    }
  if (fmt.decimal_p ())
    decimal_real_convert (r, fmt, r);
}


static void
round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
{
  int p2, np2, i, w;
  int emin2m1, emax2;
  bool round_up = false;

  if (r->decimal)
    {
      if (fmt->b == 10)
	{
	  decimal_round_for_format (fmt, r);
	  return;
	}
      /* FIXME. We can come here via fp_easy_constant
	 (e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not
	 investigated whether this convert needs to be here, or
	 something else is missing. */
      decimal_real_convert (r, REAL_MODE_FORMAT (DFmode), r);
    }

  p2 = fmt->p;
  emin2m1 = fmt->emin - 1;
  emax2 = fmt->emax;

  np2 = SIGNIFICAND_BITS - p2;
  switch (r->cl)
    {
    underflow:
      get_zero (r, r->sign);
      /* FALLTHRU */
    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:
      gcc_unreachable ();
    }

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

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

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

  if (!fmt->round_towards_zero)
    {
      /* 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.  */
      unsigned long sticky;
      bool guard, lsb;

      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.  */
      round_up = guard && (sticky || lsb);
    }

  if (round_up)
    {
      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.  */
	  SET_REAL_EXP (r, REAL_EXP (r) + 1);
	  if (REAL_EXP (r) > emax2)
	    goto overflow;
	  r->sig[SIGSZ-1] = SIG_MSB;
	}
    }

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

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

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

void
real_convert (REAL_VALUE_TYPE *r, format_helper fmt,
	      const REAL_VALUE_TYPE *a)
{
  *r = *a;

  if (a->decimal || fmt->b == 10)
    decimal_real_convert (r, fmt, a);

  round_for_format (fmt, r);

  /* Make resulting NaN value to be qNaN. The caller has the
     responsibility to avoid the operation if flag_signaling_nans
     is on.  */
  if (r->cl == rvc_nan)
    r->signalling = 0;

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

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

REAL_VALUE_TYPE
real_value_truncate (format_helper fmt, REAL_VALUE_TYPE a)
{
  REAL_VALUE_TYPE r;
  real_convert (&r, fmt, &a);
  return r;
}

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

bool
exact_real_truncate (format_helper fmt, const REAL_VALUE_TYPE *a)
{
  REAL_VALUE_TYPE t;
  int emin2m1;

  /* Don't allow conversion to denormals.  */
  emin2m1 = fmt->emin - 1;
  if (REAL_EXP (a) <= emin2m1)
    return false;

  /* After conversion to the new format, the value must be identical.  */
  real_convert (&t, fmt, 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 (long *buf, const REAL_VALUE_TYPE *r_orig,
		format_helper 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;
}

/* 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 (REAL_VALUE_TYPE *r, const long *buf, format_helper fmt)
{
  (*fmt->decode) (fmt, r, buf);
}

/* Return the number of bits of the largest binary value that the
   significand of FMT will hold.  */
/* ??? Legacy.  Should get access to real_format directly.  */

int
significand_size (format_helper fmt)
{
  if (fmt == NULL)
    return 0;

  if (fmt->b == 10)
    {
      /* Return the size in bits of the largest binary value that can be
	 held by the decimal coefficient for this format.  This is one more
	 than the number of bits required to hold the largest coefficient
	 of this format.  */
      double log2_10 = 3.3219281;
      return fmt->p * log2_10;
    }
  return fmt->p;
}

/* 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->cl | (r->sign << 2);
  switch (r->cl)
    {
    case rvc_zero:
    case rvc_inf:
      return h;

    case rvc_normal:
      h |= (unsigned int)REAL_EXP (r) << 3;
      break;

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

    default:
      gcc_unreachable ();
    }

  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->cl)
    {
    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 = (fmt->canonical_nan_lsbs_set ? (1 << 22) - 1 : 0);
	  if (r->signalling == fmt->qnan_msb_set)
	    sig &= ~(1 << 22);
	  else
	    sig |= 1 << 22;
	  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 = REAL_EXP (r) + 127 - 1;
      image |= exp << 23;
      image |= sig;
      break;

    default:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
	  r->sign = sign;
	  SET_REAL_EXP (r, -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->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, exp - 127 + 1);
      r->sig[SIGSZ-1] = image | SIG_MSB;
    }
}

const struct real_format ieee_single_format =
  {
    encode_ieee_single,
    decode_ieee_single,
    2,
    24,
    24,
    -125,
    128,
    31,
    31,
    32,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_single"
  };

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

const struct real_format motorola_single_format =
  {
    encode_ieee_single,
    decode_ieee_single,
    2,
    24,
    24,
    -125,
    128,
    31,
    31,
    32,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    true,
    "motorola_single"
  };

/*  SPU Single Precision (Extended-Range Mode) format is the same as IEEE
    single precision with the following differences:
      - Infinities are not supported.  Instead MAX_FLOAT or MIN_FLOAT
	are generated.
      - NaNs are not supported.
      - The range of non-zero numbers in binary is
	(001)[1.]000...000 to (255)[1.]111...111.
      - Denormals can be represented, but are treated as +0.0 when
	used as an operand and are never generated as a result.
      - -0.0 can be represented, but a zero result is always +0.0.
      - the only supported rounding mode is trunction (towards zero).  */
const struct real_format spu_single_format =
  {
    encode_ieee_single,
    decode_ieee_single,
    2,
    24,
    24,
    -125,
    129,
    31,
    31,
    0,
    true,
    false,
    false,
    false,
    true,
    true,
    false,
    false,
    "spu_single"
  };

/* 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;
  unsigned long sign = r->sign;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;

  image_hi = 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->cl)
    {
    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)
	    {
	      if (fmt->canonical_nan_lsbs_set)
		{
		  sig_hi = (1 << 19) - 1;
		  sig_lo = 0xffffffff;
		}
	      else
		{
		  sig_hi = 0;
		  sig_lo = 0;
		}
	    }
	  if (r->signalling == fmt->qnan_msb_set)
	    sig_hi &= ~(1 << 19);
	  else
	    sig_hi |= 1 << 19;
	  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 = REAL_EXP (r) + 1023 - 1;
      image_hi |= exp << 20;
      image_hi |= sig_hi;
      image_lo = sig_lo;
      break;

    default:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
	  r->sign = sign;
	  SET_REAL_EXP (r, -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->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, 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,
    53,
    53,
    -1021,
    1024,
    63,
    63,
    64,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_double"
  };

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

const struct real_format motorola_double_format =
  {
    encode_ieee_double,
    decode_ieee_double,
    2,
    53,
    53,
    -1021,
    1024,
    63,
    63,
    64,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    true,
    "motorola_double"
  };

/* 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->cl)
    {
    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 (r->canonical)
	    {
	      if (fmt->canonical_nan_lsbs_set)
		{
		  sig_hi = (1 << 30) - 1;
		  sig_lo = 0xffffffff;
		}
	    }
	  else 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 = REAL_EXP (r);

	/* 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;
	    gcc_assert (exp >= 0);
	  }
	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:
      gcc_unreachable ();
    }

  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);

  if (r->cl == rvc_inf)
    /* For infinity clear the explicit integer bit again, so that the
       format matches the canonical infinity generated by the FPU.  */
    intermed[1] = 0;

  /* 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->cl = 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.  */
	  SET_REAL_EXP (r, 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->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, 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,
    64,
    64,
    -16382,
    16384,
    95,
    95,
    0,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    true,
    "ieee_extended_motorola"
  };

const struct real_format ieee_extended_intel_96_format =
  {
    encode_ieee_extended_intel_96,
    decode_ieee_extended_intel_96,
    2,
    64,
    64,
    -16381,
    16384,
    79,
    79,
    65,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_extended_intel_96"
  };

const struct real_format ieee_extended_intel_128_format =
  {
    encode_ieee_extended_intel_128,
    decode_ieee_extended_intel_128,
    2,
    64,
    64,
    -16381,
    16384,
    79,
    79,
    65,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_extended_intel_128"
  };

/* 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,
    53,
    53,
    -16381,
    16384,
    79,
    79,
    33,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_extended_intel_96_round_53"
  };

/* 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
   +0.0 or -0.0 for Infinity and don't-care for NaN.  */

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;

  /* Renormalize R before doing any arithmetic on it.  */
  normr = *r;
  if (normr.cl == 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.cl == 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.cl != rvc_zero && u.cl != rvc_inf && u.cl != 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,
    53 + 53,
    53,
    -1021 + 53,
    1024,
    127,
    -1,
    0,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ibm_extended"
  };

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


/* 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;
  unsigned long sign = r->sign;
  bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
  REAL_VALUE_TYPE u;

  image3 = sign << 31;
  image2 = 0;
  image1 = 0;
  image0 = 0;

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

  switch (r->cl)
    {
    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)
	    {
	      if (fmt->canonical_nan_lsbs_set)
		{
		  image3 |= 0x7fff;
		  image2 = image1 = image0 = 0xffffffff;
		}
	    }
	  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;
	  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 = REAL_EXP (r) + 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:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
	  r->sign = sign;

	  SET_REAL_EXP (r, -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->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, 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,
    113,
    113,
    -16381,
    16384,
    127,
    127,
    128,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_quad"
  };

const struct real_format mips_quad_format =
  {
    encode_ieee_quad,
    decode_ieee_quad,
    2,
    113,
    113,
    -16381,
    16384,
    127,
    127,
    128,
    false,
    true,
    true,
    true,
    true,
    true,
    false,
    true,
    "mips_quad"
  };

/* 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->cl)
    {
    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 = REAL_EXP (r) + 128;

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

    default:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
      r->sign = (image >> 15) & 1;
      SET_REAL_EXP (r, 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->cl)
    {
    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 |= (REAL_EXP (r) + 128) << 7;
      break;

    default:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
      r->sign = (image0 >> 15) & 1;
      SET_REAL_EXP (r, 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->cl)
    {
    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 |= (REAL_EXP (r) + 1024) << 4;
      break;

    default:
      gcc_unreachable ();
    }

  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->cl = rvc_normal;
      r->sign = (image0 >> 15) & 1;
      SET_REAL_EXP (r, 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,
    24,
    24,
    -127,
    127,
    15,
    15,
    0,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    "vax_f"
  };

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

const struct real_format vax_g_format =
  {
    encode_vax_g,
    decode_vax_g,
    2,
    53,
    53,
    -1023,
    1023,
    15,
    15,
    0,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    false,
    "vax_g"
  };

/* Encode real R into a single precision DFP value in BUF.  */
static void
encode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
                       long *buf ATTRIBUTE_UNUSED,
		       const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
{
  encode_decimal32 (fmt, buf, r);
}

/* Decode a single precision DFP value in BUF into a real R.  */
static void
decode_decimal_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
		       REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
		       const long *buf ATTRIBUTE_UNUSED)
{
  decode_decimal32 (fmt, r, buf);
}

/* Encode real R into a double precision DFP value in BUF.  */
static void
encode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
		       long *buf ATTRIBUTE_UNUSED,
		       const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
{
  encode_decimal64 (fmt, buf, r);
}

/* Decode a double precision DFP value in BUF into a real R.  */
static void
decode_decimal_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
		       REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
		       const long *buf ATTRIBUTE_UNUSED)
{
  decode_decimal64 (fmt, r, buf);
}

/* Encode real R into a quad precision DFP value in BUF.  */
static void
encode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED,
		     long *buf ATTRIBUTE_UNUSED,
		     const REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED)
{
  encode_decimal128 (fmt, buf, r);
}

/* Decode a quad precision DFP value in BUF into a real R.  */
static void
decode_decimal_quad (const struct real_format *fmt ATTRIBUTE_UNUSED,
		     REAL_VALUE_TYPE *r ATTRIBUTE_UNUSED,
		     const long *buf ATTRIBUTE_UNUSED)
{
  decode_decimal128 (fmt, r, buf);
}

/* Single precision decimal floating point (IEEE 754). */
const struct real_format decimal_single_format =
  {
    encode_decimal_single,
    decode_decimal_single,
    10,
    7,
    7,
    -94,
    97,
    31,
    31,
    32,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "decimal_single"
  };

/* Double precision decimal floating point (IEEE 754). */
const struct real_format decimal_double_format =
  {
    encode_decimal_double,
    decode_decimal_double,
    10,
    16,
    16,
    -382,
    385,
    63,
    63,
    64,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "decimal_double"
  };

/* Quad precision decimal floating point (IEEE 754). */
const struct real_format decimal_quad_format =
  {
    encode_decimal_quad,
    decode_decimal_quad,
    10,
    34,
    34,
    -6142,
    6145,
    127,
    127,
    128,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "decimal_quad"
  };

/* Encode half-precision floats.  This routine is used both for the IEEE
   ARM alternative encodings.  */
static void
encode_ieee_half (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 << 15;
  sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;

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

    case rvc_inf:
      if (fmt->has_inf)
	image |= 31 << 10;
      else
	image |= 0x7fff;
      break;

    case rvc_nan:
      if (fmt->has_nans)
	{
	  if (r->canonical)
	    sig = (fmt->canonical_nan_lsbs_set ? (1 << 9) - 1 : 0);
	  if (r->signalling == fmt->qnan_msb_set)
	    sig &= ~(1 << 9);
	  else
	    sig |= 1 << 9;
	  if (sig == 0)
	    sig = 1 << 8;

	  image |= 31 << 10;
	  image |= sig;
	}
      else
	image |= 0x3ff;
      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 = REAL_EXP (r) + 15 - 1;
      image |= exp << 10;
      image |= sig;
      break;

    default:
      gcc_unreachable ();
    }

  buf[0] = image;
}

/* Decode half-precision floats.  This routine is used both for the IEEE
   ARM alternative encodings.  */
static void
decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		  const long *buf)
{
  unsigned long image = buf[0] & 0xffff;
  bool sign = (image >> 15) & 1;
  int exp = (image >> 10) & 0x1f;

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

  if (exp == 0)
    {
      if (image && fmt->has_denorm)
	{
	  r->cl = rvc_normal;
	  r->sign = sign;
	  SET_REAL_EXP (r, -14);
	  r->sig[SIGSZ-1] = image << 1;
	  normalize (r);
	}
      else if (fmt->has_signed_zero)
	r->sign = sign;
    }
  else if (exp == 31 && (fmt->has_nans || fmt->has_inf))
    {
      if (image)
	{
	  r->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, exp - 15 + 1);
      r->sig[SIGSZ-1] = image | SIG_MSB;
    }
}

/* Encode arm_bfloat types.  */
static void
encode_arm_bfloat_half (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 << 15;
  sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 8)) & 0x7f;

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

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

    case rvc_nan:
      if (fmt->has_nans)
	{
	  if (r->canonical)
	    sig = (fmt->canonical_nan_lsbs_set ? (1 << 6) - 1 : 0);
	  if (r->signalling == fmt->qnan_msb_set)
	    sig &= ~(1 << 6);
	  else
	    sig |= 1 << 6;
	  if (sig == 0)
	    sig = 1 << 5;

	  image |= 255 << 7;
	  image |= sig;
	}
      else
	image |= 0x7fff;
      break;

    case rvc_normal:
      if (denormal)
	exp = 0;
      else
      exp = REAL_EXP (r) + 127 - 1;
      image |= exp << 7;
      image |= sig;
      break;

    default:
      gcc_unreachable ();
    }

  buf[0] = image;
}

/* Decode arm_bfloat types.  */
static void
decode_arm_bfloat_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
		    const long *buf)
{
  unsigned long image = buf[0] & 0xffff;
  bool sign = (image >> 15) & 1;
  int exp = (image >> 7) & 0xff;

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

  if (exp == 0)
    {
      if (image && fmt->has_denorm)
	{
	  r->cl = rvc_normal;
	  r->sign = sign;
	  SET_REAL_EXP (r, -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->cl = 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->cl = rvc_inf;
	  r->sign = sign;
	}
    }
  else
    {
      r->cl = rvc_normal;
      r->sign = sign;
      SET_REAL_EXP (r, exp - 127 + 1);
      r->sig[SIGSZ-1] = image | SIG_MSB;
    }
}

/* Half-precision format, as specified in IEEE 754R.  */
const struct real_format ieee_half_format =
  {
    encode_ieee_half,
    decode_ieee_half,
    2,
    11,
    11,
    -13,
    16,
    15,
    15,
    16,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "ieee_half"
  };

/* ARM's alternative half-precision format, similar to IEEE but with
   no reserved exponent value for NaNs and infinities; rather, it just
   extends the range of exponents by one.  */
const struct real_format arm_half_format =
  {
    encode_ieee_half,
    decode_ieee_half,
    2,
    11,
    11,
    -13,
    17,
    15,
    15,
    0,
    false,
    true,
    false,
    false,
    true,
    true,
    false,
    false,
    "arm_half"
  };

/* ARM Bfloat half-precision format.  This format resembles a truncated
   (16-bit) version of the 32-bit IEEE 754 single-precision floating-point
   format.  */
const struct real_format arm_bfloat_half_format =
  {
    encode_arm_bfloat_half,
    decode_arm_bfloat_half,
    2,
    8,
    8,
    -125,
    128,
    15,
    15,
    0,
    false,
    true,
    true,
    true,
    true,
    true,
    true,
    false,
    "arm_bfloat_half"
  };


/* 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,
    SIGNIFICAND_BITS - 2,
    SIGNIFICAND_BITS - 2,
    -MAX_EXP,
    MAX_EXP,
    -1,
    -1,
    0,
    false,
    false,
    true,
    true,
    false,
    true,
    true,
    false,
    "real_internal"
  };

/* Calculate X raised to the integer exponent N in format FMT 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, format_helper fmt,
	   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 = HOST_WIDE_INT_1U << (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, fmt, &t);
  return inexact;
}

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

void
real_trunc (REAL_VALUE_TYPE *r, format_helper fmt,
	    const REAL_VALUE_TYPE *x)
{
  do_fix_trunc (r, x);
  if (fmt)
    real_convert (r, fmt, r);
}

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

void
real_floor (REAL_VALUE_TYPE *r, format_helper fmt,
	    const REAL_VALUE_TYPE *x)
{
  REAL_VALUE_TYPE t;

  do_fix_trunc (&t, x);
  if (! real_identical (&t, x) && x->sign)
    do_add (&t, &t, &dconstm1, 0);
  if (fmt)
    real_convert (r, fmt, &t);
  else
    *r = t;
}

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

void
real_ceil (REAL_VALUE_TYPE *r, format_helper fmt,
	   const REAL_VALUE_TYPE *x)
{
  REAL_VALUE_TYPE t;

  do_fix_trunc (&t, x);
  if (! real_identical (&t, x) && ! x->sign)
    do_add (&t, &t, &dconst1, 0);
  if (fmt)
    real_convert (r, fmt, &t);
  else
    *r = t;
}

/* Round X to the nearest integer, but round halfway cases away from
   zero.  */

void
real_round (REAL_VALUE_TYPE *r, format_helper fmt,
	    const REAL_VALUE_TYPE *x)
{
  do_add (r, x, &dconsthalf, x->sign);
  do_fix_trunc (r, r);
  if (fmt)
    real_convert (r, fmt, r);
}

/* Return true (including 0) if integer part of R is even, else return
   false.  The function is not valid for rvc_inf and rvc_nan classes.  */

static bool
is_even (REAL_VALUE_TYPE *r)
{
  gcc_assert (r->cl != rvc_inf);
  gcc_assert (r->cl != rvc_nan);

  if (r->cl == rvc_zero)
    return true;

  /* For (-1,1), number is even.  */
  if (REAL_EXP (r) <= 0)
    return true;

  /* Check lowest bit, if not set, return true.  */
  else if (REAL_EXP (r) <= SIGNIFICAND_BITS)
    {
      unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r);
      int w = n / HOST_BITS_PER_LONG;

      unsigned long num = ((unsigned long)1 << (n % HOST_BITS_PER_LONG));

      if ((r->sig[w] & num) == 0)
	return true;
    }
  else
    return true;

  return false;
}

/* Return true if R is halfway between two integers, else return
   false.  */

static bool
is_halfway_below (const REAL_VALUE_TYPE *r)
{
  if (r->cl != rvc_normal)
    return false;

  /* For numbers (-0.5,0) and (0,0.5).  */
  if (REAL_EXP (r) < 0)
    return false;

  else if (REAL_EXP (r) < SIGNIFICAND_BITS)
    {
      unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r) - 1;
      int w = n / HOST_BITS_PER_LONG;

      for (int i = 0; i < w; ++i)
	if (r->sig[i] != 0)
	  return false;

      unsigned long num = 1UL << (n % HOST_BITS_PER_LONG);

      if ((r->sig[w] & num) != 0 && (r->sig[w] & (num - 1)) == 0)
	return true;
    }
  return false;
}

/* Round X to nearest integer, rounding halfway cases towards even.  */

void
real_roundeven (REAL_VALUE_TYPE *r, format_helper fmt,
		const REAL_VALUE_TYPE *x)
{
  if (is_halfway_below (x))
    {
      /* Special case as -0.5 rounds to -0.0 and
	 similarly +0.5 rounds to +0.0.  */
      if (REAL_EXP (x) == 0)
	{
	  *r = *x;
	  clear_significand_below (r, SIGNIFICAND_BITS);
	}
      else
	{
	  do_add (r, x, &dconsthalf, x->sign);
	  if (!is_even (r))
	    do_add (r, r, &dconstm1, x->sign);
	}
      if (fmt)
	real_convert (r, fmt, r);
    }
  else
    real_round (r, fmt, x);
}

/* Set the sign of R to the sign of X.  */

void
real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x)
{
  r->sign = x->sign;
}

/* Check whether the real constant value given is an integer.
   Returns false for signaling NaN.  */

bool
real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)
{
  REAL_VALUE_TYPE cint;

  real_trunc (&cint, fmt, c);
  return real_identical (c, &cint);
}

/* Check whether C is an integer that fits in a HOST_WIDE_INT,
   storing it in *INT_OUT if so.  */

bool
real_isinteger (const REAL_VALUE_TYPE *c, HOST_WIDE_INT *int_out)
{
  REAL_VALUE_TYPE cint;

  HOST_WIDE_INT n = real_to_integer (c);
  real_from_integer (&cint, VOIDmode, n, SIGNED);
  if (real_identical (c, &cint))
    {
      *int_out = n;
      return true;
    }
  return false;
}

/* Calculate nextafter (X, Y) or nexttoward (X, Y).  Return true if
   underflow or overflow needs to be raised.  */

bool
real_nextafter (REAL_VALUE_TYPE *r, format_helper fmt,
		const REAL_VALUE_TYPE *x, const REAL_VALUE_TYPE *y)
{
  int cmp = do_compare (x, y, 2);
  /* If either operand is NaN, return qNaN.  */
  if (cmp == 2)
    {
      get_canonical_qnan (r, 0);
      return false;
    }
  /* If x == y, return y cast to target type.  */
  if (cmp == 0)
    {
      real_convert (r, fmt, y);
      return false;
    }

  if (x->cl == rvc_zero)
    {
      get_zero (r, y->sign);
      r->cl = rvc_normal;
      SET_REAL_EXP (r, fmt->emin - fmt->p + 1);
      r->sig[SIGSZ - 1] = SIG_MSB;
      return false;
    }

  int np2 = SIGNIFICAND_BITS - fmt->p;
  /* For denormals adjust np2 correspondingly.  */
  if (x->cl == rvc_normal && REAL_EXP (x) < fmt->emin)
    np2 += fmt->emin - REAL_EXP (x);

  REAL_VALUE_TYPE u;
  get_zero (r, x->sign);
  get_zero (&u, 0);
  set_significand_bit (&u, np2);
  r->cl = rvc_normal;
  SET_REAL_EXP (r, REAL_EXP (x));

  if (x->cl == rvc_inf)
    {
      bool borrow = sub_significands (r, r, &u, 0);
      gcc_assert (borrow);
      SET_REAL_EXP (r, fmt->emax);
    }
  else if (cmp == (x->sign ? 1 : -1))
    {
      if (add_significands (r, x, &u))
	{
	  /* Overflow.  Means the significand had been all ones, and
	     is now all zeros.  Need to increase the exponent, and
	     possibly re-normalize it.  */
	  SET_REAL_EXP (r, REAL_EXP (r) + 1);
	  if (REAL_EXP (r) > fmt->emax)
	    {
	      get_inf (r, x->sign);
	      return true;
	    }
	  r->sig[SIGSZ - 1] = SIG_MSB;
	}
    }
  else
    {
      if (REAL_EXP (x) > fmt->emin && x->sig[SIGSZ - 1] == SIG_MSB)
	{
	  int i;
	  for (i = SIGSZ - 2; i >= 0; i--)
	    if (x->sig[i])
	      break;
	  if (i < 0)
	    {
	      /* When mantissa is 1.0, we need to subtract only
		 half of u: nextafter (1.0, 0.0) is 1.0 - __DBL_EPSILON__ / 2
		 rather than 1.0 - __DBL_EPSILON__.  */
	      clear_significand_bit (&u, np2);
	      np2--;
	      set_significand_bit (&u, np2);
	    }
	}
      sub_significands (r, x, &u, 0);
    }

  /* Clear out trailing garbage.  */
  clear_significand_below (r, np2);
  normalize (r);
  if (REAL_EXP (r) <= fmt->emin - fmt->p)
    {
      get_zero (r, x->sign);
      return true;
    }
  return r->cl == rvc_zero || REAL_EXP (r) < fmt->emin;
}

/* Write into BUF the maximum representable finite floating-point
   number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
   float string.  LEN is the size of BUF, and the buffer must be large
   enough to contain the resulting string.  If NORM_MAX, instead write
   the maximum representable finite normalized floating-point number,
   defined to be such that all choices of digits for that exponent are
   representable in the format (this only makes a difference for IBM
   long double).  */

void
get_max_float (const struct real_format *fmt, char *buf, size_t len,
	       bool norm_max)
{
  int i, n;
  char *p;
  bool is_ibm_extended = fmt->pnan < fmt->p;

  strcpy (buf, "0x0.");
  n = fmt->p;
  for (i = 0, p = buf + 4; i + 3 < n; i += 4)
    *p++ = 'f';
  if (i < n)
    *p++ = "08ce"[n - i];
  sprintf (p, "p%d",
	   (is_ibm_extended && norm_max) ? fmt->emax - 1 : fmt->emax);
  if (is_ibm_extended && !norm_max)
    {
      /* This is an IBM extended double format made up of two IEEE
	 doubles.  The value of the long double is the sum of the
	 values of the two parts.  The most significant part is
	 required to be the value of the long double rounded to the
	 nearest double.  Rounding means we need a slightly smaller
	 value for LDBL_MAX.  */
      buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4];
    }

  gcc_assert (strlen (buf) < len);
}

/* True if all values of integral type can be represented
   by this floating-point type exactly.  */

bool format_helper::can_represent_integral_type_p (tree type) const
{
  gcc_assert (! decimal_p () && INTEGRAL_TYPE_P (type));

  /* INT?_MIN is power-of-two so it takes
     only one mantissa bit.  */
  bool signed_p = TYPE_SIGN (type) == SIGNED;
  return TYPE_PRECISION (type) - signed_p <= significand_size (*this);
}

/* True if mode M has a NaN representation and
   the treatment of NaN operands is important.  */

bool
HONOR_NANS (machine_mode m)
{
  return MODE_HAS_NANS (m) && !flag_finite_math_only;
}

bool
HONOR_NANS (const_tree t)
{
  return HONOR_NANS (element_mode (t));
}

bool
HONOR_NANS (const_rtx x)
{
  return HONOR_NANS (GET_MODE (x));
}

/* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs).  */

bool
HONOR_SNANS (machine_mode m)
{
  return flag_signaling_nans && HONOR_NANS (m);
}

bool
HONOR_SNANS (const_tree t)
{
  return HONOR_SNANS (element_mode (t));
}

bool
HONOR_SNANS (const_rtx x)
{
  return HONOR_SNANS (GET_MODE (x));
}

/* As for HONOR_NANS, but true if the mode can represent infinity and
   the treatment of infinite values is important.  */

bool
HONOR_INFINITIES (machine_mode m)
{
  return MODE_HAS_INFINITIES (m) && !flag_finite_math_only;
}

bool
HONOR_INFINITIES (const_tree t)
{
  return HONOR_INFINITIES (element_mode (t));
}

bool
HONOR_INFINITIES (const_rtx x)
{
  return HONOR_INFINITIES (GET_MODE (x));
}

/* Like HONOR_NANS, but true if the given mode distinguishes between
   positive and negative zero, and the sign of zero is important.  */

bool
HONOR_SIGNED_ZEROS (machine_mode m)
{
  return MODE_HAS_SIGNED_ZEROS (m) && flag_signed_zeros;
}

bool
HONOR_SIGNED_ZEROS (const_tree t)
{
  return HONOR_SIGNED_ZEROS (element_mode (t));
}

bool
HONOR_SIGNED_ZEROS (const_rtx x)
{
  return HONOR_SIGNED_ZEROS (GET_MODE (x));
}

/* Like HONOR_NANS, but true if given mode supports sign-dependent rounding,
   and the rounding mode is important.  */

bool
HONOR_SIGN_DEPENDENT_ROUNDING (machine_mode m)
{
  return MODE_HAS_SIGN_DEPENDENT_ROUNDING (m) && flag_rounding_math;
}

bool
HONOR_SIGN_DEPENDENT_ROUNDING (const_tree t)
{
  return HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (t));
}

bool
HONOR_SIGN_DEPENDENT_ROUNDING (const_rtx x)
{
  return HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (x));
}

/* Fills r with the largest value such that 1 + r*r won't overflow.
   This is used in both sin (atan (x)) and cos (atan(x)) optimizations. */

void
build_sinatan_real (REAL_VALUE_TYPE * r, tree type)
{
  REAL_VALUE_TYPE maxval;
  mpfr_t mpfr_const1, mpfr_c, mpfr_maxval;
  machine_mode mode = TYPE_MODE (type);
  const struct real_format * fmt = REAL_MODE_FORMAT (mode);

  real_maxval (&maxval, 0, mode);

  mpfr_inits (mpfr_const1, mpfr_c, mpfr_maxval, NULL);

  mpfr_from_real (mpfr_const1, &dconst1, MPFR_RNDN);
  mpfr_from_real (mpfr_maxval, &maxval,  MPFR_RNDN);

  mpfr_sub (mpfr_c, mpfr_maxval, mpfr_const1, MPFR_RNDN);
  mpfr_sqrt (mpfr_c, mpfr_c, MPFR_RNDZ);

  real_from_mpfr (r, mpfr_c, fmt, MPFR_RNDZ);
  
  mpfr_clears (mpfr_const1, mpfr_c, mpfr_maxval, NULL);
}
