/* Floating point routines for GDB, the GNU debugger.

   Copyright (C) 2017-2018 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbtypes.h"
#include "floatformat.h"
#include "target-float.h"


/* Target floating-point operations.

   We provide multiple implementations of those operations, which differ
   by the host-side intermediate format they perform computations in.

   Those multiple implementations all derive from the following abstract
   base class, which specifies the set of operations to be implemented.  */

class target_float_ops
{
public:
  virtual std::string to_string (const gdb_byte *addr, const struct type *type,
				 const char *format) const = 0;
  virtual bool from_string (gdb_byte *addr, const struct type *type,
			    const std::string &string) const = 0;

  virtual LONGEST to_longest (const gdb_byte *addr,
			      const struct type *type) const = 0;
  virtual void from_longest (gdb_byte *addr, const struct type *type,
			     LONGEST val) const = 0;
  virtual void from_ulongest (gdb_byte *addr, const struct type *type,
			      ULONGEST val) const = 0;
  virtual double to_host_double (const gdb_byte *addr,
				 const struct type *type) const = 0;
  virtual void from_host_double (gdb_byte *addr, const struct type *type,
				 double val) const = 0;
  virtual void convert (const gdb_byte *from, const struct type *from_type,
			gdb_byte *to, const struct type *to_type) const = 0;

  virtual void binop (enum exp_opcode opcode,
		      const gdb_byte *x, const struct type *type_x,
		      const gdb_byte *y, const struct type *type_y,
		      gdb_byte *res, const struct type *type_res) const = 0;
  virtual int compare (const gdb_byte *x, const struct type *type_x,
		       const gdb_byte *y, const struct type *type_y) const = 0;
};


/* Helper routines operating on binary floating-point data.  */

#include <cmath>
#include <limits>

/* Different kinds of floatformat numbers recognized by
   floatformat_classify.  To avoid portability issues, we use local
   values instead of the C99 macros (FP_NAN et cetera).  */
enum float_kind {
  float_nan,
  float_infinite,
  float_zero,
  float_normal,
  float_subnormal
};

/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
   going to bother with trying to muck around with whether it is defined in
   a system header, what we do if not, etc.  */
#define FLOATFORMAT_CHAR_BIT 8

/* The number of bytes that the largest floating-point type that we
   can convert to doublest will need.  */
#define FLOATFORMAT_LARGEST_BYTES 16

/* Return the floatformat's total size in host bytes.  */
static size_t
floatformat_totalsize_bytes (const struct floatformat *fmt)
{
  return ((fmt->totalsize + FLOATFORMAT_CHAR_BIT - 1)
	  / FLOATFORMAT_CHAR_BIT);
}

/* Return the precision of the floating point format FMT.  */
static int
floatformat_precision (const struct floatformat *fmt)
{
  /* Assume the precision of and IBM long double is twice the precision
     of the underlying double.  This matches what GCC does.  */
  if (fmt->split_half)
    return 2 * floatformat_precision (fmt->split_half);

  /* Otherwise, the precision is the size of mantissa in bits,
     including the implicit bit if present.  */
  int prec = fmt->man_len;
  if (fmt->intbit == floatformat_intbit_no)
    prec++;

  return prec;
}

/* Normalize the byte order of FROM into TO.  If no normalization is
   needed then FMT->byteorder is returned and TO is not changed;
   otherwise the format of the normalized form in TO is returned.  */
static enum floatformat_byteorders
floatformat_normalize_byteorder (const struct floatformat *fmt,
				 const void *from, void *to)
{
  const unsigned char *swapin;
  unsigned char *swapout;
  int words;

  if (fmt->byteorder == floatformat_little
      || fmt->byteorder == floatformat_big)
    return fmt->byteorder;

  words = fmt->totalsize / FLOATFORMAT_CHAR_BIT;
  words >>= 2;

  swapout = (unsigned char *)to;
  swapin = (const unsigned char *)from;

  if (fmt->byteorder == floatformat_vax)
    {
      while (words-- > 0)
	{
	  *swapout++ = swapin[1];
	  *swapout++ = swapin[0];
	  *swapout++ = swapin[3];
	  *swapout++ = swapin[2];
	  swapin += 4;
	}
      /* This may look weird, since VAX is little-endian, but it is
	 easier to translate to big-endian than to little-endian.  */
      return floatformat_big;
    }
  else
    {
      gdb_assert (fmt->byteorder == floatformat_littlebyte_bigword);

      while (words-- > 0)
	{
	  *swapout++ = swapin[3];
	  *swapout++ = swapin[2];
	  *swapout++ = swapin[1];
	  *swapout++ = swapin[0];
	  swapin += 4;
	}
      return floatformat_big;
    }
}

/* Extract a field which starts at START and is LEN bytes long.  DATA and
   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
static unsigned long
get_field (const bfd_byte *data, enum floatformat_byteorders order,
	   unsigned int total_len, unsigned int start, unsigned int len)
{
  unsigned long result;
  unsigned int cur_byte;
  int cur_bitshift;

  /* Caller must byte-swap words before calling this routine.  */
  gdb_assert (order == floatformat_little || order == floatformat_big);

  /* Start at the least significant part of the field.  */
  if (order == floatformat_little)
    {
      /* We start counting from the other end (i.e, from the high bytes
	 rather than the low bytes).  As such, we need to be concerned
	 with what happens if bit 0 doesn't start on a byte boundary.
	 I.e, we need to properly handle the case where total_len is
	 not evenly divisible by 8.  So we compute ``excess'' which
	 represents the number of bits from the end of our starting
	 byte needed to get to bit 0.  */
      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);

      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
                     - FLOATFORMAT_CHAR_BIT;
    }
  else
    {
      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
      cur_bitshift =
	((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
    }
  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
    result = *(data + cur_byte) >> (-cur_bitshift);
  else
    result = 0;
  cur_bitshift += FLOATFORMAT_CHAR_BIT;
  if (order == floatformat_little)
    ++cur_byte;
  else
    --cur_byte;

  /* Move towards the most significant part of the field.  */
  while (cur_bitshift < len)
    {
      result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
      cur_bitshift += FLOATFORMAT_CHAR_BIT;
      switch (order)
	{
	case floatformat_little:
	  ++cur_byte;
	  break;
	case floatformat_big:
	  --cur_byte;
	  break;
	}
    }
  if (len < sizeof(result) * FLOATFORMAT_CHAR_BIT)
    /* Mask out bits which are not part of the field.  */
    result &= ((1UL << len) - 1);
  return result;
}

/* Set a field which starts at START and is LEN bytes long.  DATA and
   TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER.  */
static void
put_field (unsigned char *data, enum floatformat_byteorders order,
	   unsigned int total_len, unsigned int start, unsigned int len,
	   unsigned long stuff_to_put)
{
  unsigned int cur_byte;
  int cur_bitshift;

  /* Caller must byte-swap words before calling this routine.  */
  gdb_assert (order == floatformat_little || order == floatformat_big);

  /* Start at the least significant part of the field.  */
  if (order == floatformat_little)
    {
      int excess = FLOATFORMAT_CHAR_BIT - (total_len % FLOATFORMAT_CHAR_BIT);

      cur_byte = (total_len / FLOATFORMAT_CHAR_BIT)
                 - ((start + len + excess) / FLOATFORMAT_CHAR_BIT);
      cur_bitshift = ((start + len + excess) % FLOATFORMAT_CHAR_BIT)
                     - FLOATFORMAT_CHAR_BIT;
    }
  else
    {
      cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
      cur_bitshift =
	((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
    }
  if (cur_bitshift > -FLOATFORMAT_CHAR_BIT)
    {
      *(data + cur_byte) &=
	~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1)
	  << (-cur_bitshift));
      *(data + cur_byte) |=
	(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
    }
  cur_bitshift += FLOATFORMAT_CHAR_BIT;
  if (order == floatformat_little)
    ++cur_byte;
  else
    --cur_byte;

  /* Move towards the most significant part of the field.  */
  while (cur_bitshift < len)
    {
      if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
	{
	  /* This is the last byte.  */
	  *(data + cur_byte) &=
	    ~((1 << (len - cur_bitshift)) - 1);
	  *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
	}
      else
	*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
			      & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
      cur_bitshift += FLOATFORMAT_CHAR_BIT;
      if (order == floatformat_little)
	++cur_byte;
      else
	--cur_byte;
    }
}

/* Check if VAL (which is assumed to be a floating point number whose
   format is described by FMT) is negative.  */
static int
floatformat_is_negative (const struct floatformat *fmt,
			 const bfd_byte *uval)
{
  enum floatformat_byteorders order;
  unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];

  gdb_assert (fmt != NULL);
  gdb_assert (fmt->totalsize
	      <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);

  /* An IBM long double (a two element array of double) always takes the
     sign of the first double.  */
  if (fmt->split_half)
    fmt = fmt->split_half;

  order = floatformat_normalize_byteorder (fmt, uval, newfrom);

  if (order != fmt->byteorder)
    uval = newfrom;

  return get_field (uval, order, fmt->totalsize, fmt->sign_start, 1);
}

/* Check if VAL is "not a number" (NaN) for FMT.  */
static enum float_kind
floatformat_classify (const struct floatformat *fmt,
		      const bfd_byte *uval)
{
  long exponent;
  unsigned long mant;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  enum floatformat_byteorders order;
  unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
  int mant_zero;

  gdb_assert (fmt != NULL);
  gdb_assert (fmt->totalsize
	      <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);

  /* An IBM long double (a two element array of double) can be classified
     by looking at the first double.  inf and nan are specified as
     ignoring the second double.  zero and subnormal will always have
     the second double 0.0 if the long double is correctly rounded.  */
  if (fmt->split_half)
    fmt = fmt->split_half;

  order = floatformat_normalize_byteorder (fmt, uval, newfrom);

  if (order != fmt->byteorder)
    uval = newfrom;

  exponent = get_field (uval, order, fmt->totalsize, fmt->exp_start,
			fmt->exp_len);

  mant_bits_left = fmt->man_len;
  mant_off = fmt->man_start;

  mant_zero = 1;
  while (mant_bits_left > 0)
    {
      mant_bits = std::min (mant_bits_left, 32);

      mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits);

      /* If there is an explicit integer bit, mask it off.  */
      if (mant_off == fmt->man_start
	  && fmt->intbit == floatformat_intbit_yes)
	mant &= ~(1 << (mant_bits - 1));

      if (mant)
	{
	  mant_zero = 0;
	  break;
	}

      mant_off += mant_bits;
      mant_bits_left -= mant_bits;
    }

  /* If exp_nan is not set, assume that inf, NaN, and subnormals are not
     supported.  */
  if (! fmt->exp_nan)
    {
      if (mant_zero)
	return float_zero;
      else
	return float_normal;
    }

  if (exponent == 0)
    {
      if (mant_zero)
	return float_zero;
      else
	return float_subnormal;
    }

  if (exponent == fmt->exp_nan)
    {
      if (mant_zero)
	return float_infinite;
      else
	return float_nan;
    }

  return float_normal;
}

