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

   Copyright (C) 2017-2020 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"
#include "gdbarch.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;
  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;
  T 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);

  DIAGNOSTIC_PUSH
  DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
  return string_printf (host_format.c_str (), host_float);
  DIAGNOSTIC_POP
}

/* 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";

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

  /* 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);
  T min_possible_range = static_cast<T>(std::numeric_limits<LONGEST>::min());
  T max_possible_range = -min_possible_range;
  /* host_float can be converted to an integer as long as it's in
     the range [min_possible_range, max_possible_range). If not, it is either
     too large, or too small, or is NaN; in this case return the maximum or
     minimum possible value.  */
  if (host_float < max_possible_range && host_float >= min_possible_range)
    return static_cast<LONGEST> (host_float);
  if (host_float < min_possible_range)
    return std::numeric_limits<LONGEST>::min();
  /* This line will be executed if host_float is NaN.  */
  return std::numeric_limits<LONGEST>::max();
}

/* 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 (type_byte_order (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)
		&& (type_byte_order (type1)
		    == type_byte_order (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 available,
         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);
}