/* Convert the mantissa of VAL (which is assumed to be a floating
   point number whose format is described by FMT) into a hexadecimal
   and store it in a static string.  Return a pointer to that string.  */
static const char *
floatformat_mantissa (const struct floatformat *fmt,
		      const bfd_byte *val)
{
  unsigned char *uval = (unsigned char *) val;
  unsigned long mant;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  static char res[50];
  char buf[9];
  int len;
  enum floatformat_byteorders order;
  unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];

  gdb_assert (fmt != NULL);
  gdb_assert (fmt->totalsize
	      <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);

  /* For IBM long double (a two element array of double), return the
     mantissa of the first double.  The problem with returning the
     actual mantissa from both doubles is that there can be an
     arbitrary number of implied 0's or 1's between the mantissas
     of the first and second double.  In any case, this function
     is only used for dumping out nans, and a nan is specified to
     ignore the value in the second double.  */
  if (fmt->split_half)
    fmt = fmt->split_half;

  order = floatformat_normalize_byteorder (fmt, uval, newfrom);

  if (order != fmt->byteorder)
    uval = newfrom;

  if (! fmt->exp_nan)
    return 0;

  /* Make sure we have enough room to store the mantissa.  */
  gdb_assert (sizeof res > ((fmt->man_len + 7) / 8) * 2);

  mant_off = fmt->man_start;
  mant_bits_left = fmt->man_len;
  mant_bits = (mant_bits_left % 32) > 0 ? mant_bits_left % 32 : 32;

  mant = get_field (uval, order, fmt->totalsize, mant_off, mant_bits);

  len = xsnprintf (res, sizeof res, "%lx", mant);

  mant_off += mant_bits;
  mant_bits_left -= mant_bits;

  while (mant_bits_left > 0)
    {
      mant = get_field (uval, order, fmt->totalsize, mant_off, 32);

      xsnprintf (buf, sizeof buf, "%08lx", mant);
      gdb_assert (len + strlen (buf) <= sizeof res);
      strcat (res, buf);

      mant_off += 32;
      mant_bits_left -= 32;
    }

  return res;
}

/* Convert printf format string FORMAT to the otherwise equivalent string
   which may be used to print a host floating-point number using the length
   modifier LENGTH (which may be 0 if none is needed).  If FORMAT is null,
   return a format appropriate to print the full precision of a target
   floating-point number of format FMT.  */
static std::string
floatformat_printf_format (const struct floatformat *fmt,
                           const char *format, char length)
{
  std::string host_format;
  char conversion;

  if (format == nullptr)
    {
      /* If no format was specified, print the number using a format string
	 where the precision is set to the DECIMAL_DIG value for the given
	 floating-point format.  This value is computed as

		ceil(1 + p * log10(b)),

	 where p is the precision of the floating-point format in bits, and
	 b is the base (which is always 2 for the formats we support).  */
      const double log10_2 = .30102999566398119521;
      double d_decimal_dig = 1 + floatformat_precision (fmt) * log10_2;
      int decimal_dig = d_decimal_dig;
      if (decimal_dig < d_decimal_dig)
	decimal_dig++;

      host_format = string_printf ("%%.%d", decimal_dig);
      conversion = 'g';
    }
  else
    {
      /* Use the specified format, stripping out the conversion character
         and length modifier, if present.  */
      size_t len = strlen (format);
      gdb_assert (len > 1);
      conversion = format[--len];
      gdb_assert (conversion == 'e' || conversion == 'f' || conversion == 'g'
		  || conversion == 'E' || conversion == 'G');
      if (format[len - 1] == 'L')
	len--;

      host_format = std::string (format, len);
    }

  /* Add the length modifier and conversion character appropriate for
     handling the appropriate host floating-point type.  */
  if (length)
    host_format += length;
  host_format += conversion;

  return host_format;
}

/* Implementation of target_float_ops using the host floating-point type T
   as intermediate type.  */

template<typename T> class host_float_ops : public target_float_ops
{
public:
  std::string to_string (const gdb_byte *addr, const struct type *type,
			 const char *format) const override;
  bool from_string (gdb_byte *addr, const struct type *type,
		    const std::string &string) const override;

  LONGEST to_longest (const gdb_byte *addr,
		      const struct type *type) const override;
  void from_longest (gdb_byte *addr, const struct type *type,
		     LONGEST val) const override;
  void from_ulongest (gdb_byte *addr, const struct type *type,
		      ULONGEST val) const override;
  double to_host_double (const gdb_byte *addr,
			 const struct type *type) const override;
  void from_host_double (gdb_byte *addr, const struct type *type,
			 double val) const override;
  void convert (const gdb_byte *from, const struct type *from_type,
		gdb_byte *to, const struct type *to_type) const override;

  void binop (enum exp_opcode opcode,
	      const gdb_byte *x, const struct type *type_x,
	      const gdb_byte *y, const struct type *type_y,
	      gdb_byte *res, const struct type *type_res) const override;
  int compare (const gdb_byte *x, const struct type *type_x,
	       const gdb_byte *y, const struct type *type_y) const override;

private:
  void from_target (const struct floatformat *fmt,
		    const gdb_byte *from, T *to) const;
  void from_target (const struct type *type,
		    const gdb_byte *from, T *to) const;

  void to_target (const struct type *type,
		  const T *from, gdb_byte *to) const;
  void to_target (const struct floatformat *fmt,
		  const T *from, gdb_byte *to) const;
};


/* Convert TO/FROM target to the host floating-point format T.

   If the host and target formats agree, we just copy the raw data
   into the appropriate type of variable and return, letting the host
   increase precision as necessary.  Otherwise, we call the conversion
   routine and let it do the dirty work.  Note that even if the target
   and host floating-point formats match, the length of the types
   might still be different, so the conversion routines must make sure
   to not overrun any buffers.  For example, on x86, long double is
   the 80-bit extended precision type on both 32-bit and 64-bit ABIs,
   but by default it is stored as 12 bytes on 32-bit, and 16 bytes on
   64-bit, for alignment reasons.  See comment in store_typed_floating
   for a discussion about zeroing out remaining bytes in the target
   buffer.  */

static const struct floatformat *host_float_format = GDB_HOST_FLOAT_FORMAT;
static const struct floatformat *host_double_format = GDB_HOST_DOUBLE_FORMAT;
static const struct floatformat *host_long_double_format
  = GDB_HOST_LONG_DOUBLE_FORMAT;

/* Convert target floating-point value at FROM in format FMT to host
   floating-point format of type T.  */
template<typename T> void
host_float_ops<T>::from_target (const struct floatformat *fmt,
				const gdb_byte *from, T *to) const
{
  gdb_assert (fmt != NULL);

  if (fmt == host_float_format)
    {
      float val = 0;

      memcpy (&val, from, floatformat_totalsize_bytes (fmt));
      *to = val;
      return;
    }
  else if (fmt == host_double_format)
    {
      double val = 0;

      memcpy (&val, from, floatformat_totalsize_bytes (fmt));
      *to = val;
      return;
    }
  else if (fmt == host_long_double_format)
    {
      long double val = 0;

      memcpy (&val, from, floatformat_totalsize_bytes (fmt));
      *to = val;
      return;
    }

  unsigned char *ufrom = (unsigned char *) from;
  T dto;
  long exponent;
  unsigned long mant;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  int special_exponent;		/* It's a NaN, denorm or zero.  */
  enum floatformat_byteorders order;
  unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
  enum float_kind kind;

  gdb_assert (fmt->totalsize
	      <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);

  /* For non-numbers, reuse libiberty's logic to find the correct
     format.  We do not lose any precision in this case by passing
     through a double.  */
  kind = floatformat_classify (fmt, (const bfd_byte *) from);
  if (kind == float_infinite || kind == float_nan)
    {
      double dto;

      floatformat_to_double (fmt->split_half ? fmt->split_half : fmt,
			     from, &dto);
      *to = (T) dto;
      return;
    }

  order = floatformat_normalize_byteorder (fmt, ufrom, newfrom);

  if (order != fmt->byteorder)
    ufrom = newfrom;

  if (fmt->split_half)
    {
      T dtop, dbot;

      from_target (fmt->split_half, ufrom, &dtop);
      /* Preserve the sign of 0, which is the sign of the top
	 half.  */
      if (dtop == 0.0)
	{
	  *to = dtop;
	  return;
	}
      from_target (fmt->split_half,
		   ufrom + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2, &dbot);
      *to = dtop + dbot;
      return;
    }

  exponent = get_field (ufrom, order, fmt->totalsize, fmt->exp_start,
			fmt->exp_len);
  /* Note that if exponent indicates a NaN, we can't really do anything useful
     (not knowing if the host has NaN's, or how to build one).  So it will
     end up as an infinity or something close; that is OK.  */

  mant_bits_left = fmt->man_len;
  mant_off = fmt->man_start;
  dto = 0.0;

  special_exponent = exponent == 0 || exponent == fmt->exp_nan;

  /* Don't bias NaNs.  Use minimum exponent for denorms.  For
     simplicity, we don't check for zero as the exponent doesn't matter.
     Note the cast to int; exp_bias is unsigned, so it's important to
     make sure the operation is done in signed arithmetic.  */
  if (!special_exponent)
    exponent -= fmt->exp_bias;
  else if (exponent == 0)
    exponent = 1 - fmt->exp_bias;

  /* Build the result algebraically.  Might go infinite, underflow, etc;
     who cares.  */

  /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
     increment the exponent by one to account for the integer bit.  */

  if (!special_exponent)
    {
      if (fmt->intbit == floatformat_intbit_no)
	dto = ldexp (1.0, exponent);
      else
	exponent++;
    }

  while (mant_bits_left > 0)
    {
      mant_bits = std::min (mant_bits_left, 32);

      mant = get_field (ufrom, order, fmt->totalsize, mant_off, mant_bits);

      dto += ldexp ((T) mant, exponent - mant_bits);
      exponent -= mant_bits;
      mant_off += mant_bits;
      mant_bits_left -= mant_bits;
    }

  /* Negate it if negative.  */
  if (get_field (ufrom, order, fmt->totalsize, fmt->sign_start, 1))
    dto = -dto;
  *to = dto;
}

template<typename T> void
host_float_ops<T>::from_target (const struct type *type,
				const gdb_byte *from, T *to) const
{
  from_target (floatformat_from_type (type), from, to);
}

/* Convert host floating-point value of type T to target floating-point
   value in format FMT and store at TO.  */
template<typename T> void
host_float_ops<T>::to_target (const struct floatformat *fmt,
			      const T *from, gdb_byte *to) const
{
  gdb_assert (fmt != NULL);

  if (fmt == host_float_format)
    {
      float val = *from;

      memcpy (to, &val, floatformat_totalsize_bytes (fmt));
      return;
    }
  else if (fmt == host_double_format)
    {
      double val = *from;

      memcpy (to, &val, floatformat_totalsize_bytes (fmt));
      return;
    }
  else if (fmt == host_long_double_format)
    {
      long double val = *from;

      memcpy (to, &val, floatformat_totalsize_bytes (fmt));
      return;
    }

  T dfrom;
  int exponent;
  T mant;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  unsigned char *uto = (unsigned char *) to;
  enum floatformat_byteorders order = fmt->byteorder;
  unsigned char newto[FLOATFORMAT_LARGEST_BYTES];

  if (order != floatformat_little)
    order = floatformat_big;

  if (order != fmt->byteorder)
    uto = newto;

  memcpy (&dfrom, from, sizeof (dfrom));
  memset (uto, 0, floatformat_totalsize_bytes (fmt));

  if (fmt->split_half)
    {
      /* Use static volatile to ensure that any excess precision is
	 removed via storing in memory, and so the top half really is
	 the result of converting to double.  */
      static volatile double dtop, dbot;
      T dtopnv, dbotnv;

      dtop = (double) dfrom;
      /* If the rounded top half is Inf, the bottom must be 0 not NaN
	 or Inf.  */
      if (dtop + dtop == dtop && dtop != 0.0)
	dbot = 0.0;
      else
	dbot = (double) (dfrom - (T) dtop);
      dtopnv = dtop;
      dbotnv = dbot;
      to_target (fmt->split_half, &dtopnv, uto);
      to_target (fmt->split_half, &dbotnv,
		 uto + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2);
      return;
    }

  if (dfrom == 0)
    goto finalize_byteorder;	/* Result is zero */
  if (dfrom != dfrom)		/* Result is NaN */
    {
      /* From is NaN */
      put_field (uto, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      /* Be sure it's not infinity, but NaN value is irrel.  */
      put_field (uto, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 1);
      goto finalize_byteorder;
    }

  /* If negative, set the sign bit.  */
  if (dfrom < 0)
    {
      put_field (uto, order, fmt->totalsize, fmt->sign_start, 1, 1);
      dfrom = -dfrom;
    }

  if (dfrom + dfrom == dfrom && dfrom != 0.0)	/* Result is Infinity.  */
    {
      /* Infinity exponent is same as NaN's.  */
      put_field (uto, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      /* Infinity mantissa is all zeroes.  */
      put_field (uto, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  mant = frexp (dfrom, &exponent);

  if (exponent + fmt->exp_bias <= 0)
    {
      /* The value is too small to be expressed in the destination
	 type (not enough bits in the exponent.  Treat as 0.  */
      put_field (uto, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, 0);
      put_field (uto, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  if (exponent + fmt->exp_bias >= (1 << fmt->exp_len))
    {
      /* The value is too large to fit into the destination.
	 Treat as infinity.  */
      put_field (uto, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      put_field (uto, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
	     exponent + fmt->exp_bias - 1);

  mant_bits_left = fmt->man_len;
  mant_off = fmt->man_start;
  while (mant_bits_left > 0)
    {
      unsigned long mant_long;

      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;

      mant *= 4294967296.0;
      mant_long = ((unsigned long) mant) & 0xffffffffL;
      mant -= mant_long;

      /* If the integer bit is implicit, then we need to discard it.
         If we are discarding a zero, we should be (but are not) creating
         a denormalized number which means adjusting the exponent
         (I think).  */
      if (mant_bits_left == fmt->man_len
	  && fmt->intbit == floatformat_intbit_no)
	{
	  mant_long <<= 1;
	  mant_long &= 0xffffffffL;
          /* If we are processing the top 32 mantissa bits of a doublest
             so as to convert to a float value with implied integer bit,
             we will only be putting 31 of those 32 bits into the
             final value due to the discarding of the top bit.  In the
             case of a small float value where the number of mantissa
             bits is less than 32, discarding the top bit does not alter
             the number of bits we will be adding to the result.  */
          if (mant_bits == 32)
            mant_bits -= 1;
	}

      if (mant_bits < 32)
	{
	  /* The bits we want are in the most significant MANT_BITS bits of
	     mant_long.  Move them to the least significant.  */
	  mant_long >>= 32 - mant_bits;
	}

      put_field (uto, order, fmt->totalsize,
		 mant_off, mant_bits, mant_long);
      mant_off += mant_bits;
      mant_bits_left -= mant_bits;
    }

 finalize_byteorder:
  /* Do we need to byte-swap the words in the result?  */
  if (order != fmt->byteorder)
    floatformat_normalize_byteorder (fmt, newto, to);
}

template<typename T> void
host_float_ops<T>::to_target (const struct type *type,
			      const T *from, gdb_byte *to) const
{
  /* Ensure possible padding bytes in the target buffer are zeroed out.  */
  memset (to, 0, TYPE_LENGTH (type));

  to_target (floatformat_from_type (type), from, to);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a string, optionally using the print format FORMAT.  */
template<typename T> struct printf_length_modifier
{
  static constexpr char value = 0;
};
template<> struct printf_length_modifier<long double>
{
  static constexpr char value = 'L';
};
template<typename T> std::string
host_float_ops<T>::to_string (const gdb_byte *addr, const struct type *type,
			      const char *format) const
{
  /* Determine the format string to use on the host side.  */
  constexpr char length = printf_length_modifier<T>::value;
  const struct floatformat *fmt = floatformat_from_type (type);
  std::string host_format = floatformat_printf_format (fmt, format, length);

  T host_float;
  from_target (type, addr, &host_float);
  return string_printf (host_format.c_str (), host_float);
}

/* Parse string IN into a target floating-number of type TYPE and
   store it as byte-stream ADDR.  Return whether parsing succeeded.  */
template<typename T> struct scanf_length_modifier
{
  static constexpr char value = 0;
};
template<> struct scanf_length_modifier<double>
{
  static constexpr char value = 'l';
};
template<> struct scanf_length_modifier<long double>
{
  static constexpr char value = 'L';
};
template<typename T> bool
host_float_ops<T>::from_string (gdb_byte *addr, const struct type *type,
				const std::string &in) const
{
  T host_float;
  int n, num;

  std::string scan_format = "%";
  if (scanf_length_modifier<T>::value)
    scan_format += scanf_length_modifier<T>::value;
  scan_format += "g%n";

  num = sscanf (in.c_str (), scan_format.c_str(), &host_float, &n);

  /* The sscanf man page suggests not making any assumptions on the effect
     of %n on the result, so we don't.
     That is why we simply test num == 0.  */
  if (num == 0)
    return false;

  /* We only accept the whole string.  */
  if (in[n])
    return false;

  to_target (type, &host_float, addr);
  return true;
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to an integer value (rounding towards zero).  */
template<typename T> LONGEST
host_float_ops<T>::to_longest (const gdb_byte *addr,
			       const struct type *type) const
{
  T host_float;
  from_target (type, addr, &host_float);
  /* Converting an out-of-range value is undefined behavior in C, but we
     prefer to return a defined value here.  */
  if (host_float > std::numeric_limits<LONGEST>::max())
    return std::numeric_limits<LONGEST>::max();
  if (host_float < std::numeric_limits<LONGEST>::min())
    return std::numeric_limits<LONGEST>::min();
  return (LONGEST) host_float;
}

/* Convert signed integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
template<typename T> void
host_float_ops<T>::from_longest (gdb_byte *addr, const struct type *type,
				 LONGEST val) const
{
  T host_float = (T) val;
  to_target (type, &host_float, addr);
}

/* Convert unsigned integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
template<typename T> void
host_float_ops<T>::from_ulongest (gdb_byte *addr, const struct type *type,
				  ULONGEST val) const
{
  T host_float = (T) val;
  to_target (type, &host_float, addr);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a floating-point value in the host "double" format.  */
template<typename T> double
host_float_ops<T>::to_host_double (const gdb_byte *addr,
				   const struct type *type) const
{
  T host_float;
  from_target (type, addr, &host_float);
  return (double) host_float;
}

/* Convert floating-point value VAL in the host "double" format to a target
   floating-number of type TYPE and store it as byte-stream ADDR.  */
template<typename T> void
host_float_ops<T>::from_host_double (gdb_byte *addr, const struct type *type,
				     double val) const
{
  T host_float = (T) val;
  to_target (type, &host_float, addr);
}

/* Convert a floating-point number of type FROM_TYPE from the target
   byte-stream FROM to a floating-point number of type TO_TYPE, and
   store it to the target byte-stream TO.  */
template<typename T> void
host_float_ops<T>::convert (const gdb_byte *from,
			    const struct type *from_type,
			    gdb_byte *to,
			    const struct type *to_type) const
{
  T host_float;
  from_target (from_type, from, &host_float);
  to_target (to_type, &host_float, to);
}

/* Perform the binary operation indicated by OPCODE, using as operands the
   target byte streams X and Y, interpreted as floating-point numbers of
   types TYPE_X and TYPE_Y, respectively.  Convert the result to format
   TYPE_RES and store it into the byte-stream RES.  */
template<typename T> void
host_float_ops<T>::binop (enum exp_opcode op,
			  const gdb_byte *x, const struct type *type_x,
			  const gdb_byte *y, const struct type *type_y,
			  gdb_byte *res, const struct type *type_res) const
{
  T v1, v2, v = 0;

  from_target (type_x, x, &v1);
  from_target (type_y, y, &v2);

  switch (op)
    {
      case BINOP_ADD:
	v = v1 + v2;
	break;

      case BINOP_SUB:
	v = v1 - v2;
	break;

      case BINOP_MUL:
	v = v1 * v2;
	break;

      case BINOP_DIV:
	v = v1 / v2;
	break;

      case BINOP_EXP:
	errno = 0;
	v = pow (v1, v2);
	if (errno)
	  error (_("Cannot perform exponentiation: %s"),
		 safe_strerror (errno));
	break;

      case BINOP_MIN:
	v = v1 < v2 ? v1 : v2;
	break;

      case BINOP_MAX:
	v = v1 > v2 ? v1 : v2;
	break;

      default:
	error (_("Integer-only operation on floating point number."));
	break;
    }

  to_target (type_res, &v, res);
}

/* Compare the two target byte streams X and Y, interpreted as floating-point
   numbers of types TYPE_X and TYPE_Y, respectively.  Return zero if X and Y
   are equal, -1 if X is less than Y, and 1 otherwise.  */
template<typename T> int
host_float_ops<T>::compare (const gdb_byte *x, const struct type *type_x,
			    const gdb_byte *y, const struct type *type_y) const
{
  T v1, v2;

  from_target (type_x, x, &v1);
  from_target (type_y, y, &v2);

  if (v1 == v2)
    return 0;
  if (v1 < v2)
    return -1;
  return 1;
}


/* Implementation of target_float_ops using the MPFR library
   mpfr_t as intermediate type.  */

#ifdef HAVE_LIBMPFR

#define MPFR_USE_INTMAX_T

#include <mpfr.h>

class mpfr_float_ops : public target_float_ops
{
public:
  std::string to_string (const gdb_byte *addr, const struct type *type,
			 const char *format) const override;
  bool from_string (gdb_byte *addr, const struct type *type,
		    const std::string &string) const override;

  LONGEST to_longest (const gdb_byte *addr,
		      const struct type *type) const override;
  void from_longest (gdb_byte *addr, const struct type *type,
		     LONGEST val) const override;
  void from_ulongest (gdb_byte *addr, const struct type *type,
		      ULONGEST val) const override;
  double to_host_double (const gdb_byte *addr,
			 const struct type *type) const override;
  void from_host_double (gdb_byte *addr, const struct type *type,
			 double val) const override;
  void convert (const gdb_byte *from, const struct type *from_type,
		gdb_byte *to, const struct type *to_type) const override;

  void binop (enum exp_opcode opcode,
	      const gdb_byte *x, const struct type *type_x,
	      const gdb_byte *y, const struct type *type_y,
	      gdb_byte *res, const struct type *type_res) const override;
  int compare (const gdb_byte *x, const struct type *type_x,
	       const gdb_byte *y, const struct type *type_y) const override;

private:
  /* Local wrapper class to handle mpfr_t initalization and cleanup.  */
  class gdb_mpfr
  {
  public:
    mpfr_t val;

    gdb_mpfr (const struct type *type)
    {
      const struct floatformat *fmt = floatformat_from_type (type);
      mpfr_init2 (val, floatformat_precision (fmt));
    }

    gdb_mpfr (const gdb_mpfr &source)
    {
      mpfr_init2 (val, mpfr_get_prec (source.val));
    }

    ~gdb_mpfr ()
    {
      mpfr_clear (val);
    }
  };

  void from_target (const struct floatformat *fmt,
		const gdb_byte *from, gdb_mpfr &to) const;
  void from_target (const struct type *type,
		const gdb_byte *from, gdb_mpfr &to) const;

  void to_target (const struct type *type,
		  const gdb_mpfr &from, gdb_byte *to) const;
  void to_target (const struct floatformat *fmt,
		  const gdb_mpfr &from, gdb_byte *to) const;
};


/* Convert TO/FROM target floating-point format to mpfr_t.  */

void
mpfr_float_ops::from_target (const struct floatformat *fmt,
			     const gdb_byte *orig_from, gdb_mpfr &to) const
{
  const gdb_byte *from = orig_from;
  mpfr_exp_t exponent;
  unsigned long mant;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  int special_exponent;		/* It's a NaN, denorm or zero.  */
  enum floatformat_byteorders order;
  unsigned char newfrom[FLOATFORMAT_LARGEST_BYTES];
  enum float_kind kind;

  gdb_assert (fmt->totalsize
	      <= FLOATFORMAT_LARGEST_BYTES * FLOATFORMAT_CHAR_BIT);

  /* Handle non-numbers.  */
  kind = floatformat_classify (fmt, from);
  if (kind == float_infinite)
    {
      mpfr_set_inf (to.val, floatformat_is_negative (fmt, from) ? -1 : 1);
      return;
    }
  if (kind == float_nan)
    {
      mpfr_set_nan (to.val);
      return;
    }

  order = floatformat_normalize_byteorder (fmt, from, newfrom);

  if (order != fmt->byteorder)
    from = newfrom;

  if (fmt->split_half)
    {
      gdb_mpfr top (to), bot (to);

      from_target (fmt->split_half, from, top);
      /* Preserve the sign of 0, which is the sign of the top half.  */
      if (mpfr_zero_p (top.val))
	{
	  mpfr_set (to.val, top.val, MPFR_RNDN);
	  return;
	}
      from_target (fmt->split_half,
	       from + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2, bot);
      mpfr_add (to.val, top.val, bot.val, MPFR_RNDN);
      return;
    }

  exponent = get_field (from, order, fmt->totalsize, fmt->exp_start,
			fmt->exp_len);
  /* Note that if exponent indicates a NaN, we can't really do anything useful
     (not knowing if the host has NaN's, or how to build one).  So it will
     end up as an infinity or something close; that is OK.  */

  mant_bits_left = fmt->man_len;
  mant_off = fmt->man_start;
  mpfr_set_zero (to.val, 0);

  special_exponent = exponent == 0 || exponent == fmt->exp_nan;

  /* Don't bias NaNs.  Use minimum exponent for denorms.  For
     simplicity, we don't check for zero as the exponent doesn't matter.
     Note the cast to int; exp_bias is unsigned, so it's important to
     make sure the operation is done in signed arithmetic.  */
  if (!special_exponent)
    exponent -= fmt->exp_bias;
  else if (exponent == 0)
    exponent = 1 - fmt->exp_bias;

  /* Build the result algebraically.  Might go infinite, underflow, etc;
     who cares.  */

  /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
     increment the exponent by one to account for the integer bit.  */

  if (!special_exponent)
    {
      if (fmt->intbit == floatformat_intbit_no)
	mpfr_set_ui_2exp (to.val, 1, exponent, MPFR_RNDN);
      else
	exponent++;
    }

  gdb_mpfr tmp (to);

  while (mant_bits_left > 0)
    {
      mant_bits = std::min (mant_bits_left, 32);

      mant = get_field (from, order, fmt->totalsize, mant_off, mant_bits);

      mpfr_set_ui (tmp.val, mant, MPFR_RNDN);
      mpfr_mul_2si (tmp.val, tmp.val, exponent - mant_bits, MPFR_RNDN);
      mpfr_add (to.val, to.val, tmp.val, MPFR_RNDN);
      exponent -= mant_bits;
      mant_off += mant_bits;
      mant_bits_left -= mant_bits;
    }

  /* Negate it if negative.  */
  if (get_field (from, order, fmt->totalsize, fmt->sign_start, 1))
    mpfr_neg (to.val, to.val, MPFR_RNDN);
}

void
mpfr_float_ops::from_target (const struct type *type,
			     const gdb_byte *from, gdb_mpfr &to) const
{
  from_target (floatformat_from_type (type), from, to);
}

void
mpfr_float_ops::to_target (const struct floatformat *fmt,
			   const gdb_mpfr &from, gdb_byte *orig_to) const
{
  unsigned char *to = orig_to;
  mpfr_exp_t exponent;
  unsigned int mant_bits, mant_off;
  int mant_bits_left;
  enum floatformat_byteorders order = fmt->byteorder;
  unsigned char newto[FLOATFORMAT_LARGEST_BYTES];

  if (order != floatformat_little)
    order = floatformat_big;

  if (order != fmt->byteorder)
    to = newto;

  memset (to, 0, floatformat_totalsize_bytes (fmt));

  if (fmt->split_half)
    {
      gdb_mpfr top (from), bot (from);

      mpfr_set (top.val, from.val, MPFR_RNDN);
      /* If the rounded top half is Inf, the bottom must be 0 not NaN
	 or Inf.  */
      if (mpfr_inf_p (top.val))
	mpfr_set_zero (bot.val, 0);
      else
	mpfr_sub (bot.val, from.val, top.val, MPFR_RNDN);

      to_target (fmt->split_half, top, to);
      to_target (fmt->split_half, bot,
		 to + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2);
      return;
    }

  gdb_mpfr tmp (from);

  if (mpfr_zero_p (from.val))
    goto finalize_byteorder;	/* Result is zero */

  mpfr_set (tmp.val, from.val, MPFR_RNDN);

  if (mpfr_nan_p (tmp.val))	/* Result is NaN */
    {
      /* From is NaN */
      put_field (to, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      /* Be sure it's not infinity, but NaN value is irrel.  */
      put_field (to, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 1);
      goto finalize_byteorder;
    }

  /* If negative, set the sign bit.  */
  if (mpfr_sgn (tmp.val) < 0)
    {
      put_field (to, order, fmt->totalsize, fmt->sign_start, 1, 1);
      mpfr_neg (tmp.val, tmp.val, MPFR_RNDN);
    }

  if (mpfr_inf_p (tmp.val))		/* Result is Infinity.  */
    {
      /* Infinity exponent is same as NaN's.  */
      put_field (to, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      /* Infinity mantissa is all zeroes.  */
      put_field (to, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  mpfr_frexp (&exponent, tmp.val, tmp.val, MPFR_RNDN);

  if (exponent + fmt->exp_bias <= 0)
    {
      /* The value is too small to be expressed in the destination
	 type (not enough bits in the exponent.  Treat as 0.  */
      put_field (to, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, 0);
      put_field (to, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  if (exponent + fmt->exp_bias >= (1 << fmt->exp_len))
    {
      /* The value is too large to fit into the destination.
	 Treat as infinity.  */
      put_field (to, order, fmt->totalsize, fmt->exp_start,
		 fmt->exp_len, fmt->exp_nan);
      put_field (to, order, fmt->totalsize, fmt->man_start,
		 fmt->man_len, 0);
      goto finalize_byteorder;
    }

  put_field (to, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
	     exponent + fmt->exp_bias - 1);

  mant_bits_left = fmt->man_len;
  mant_off = fmt->man_start;
  while (mant_bits_left > 0)
    {
      unsigned long mant_long;

      mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;

      mpfr_mul_2ui (tmp.val, tmp.val, 32, MPFR_RNDN);
      mant_long = mpfr_get_ui (tmp.val, MPFR_RNDZ) & 0xffffffffL;
      mpfr_sub_ui (tmp.val, tmp.val, mant_long, MPFR_RNDZ);

      /* If the integer bit is implicit, then we need to discard it.
         If we are discarding a zero, we should be (but are not) creating
         a denormalized number which means adjusting the exponent
         (I think).  */
      if (mant_bits_left == fmt->man_len
	  && fmt->intbit == floatformat_intbit_no)
	{
	  mant_long <<= 1;
	  mant_long &= 0xffffffffL;
          /* If we are processing the top 32 mantissa bits of a doublest
             so as to convert to a float value with implied integer bit,
             we will only be putting 31 of those 32 bits into the
             final value due to the discarding of the top bit.  In the
             case of a small float value where the number of mantissa
             bits is less than 32, discarding the top bit does not alter
             the number of bits we will be adding to the result.  */
          if (mant_bits == 32)
            mant_bits -= 1;
	}

      if (mant_bits < 32)
	{
	  /* The bits we want are in the most significant MANT_BITS bits of
	     mant_long.  Move them to the least significant.  */
	  mant_long >>= 32 - mant_bits;
	}

      put_field (to, order, fmt->totalsize,
		 mant_off, mant_bits, mant_long);
      mant_off += mant_bits;
      mant_bits_left -= mant_bits;
    }

 finalize_byteorder:
  /* Do we need to byte-swap the words in the result?  */
  if (order != fmt->byteorder)
    floatformat_normalize_byteorder (fmt, newto, orig_to);
}

void
mpfr_float_ops::to_target (const struct type *type,
			   const gdb_mpfr &from, gdb_byte *to) const
{
  /* Ensure possible padding bytes in the target buffer are zeroed out.  */
  memset (to, 0, TYPE_LENGTH (type));

  to_target (floatformat_from_type (type), from, to);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a string, optionally using the print format FORMAT.  */
std::string
mpfr_float_ops::to_string (const gdb_byte *addr,
			   const struct type *type,
			   const char *format) const
{
  const struct floatformat *fmt = floatformat_from_type (type);

  /* Unless we need to adhere to a specific format, provide special
     output for certain cases.  */
  if (format == nullptr)
    {
      /* Detect invalid representations.  */
      if (!floatformat_is_valid (fmt, addr))
	return "<invalid float value>";

      /* Handle NaN and Inf.  */
      enum float_kind kind = floatformat_classify (fmt, addr);
      if (kind == float_nan)
	{
	  const char *sign = floatformat_is_negative (fmt, addr)? "-" : "";
	  const char *mantissa = floatformat_mantissa (fmt, addr);
	  return string_printf ("%snan(0x%s)", sign, mantissa);
	}
      else if (kind == float_infinite)
	{
	  const char *sign = floatformat_is_negative (fmt, addr)? "-" : "";
	  return string_printf ("%sinf", sign);
	}
    }

  /* Determine the format string to use on the host side.  */
  std::string host_format = floatformat_printf_format (fmt, format, 'R');

  gdb_mpfr tmp (type);
  from_target (type, addr, tmp);

  int size = mpfr_snprintf (NULL, 0, host_format.c_str (), tmp.val);
  std::string str (size, '\0');
  mpfr_sprintf (&str[0], host_format.c_str (), tmp.val);

  return str;
}

/* Parse string STRING into a target floating-number of type TYPE and
   store it as byte-stream ADDR.  Return whether parsing succeeded.  */
bool
mpfr_float_ops::from_string (gdb_byte *addr,
			     const struct type *type,
			     const std::string &in) const
{
  gdb_mpfr tmp (type);

  char *endptr;
  mpfr_strtofr (tmp.val, in.c_str (), &endptr, 0, MPFR_RNDN);

  /* We only accept the whole string.  */
  if (*endptr)
    return false;

  to_target (type, tmp, addr);
  return true;
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to an integer value (rounding towards zero).  */
LONGEST
mpfr_float_ops::to_longest (const gdb_byte *addr,
			    const struct type *type) const
{
  gdb_mpfr tmp (type);
  from_target (type, addr, tmp);
  return mpfr_get_sj (tmp.val, MPFR_RNDZ);
}

/* Convert signed integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
void
mpfr_float_ops::from_longest (gdb_byte *addr,
			      const struct type *type,
			      LONGEST val) const
{
  gdb_mpfr tmp (type);
  mpfr_set_sj (tmp.val, val, MPFR_RNDN);
  to_target (type, tmp, addr);
}

/* Convert unsigned integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
void
mpfr_float_ops::from_ulongest (gdb_byte *addr,
			       const struct type *type,
			       ULONGEST val) const
{
  gdb_mpfr tmp (type);
  mpfr_set_uj (tmp.val, val, MPFR_RNDN);
  to_target (type, tmp, addr);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a floating-point value in the host "double" format.  */
double
mpfr_float_ops::to_host_double (const gdb_byte *addr,
				const struct type *type) const
{
  gdb_mpfr tmp (type);
  from_target (type, addr, tmp);
  return mpfr_get_d (tmp.val, MPFR_RNDN);
}

/* Convert floating-point value VAL in the host "double" format to a target
   floating-number of type TYPE and store it as byte-stream ADDR.  */
void
mpfr_float_ops::from_host_double (gdb_byte *addr,
				  const struct type *type,
				  double val) const
{
  gdb_mpfr tmp (type);
  mpfr_set_d (tmp.val, val, MPFR_RNDN);
  to_target (type, tmp, addr);
}

/* Convert a floating-point number of type FROM_TYPE from the target
   byte-stream FROM to a floating-point number of type TO_TYPE, and
   store it to the target byte-stream TO.  */
void
mpfr_float_ops::convert (const gdb_byte *from,
			 const struct type *from_type,
			 gdb_byte *to,
			 const struct type *to_type) const
{
  gdb_mpfr from_tmp (from_type), to_tmp (to_type);
  from_target (from_type, from, from_tmp);
  mpfr_set (to_tmp.val, from_tmp.val, MPFR_RNDN);
  to_target (to_type, to_tmp, to);
}

/* Perform the binary operation indicated by OPCODE, using as operands the
   target byte streams X and Y, interpreted as floating-point numbers of
   types TYPE_X and TYPE_Y, respectively.  Convert the result to type
   TYPE_RES and store it into the byte-stream RES.  */
void
mpfr_float_ops::binop (enum exp_opcode op,
		       const gdb_byte *x, const struct type *type_x,
		       const gdb_byte *y, const struct type *type_y,
		       gdb_byte *res, const struct type *type_res) const
{
  gdb_mpfr x_tmp (type_x), y_tmp (type_y), tmp (type_res);

  from_target (type_x, x, x_tmp);
  from_target (type_y, y, y_tmp);

  switch (op)
    {
      case BINOP_ADD:
	mpfr_add (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_SUB:
	mpfr_sub (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_MUL:
	mpfr_mul (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_DIV:
	mpfr_div (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_EXP:
	mpfr_pow (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_MIN:
	mpfr_min (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      case BINOP_MAX:
	mpfr_max (tmp.val, x_tmp.val, y_tmp.val, MPFR_RNDN);
	break;

      default:
	error (_("Integer-only operation on floating point number."));
	break;
    }

  to_target (type_res, tmp, res);
}

/* Compare the two target byte streams X and Y, interpreted as floating-point
   numbers of types TYPE_X and TYPE_Y, respectively.  Return zero if X and Y
   are equal, -1 if X is less than Y, and 1 otherwise.  */
int
mpfr_float_ops::compare (const gdb_byte *x, const struct type *type_x,
			 const gdb_byte *y, const struct type *type_y) const
{
  gdb_mpfr x_tmp (type_x), y_tmp (type_y);

  from_target (type_x, x, x_tmp);
  from_target (type_y, y, y_tmp);

  if (mpfr_equal_p (x_tmp.val, y_tmp.val))
    return 0;
  else if (mpfr_less_p (x_tmp.val, y_tmp.val))
    return -1;
  else
    return 1;
}

#endif


/* Helper routines operating on decimal floating-point data.  */

/* Decimal floating point is one of the extension to IEEE 754, which is
   described in http://grouper.ieee.org/groups/754/revision.html and
   http://www2.hursley.ibm.com/decimal/.  It completes binary floating
   point by representing floating point more exactly.  */

/* The order of the following headers is important for making sure
   decNumber structure is large enough to hold decimal128 digits.  */

#include "dpd/decimal128.h"
#include "dpd/decimal64.h"
#include "dpd/decimal32.h"

/* When using decimal128, this is the maximum string length + 1
   (value comes from libdecnumber's DECIMAL128_String constant).  */
#define MAX_DECIMAL_STRING  43

/* In GDB, we are using an array of gdb_byte to represent decimal values.
   They are stored in host byte order.  This routine does the conversion if
   the target byte order is different.  */
static void
match_endianness (const gdb_byte *from, const struct type *type, gdb_byte *to)
{
  gdb_assert (TYPE_CODE (type) == TYPE_CODE_DECFLOAT);

  int len = TYPE_LENGTH (type);
  int i;

#if WORDS_BIGENDIAN
#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
#else
#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
#endif

  if (gdbarch_byte_order (get_type_arch (type)) == OPPOSITE_BYTE_ORDER)
    for (i = 0; i < len; i++)
      to[i] = from[len - i - 1];
  else
    for (i = 0; i < len; i++)
      to[i] = from[i];

  return;
}

/* Helper function to get the appropriate libdecnumber context for each size
   of decimal float.  */
static void
set_decnumber_context (decContext *ctx, const struct type *type)
{
  gdb_assert (TYPE_CODE (type) == TYPE_CODE_DECFLOAT);

  switch (TYPE_LENGTH (type))
    {
      case 4:
	decContextDefault (ctx, DEC_INIT_DECIMAL32);
	break;
      case 8:
	decContextDefault (ctx, DEC_INIT_DECIMAL64);
	break;
      case 16:
	decContextDefault (ctx, DEC_INIT_DECIMAL128);
	break;
    }

  ctx->traps = 0;
}

/* Check for errors signaled in the decimal context structure.  */
static void
decimal_check_errors (decContext *ctx)
{
  /* An error here could be a division by zero, an overflow, an underflow or
     an invalid operation (from the DEC_Errors constant in decContext.h).
     Since GDB doesn't complain about division by zero, overflow or underflow
     errors for binary floating, we won't complain about them for decimal
     floating either.  */
  if (ctx->status & DEC_IEEE_854_Invalid_operation)
    {
      /* Leave only the error bits in the status flags.  */
      ctx->status &= DEC_IEEE_854_Invalid_operation;
      error (_("Cannot perform operation: %s"),
	     decContextStatusToString (ctx));
    }
}

/* Helper function to convert from libdecnumber's appropriate representation
   for computation to each size of decimal float.  */
static void
decimal_from_number (const decNumber *from,
                     gdb_byte *to, const struct type *type)
{
  gdb_byte dec[16];

  decContext set;

  set_decnumber_context (&set, type);

  switch (TYPE_LENGTH (type))
    {
      case 4:
	decimal32FromNumber ((decimal32 *) dec, from, &set);
	break;
      case 8:
	decimal64FromNumber ((decimal64 *) dec, from, &set);
	break;
      case 16:
	decimal128FromNumber ((decimal128 *) dec, from, &set);
	break;
      default:
	error (_("Unknown decimal floating point type."));
	break;
    }

  match_endianness (dec, type, to);
}

/* Helper function to convert each size of decimal float to libdecnumber's
   appropriate representation for computation.  */
static void
decimal_to_number (const gdb_byte *addr, const struct type *type,
                   decNumber *to)
{
  gdb_byte dec[16];
  match_endianness (addr, type, dec);

  switch (TYPE_LENGTH (type))
    {
      case 4:
	decimal32ToNumber ((decimal32 *) dec, to);
	break;
      case 8:
	decimal64ToNumber ((decimal64 *) dec, to);
	break;
      case 16:
	decimal128ToNumber ((decimal128 *) dec, to);
	break;
      default:
	error (_("Unknown decimal floating point type."));
	break;
    }
}

/* Returns true if ADDR (which is of type TYPE) is the number zero.  */
static bool
decimal_is_zero (const gdb_byte *addr, const struct type *type)
{
  decNumber number;

  decimal_to_number (addr, type, &number);

  return decNumberIsZero (&number);
}


/* Implementation of target_float_ops using the libdecnumber decNumber type
   as intermediate format.  */

class decimal_float_ops : public target_float_ops
{
public:
  std::string to_string (const gdb_byte *addr, const struct type *type,
			 const char *format) const override;
  bool from_string (gdb_byte *addr, const struct type *type,
		    const std::string &string) const override;

  LONGEST to_longest (const gdb_byte *addr,
		      const struct type *type) const override;
  void from_longest (gdb_byte *addr, const struct type *type,
		     LONGEST val) const override;
  void from_ulongest (gdb_byte *addr, const struct type *type,
		      ULONGEST val) const override;
  double to_host_double (const gdb_byte *addr,
			 const struct type *type) const override
  {
    /* We don't support conversions between target decimal floating-point
       types and the host double type.  */
    gdb_assert_not_reached ("invalid operation on decimal float");
  }
  void from_host_double (gdb_byte *addr, const struct type *type,
			 double val) const override
  {
    /* We don't support conversions between target decimal floating-point
       types and the host double type.  */
    gdb_assert_not_reached ("invalid operation on decimal float");
  }
  void convert (const gdb_byte *from, const struct type *from_type,
		gdb_byte *to, const struct type *to_type) const override;

  void binop (enum exp_opcode opcode,
	      const gdb_byte *x, const struct type *type_x,
	      const gdb_byte *y, const struct type *type_y,
	      gdb_byte *res, const struct type *type_res) const override;
  int compare (const gdb_byte *x, const struct type *type_x,
	       const gdb_byte *y, const struct type *type_y) const override;
};

/* Convert decimal type to its string representation.  LEN is the length
   of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
   16 bytes for decimal128.  */
std::string
decimal_float_ops::to_string (const gdb_byte *addr, const struct type *type,
			      const char *format = nullptr) const
{
  gdb_byte dec[16];

  match_endianness (addr, type, dec);

  if (format != nullptr)
    {
      /* We don't handle format strings (yet).  If the host printf supports
	 decimal floating point types, just use this.  Otherwise, fall back
	 to printing the number while ignoring the format string.  */
#if defined (PRINTF_HAS_DECFLOAT)
      /* FIXME: This makes unwarranted assumptions about the host ABI!  */
      return string_printf (format, dec);
#endif
    }

  std::string result;
  result.resize (MAX_DECIMAL_STRING);

  switch (TYPE_LENGTH (type))
    {
      case 4:
	decimal32ToString ((decimal32 *) dec, &result[0]);
	break;
      case 8:
	decimal64ToString ((decimal64 *) dec, &result[0]);
	break;
      case 16:
	decimal128ToString ((decimal128 *) dec, &result[0]);
	break;
      default:
	error (_("Unknown decimal floating point type."));
	break;
    }

  return result;
}

/* Convert the string form of a decimal value to its decimal representation.
   LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
   decimal64 and 16 bytes for decimal128.  */
bool
decimal_float_ops::from_string (gdb_byte *addr, const struct type *type,
				const std::string &string) const
{
  decContext set;
  gdb_byte dec[16];

  set_decnumber_context (&set, type);

  switch (TYPE_LENGTH (type))
    {
      case 4:
	decimal32FromString ((decimal32 *) dec, string.c_str (), &set);
	break;
      case 8:
	decimal64FromString ((decimal64 *) dec, string.c_str (), &set);
	break;
      case 16:
	decimal128FromString ((decimal128 *) dec, string.c_str (), &set);
	break;
      default:
	error (_("Unknown decimal floating point type."));
	break;
    }

  match_endianness (dec, type, addr);

  /* Check for errors in the DFP operation.  */
  decimal_check_errors (&set);

  return true;
}

/* Converts a LONGEST to a decimal float of specified LEN bytes.  */
void
decimal_float_ops::from_longest (gdb_byte *addr, const struct type *type,
				 LONGEST from) const
{
  decNumber number;

  if ((int32_t) from != from)
    /* libdecnumber can convert only 32-bit integers.  */
    error (_("Conversion of large integer to a "
	     "decimal floating type is not supported."));

  decNumberFromInt32 (&number, (int32_t) from);

  decimal_from_number (&number, addr, type);
}

/* Converts a ULONGEST to a decimal float of specified LEN bytes.  */
void
decimal_float_ops::from_ulongest (gdb_byte *addr, const struct type *type,
				  ULONGEST from) const
{
  decNumber number;

  if ((uint32_t) from != from)
    /* libdecnumber can convert only 32-bit integers.  */
    error (_("Conversion of large integer to a "
	     "decimal floating type is not supported."));

  decNumberFromUInt32 (&number, (uint32_t) from);

  decimal_from_number (&number, addr, type);
}

/* Converts a decimal float of LEN bytes to a LONGEST.  */
LONGEST
decimal_float_ops::to_longest (const gdb_byte *addr,
                               const struct type *type) const
{
  /* libdecnumber has a function to convert from decimal to integer, but
     it doesn't work when the decimal number has a fractional part.  */
  std::string str = to_string (addr, type);
  return strtoll (str.c_str (), NULL, 10);
}

/* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
   and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
   RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT.  */
void
decimal_float_ops::binop (enum exp_opcode op,
			  const gdb_byte *x, const struct type *type_x,
			  const gdb_byte *y, const struct type *type_y,
			  gdb_byte *res, const struct type *type_res) const
{
  decContext set;
  decNumber number1, number2, number3;

  decimal_to_number (x, type_x, &number1);
  decimal_to_number (y, type_y, &number2);

  set_decnumber_context (&set, type_res);

  switch (op)
    {
      case BINOP_ADD:
	decNumberAdd (&number3, &number1, &number2, &set);
	break;
      case BINOP_SUB:
	decNumberSubtract (&number3, &number1, &number2, &set);
	break;
      case BINOP_MUL:
	decNumberMultiply (&number3, &number1, &number2, &set);
	break;
      case BINOP_DIV:
	decNumberDivide (&number3, &number1, &number2, &set);
	break;
      case BINOP_EXP:
	decNumberPower (&number3, &number1, &number2, &set);
	break;
     default:
	error (_("Operation not valid for decimal floating point number."));
	break;
    }

  /* Check for errors in the DFP operation.  */
  decimal_check_errors (&set);

  decimal_from_number (&number3, res, type_res);
}

/* Compares two numbers numerically.  If X is less than Y then the return value
   will be -1.  If they are equal, then the return value will be 0.  If X is
   greater than the Y then the return value will be 1.  */
int
decimal_float_ops::compare (const gdb_byte *x, const struct type *type_x,
			    const gdb_byte *y, const struct type *type_y) const
{
  decNumber number1, number2, result;
  decContext set;
  const struct type *type_result;

  decimal_to_number (x, type_x, &number1);
  decimal_to_number (y, type_y, &number2);

  /* Perform the comparison in the larger of the two sizes.  */
  type_result = TYPE_LENGTH (type_x) > TYPE_LENGTH (type_y) ? type_x : type_y;
  set_decnumber_context (&set, type_result);

  decNumberCompare (&result, &number1, &number2, &set);

  /* Check for errors in the DFP operation.  */
  decimal_check_errors (&set);

  if (decNumberIsNaN (&result))
    error (_("Comparison with an invalid number (NaN)."));
  else if (decNumberIsZero (&result))
    return 0;
  else if (decNumberIsNegative (&result))
    return -1;
  else
    return 1;
}

/* Convert a decimal value from a decimal type with LEN_FROM bytes to a
   decimal type with LEN_TO bytes.  */
void
decimal_float_ops::convert (const gdb_byte *from, const struct type *from_type,
			    gdb_byte *to, const struct type *to_type) const
{
  decNumber number;

  decimal_to_number (from, from_type, &number);
  decimal_from_number (&number, to, to_type);
}


/* Typed floating-point routines.  These routines operate on floating-point
   values in target format, represented by a byte buffer interpreted as a
   "struct type", which may be either a binary or decimal floating-point
   type (TYPE_CODE_FLT or TYPE_CODE_DECFLOAT).  */

/* Return whether TYPE1 and TYPE2 are of the same category (binary or
   decimal floating-point).  */
static bool
target_float_same_category_p (const struct type *type1,
			      const struct type *type2)
{
  return TYPE_CODE (type1) == TYPE_CODE (type2);
}

/* Return whether TYPE1 and TYPE2 use the same floating-point format.  */
static bool
target_float_same_format_p (const struct type *type1,
			    const struct type *type2)
{
  if (!target_float_same_category_p (type1, type2))
    return false;

  switch (TYPE_CODE (type1))
    {
      case TYPE_CODE_FLT:
	return floatformat_from_type (type1) == floatformat_from_type (type2);

      case TYPE_CODE_DECFLOAT:
	return (TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
		&& (gdbarch_byte_order (get_type_arch (type1))
		    == gdbarch_byte_order (get_type_arch (type2))));

      default:
	gdb_assert_not_reached ("unexpected type code");
    }
}

/* Return the size (without padding) of the target floating-point
   format used by TYPE.  */
static int
target_float_format_length (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
      case TYPE_CODE_FLT:
	return floatformat_totalsize_bytes (floatformat_from_type (type));

      case TYPE_CODE_DECFLOAT:
	return TYPE_LENGTH (type);

      default:
	gdb_assert_not_reached ("unexpected type code");
    }
}

/* Identifiers of available host-side intermediate formats.  These must
   be sorted so the that the more "general" kinds come later.  */
enum target_float_ops_kind
{
  /* Target binary floating-point formats that match a host format.  */
  host_float = 0,
  host_double,
  host_long_double,
  /* Any other target binary floating-point format.  */
  binary,
  /* Any target decimal floating-point format.  */
  decimal
};

/* Given a target type TYPE, choose the best host-side intermediate format
   to perform operations on TYPE in.  */
static enum target_float_ops_kind
get_target_float_ops_kind (const struct type *type)
{
  switch (TYPE_CODE (type))
    {
      case TYPE_CODE_FLT:
        {
	  const struct floatformat *fmt = floatformat_from_type (type);

	  /* Binary floating-point formats matching a host format.  */
	  if (fmt == host_float_format)
	    return target_float_ops_kind::host_float;
	  if (fmt == host_double_format)
	    return target_float_ops_kind::host_double;
	  if (fmt == host_long_double_format)
	    return target_float_ops_kind::host_long_double;

	  /* Any other binary floating-point format.  */
	  return target_float_ops_kind::binary;
	}

      case TYPE_CODE_DECFLOAT:
	{
	  /* Any decimal floating-point format.  */
	  return target_float_ops_kind::decimal;
	}

      default:
	gdb_assert_not_reached ("unexpected type code");
    }
}

/* Return target_float_ops to peform operations for KIND.  */
static const target_float_ops *
get_target_float_ops (enum target_float_ops_kind kind)
{
  switch (kind)
    {
      /* If the type format matches one of the host floating-point
	 types, use that type as intermediate format.  */
      case target_float_ops_kind::host_float:
        {
	  static host_float_ops<float> host_float_ops_float;
	  return &host_float_ops_float;
	}

      case target_float_ops_kind::host_double:
        {
	  static host_float_ops<double> host_float_ops_double;
	  return &host_float_ops_double;
	}

      case target_float_ops_kind::host_long_double:
        {
	  static host_float_ops<long double> host_float_ops_long_double;
	  return &host_float_ops_long_double;
	}

      /* For binary floating-point formats that do not match any host format,
         use mpfr_t as intermediate format to provide precise target-floating
         point emulation.  However, if the MPFR library is not availabe,
         use the largest host floating-point type as intermediate format.  */
      case target_float_ops_kind::binary:
        {
#ifdef HAVE_LIBMPFR
	  static mpfr_float_ops binary_float_ops;
#else
	  static host_float_ops<long double> binary_float_ops;
#endif
	  return &binary_float_ops;
	}

      /* For decimal floating-point types, always use the libdecnumber
	 decNumber type as intermediate format.  */
      case target_float_ops_kind::decimal:
	{
	  static decimal_float_ops decimal_float_ops;
	  return &decimal_float_ops;
	}

      default:
	gdb_assert_not_reached ("unexpected target_float_ops_kind");
    }
}

/* Given a target type TYPE, determine the best host-side intermediate format
   to perform operations on TYPE in.  */
static const target_float_ops *
get_target_float_ops (const struct type *type)
{
  enum target_float_ops_kind kind = get_target_float_ops_kind (type);
  return get_target_float_ops (kind);
}

/* The same for operations involving two target types TYPE1 and TYPE2.  */
static const target_float_ops *
get_target_float_ops (const struct type *type1, const struct type *type2)
{
  gdb_assert (TYPE_CODE (type1) == TYPE_CODE (type2));

  enum target_float_ops_kind kind1 = get_target_float_ops_kind (type1);
  enum target_float_ops_kind kind2 = get_target_float_ops_kind (type2);

  /* Given the way the kinds are sorted, we simply choose the larger one;
     this will be able to hold values of either type.  */
  return get_target_float_ops (std::max (kind1, kind2));
}

/* Return whether the byte-stream ADDR holds a valid value of
   floating-point type TYPE.  */
bool
target_float_is_valid (const gdb_byte *addr, const struct type *type)
{
  if (TYPE_CODE (type) == TYPE_CODE_FLT)
    return floatformat_is_valid (floatformat_from_type (type), addr);

  if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
    return true;

  gdb_assert_not_reached ("unexpected type code");
}

/* Return whether the byte-stream ADDR, interpreted as floating-point
   type TYPE, is numerically equal to zero (of either sign).  */
bool
target_float_is_zero (const gdb_byte *addr, const struct type *type)
{
  if (TYPE_CODE (type) == TYPE_CODE_FLT)
    return (floatformat_classify (floatformat_from_type (type), addr)
	    == float_zero);

  if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
    return decimal_is_zero (addr, type);

  gdb_assert_not_reached ("unexpected type code");
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a string, optionally using the print format FORMAT.  */
std::string
target_float_to_string (const gdb_byte *addr, const struct type *type,
			const char *format)
{
  /* Unless we need to adhere to a specific format, provide special
     output for special cases of binary floating-point numbers.  */
  if (format == nullptr && TYPE_CODE (type) == TYPE_CODE_FLT)
    {
      const struct floatformat *fmt = floatformat_from_type (type);

      /* Detect invalid representations.  */
      if (!floatformat_is_valid (fmt, addr))
	return "<invalid float value>";

      /* Handle NaN and Inf.  */
      enum float_kind kind = floatformat_classify (fmt, addr);
      if (kind == float_nan)
	{
	  const char *sign = floatformat_is_negative (fmt, addr)? "-" : "";
	  const char *mantissa = floatformat_mantissa (fmt, addr);
	  return string_printf ("%snan(0x%s)", sign, mantissa);
	}
      else if (kind == float_infinite)
	{
	  const char *sign = floatformat_is_negative (fmt, addr)? "-" : "";
	  return string_printf ("%sinf", sign);
	}
    }

  const target_float_ops *ops = get_target_float_ops (type);
  return ops->to_string (addr, type, format);
}

/* Parse string STRING into a target floating-number of type TYPE and
   store it as byte-stream ADDR.  Return whether parsing succeeded.  */
bool
target_float_from_string (gdb_byte *addr, const struct type *type,
			  const std::string &string)
{
  const target_float_ops *ops = get_target_float_ops (type);
  return ops->from_string (addr, type, string);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to an integer value (rounding towards zero).  */
LONGEST
target_float_to_longest (const gdb_byte *addr, const struct type *type)
{
  const target_float_ops *ops = get_target_float_ops (type);
  return ops->to_longest (addr, type);
}

/* Convert signed integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
void
target_float_from_longest (gdb_byte *addr, const struct type *type,
			   LONGEST val)
{
  const target_float_ops *ops = get_target_float_ops (type);
  ops->from_longest (addr, type, val);
}

/* Convert unsigned integer VAL to a target floating-number of type TYPE
   and store it as byte-stream ADDR.  */
void
target_float_from_ulongest (gdb_byte *addr, const struct type *type,
			    ULONGEST val)
{
  const target_float_ops *ops = get_target_float_ops (type);
  ops->from_ulongest (addr, type, val);
}

/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE,
   to a floating-point value in the host "double" format.  */
double
target_float_to_host_double (const gdb_byte *addr,
			     const struct type *type)
{
  const target_float_ops *ops = get_target_float_ops (type);
  return ops->to_host_double (addr, type);
}

/* Convert floating-point value VAL in the host "double" format to a target
   floating-number of type TYPE and store it as byte-stream ADDR.  */
void
target_float_from_host_double (gdb_byte *addr, const struct type *type,
			       double val)
{
  const target_float_ops *ops = get_target_float_ops (type);
  ops->from_host_double (addr, type, val);
}

/* Convert a floating-point number of type FROM_TYPE from the target
   byte-stream FROM to a floating-point number of type TO_TYPE, and
   store it to the target byte-stream TO.  */
void
target_float_convert (const gdb_byte *from, const struct type *from_type,
		      gdb_byte *to, const struct type *to_type)
{
  /* We cannot directly convert between binary and decimal floating-point
     types, so go via an intermediary string.  */
  if (!target_float_same_category_p (from_type, to_type))
    {
      std::string str = target_float_to_string (from, from_type);
      target_float_from_string (to, to_type, str);
      return;
    }

  /* Convert between two different formats in the same category.  */
  if (!target_float_same_format_p (from_type, to_type))
  {
    const target_float_ops *ops = get_target_float_ops (from_type, to_type);
    ops->convert (from, from_type, to, to_type);
    return;
  }

  /* The floating-point formats match, so we simply copy the data, ensuring
     possible padding bytes in the target buffer are zeroed out.  */
  memset (to, 0, TYPE_LENGTH (to_type));
  memcpy (to, from, target_float_format_length (to_type));
}

/* Perform the binary operation indicated by OPCODE, using as operands the
   target byte streams X and Y, interpreted as floating-point numbers of
   types TYPE_X and TYPE_Y, respectively.  Convert the result to type
   TYPE_RES and store it into the byte-stream RES.

   The three types must either be all binary floating-point types, or else
   all decimal floating-point types.  Binary and decimal floating-point
   types cannot be mixed within a single operation.  */
void
target_float_binop (enum exp_opcode opcode,
		    const gdb_byte *x, const struct type *type_x,
		    const gdb_byte *y, const struct type *type_y,
		    gdb_byte *res, const struct type *type_res)
{
  gdb_assert (target_float_same_category_p (type_x, type_res));
  gdb_assert (target_float_same_category_p (type_y, type_res));

  const target_float_ops *ops = get_target_float_ops (type_x, type_y);
  ops->binop (opcode, x, type_x, y, type_y, res, type_res);
}

/* Compare the two target byte streams X and Y, interpreted as floating-point
   numbers of types TYPE_X and TYPE_Y, respectively.  Return zero if X and Y
   are equal, -1 if X is less than Y, and 1 otherwise.

   The two types must either both be binary floating-point types, or else
   both be decimal floating-point types.  Binary and decimal floating-point
   types cannot compared directly against each other.  */
int
target_float_compare (const gdb_byte *x, const struct type *type_x,
		      const gdb_byte *y, const struct type *type_y)
{
  gdb_assert (target_float_same_category_p (type_x, type_y));

  const target_float_ops *ops = get_target_float_ops (type_x, type_y);
  return ops->compare (x, type_x, y, type_y);
}

