public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC v2][2/2] Target FP: Make use of MPFR if available
@ 2017-11-16 19:00 Ulrich Weigand
  2017-11-29  0:37 ` John Baldwin
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Ulrich Weigand @ 2017-11-16 19:00 UTC (permalink / raw)
  To: gdb-patches

[RFC v2][2/2] Target FP: Make use of MPFR if available

This second patch introduces mfpr_float_ops, an new implementation
of target_float_ops.  This implements precise emulation of target
floating-point formats using the MPFR library.  This is then used
to perform operations on types that do not match any host type.

Note that use of MPFR is still not required.  The patch adds
a configure option --with-mpfr similar to --with-expat.  If use of
MPFR is disabled via the option or MPFR is not available, code will
fall back to current behavior.  This means that operations on types
that do not match any host type will be implemented on the host
long double type instead.

A new test case verifies that we can correctly print the largest
__float128 value now.

Bye,
Ulrich


gdb/ChangeLog:

	* target-float.c [HAVE_LIBMPFR]: Include <mpfr.h>.
	(class mpfr_float_ops): New type.
	(mpfr_float_ops::from_target): Two new overloaded functions.
	(mpfr_float_ops::to_target): Likewise.
	(mpfr_float_ops::to_string): New function.
	(mpfr_float_ops::from_string): Likewise.
	(mpfr_float_ops::to_longest): Likewise.
	(mpfr_float_ops::from_longest): Likewise.
	(mpfr_float_ops::from_ulongest): Likewise.
	(mpfr_float_ops::to_host_double): Likewise.
	(mpfr_float_ops::from_host_double): Likewise.
	(mpfr_float_ops::convert): Likewise.
	(mpfr_float_ops::binop): Likewise.
	(mpfr_float_ops::compare): Likewise.
	(get_target_float_ops): Use mpfr_float_ops if available.

	* Makefile.in (LIBMPFR): Add define.
	(CLIBS): Add $(LIBMPFR).
	* configure.ac: Add --with-mpfr configure option.
	* configure: Regenerate.
	* config.in: Regenerate.

gdb/testsuite/ChangeLog:

	* gdb.base/float128.c (large128): New variable.
	* gdb.base/float128.exp: Add test to print largest __float128 value.


Index: binutils-gdb/gdb/target-float.c
===================================================================
--- binutils-gdb.orig/gdb/target-float.c
+++ binutils-gdb/gdb/target-float.c
@@ -1142,6 +1142,569 @@ host_float_ops<T>::compare (const gdb_by
 }
 
 
+/* Implementation of target_float_ops using the MPFR library
+   mpfr_t as intermediate type.  */
+
+#ifdef HAVE_LIBMPFR
+
+#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_si (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
@@ -1685,10 +2248,16 @@ get_target_float_ops (enum target_float_
 	}
 
       /* 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;
 	}
 
Index: binutils-gdb/gdb/testsuite/gdb.base/float128.c
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.base/float128.c
+++ binutils-gdb/gdb/testsuite/gdb.base/float128.c
@@ -21,6 +21,10 @@
 long double ld;
 __float128 f128;
 
+// Test largest IEEE-128 value.  This has to be supported since the
+// __float128 data type by definition is encoded as IEEE-128.
+__float128 large128 = 1.18973149535723176508575932662800702e+4932q;
+
 int main()
 {
   ld = 1.375l;
Index: binutils-gdb/gdb/testsuite/gdb.base/float128.exp
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.base/float128.exp
+++ binutils-gdb/gdb/testsuite/gdb.base/float128.exp
@@ -74,3 +74,6 @@ gdb_test_multiple "set var f128=20.375l"
 gdb_test "print ld" ".* = 10\\.375.*" "the value of ld is changed to 10.375"
 gdb_test "print f128" ".* = 20\\.375.*" "the value of f128 is changed to 20.375"
 
+# Test that we can correctly handle the largest IEEE-128 value
+gdb_test "print large128" ".* = 1\\.18973149535723176508575932662800702e\\+4932" "print large128"
+
Index: binutils-gdb/gdb/Makefile.in
===================================================================
--- binutils-gdb.orig/gdb/Makefile.in
+++ binutils-gdb/gdb/Makefile.in
@@ -194,6 +194,9 @@ LIBBABELTRACE = @LIBBABELTRACE@
 # Where is libipt?  This will be empty if libipt was not available.
 LIBIPT = @LIBIPT@
 
+# Where is libmpfr?  This will be empty if libmpfr was not available.
+LIBMPFR = @LIBMPFR@
+
 WARN_CFLAGS = @WARN_CFLAGS@
 WERROR_CFLAGS = @WERROR_CFLAGS@
 GDB_WARN_CFLAGS = $(WARN_CFLAGS)
@@ -703,7 +706,7 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(
 	$(XM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) \
 	@LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \
 	$(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \
-	$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV)
+	$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR)
 CDEPS = $(XM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) \
 	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU)
 
Index: binutils-gdb/gdb/config.in
===================================================================
--- binutils-gdb.orig/gdb/config.in
+++ binutils-gdb/gdb/config.in
@@ -249,6 +249,9 @@
 /* Define to 1 if you have the `mcheck' library (-lmcheck). */
 #undef HAVE_LIBMCHECK
 
+/* Define if you have the mpfr library. */
+#undef HAVE_LIBMPFR
+
 /* Define if Python 2.4 is being used. */
 #undef HAVE_LIBPYTHON2_4
 
Index: binutils-gdb/gdb/configure.ac
===================================================================
--- binutils-gdb.orig/gdb/configure.ac
+++ binutils-gdb/gdb/configure.ac
@@ -695,6 +695,28 @@ else
   fi
 fi
 
+AC_ARG_WITH(mpfr,
+  AS_HELP_STRING([--with-mpfr], [include MPFR support (auto/yes/no)]),
+  [], [with_mpfr=auto])
+AC_MSG_CHECKING([whether to use MPFR])
+AC_MSG_RESULT([$with_mpfr])
+
+if test "${with_mpfr}" = no; then
+  AC_MSG_WARN([MPFR support disabled; some features may be unavailable.])
+  HAVE_LIBMPFR=no
+else
+  AC_LIB_HAVE_LINKFLAGS([mpfr], [], [#include <mpfr.h>],
+			[mpfr_exp_t exp; mpfr_t x;
+			 mpfr_frexp (&exp, x, x, MPFR_RNDN);])
+  if test "$HAVE_LIBMPFR" != yes; then
+    if test "$with_mpfr" = yes; then
+      AC_MSG_ERROR([MPFR is missing or unusable])
+    else
+      AC_MSG_WARN([MPFR is missing or unusable; some features may be unavailable.])
+    fi
+  fi
+fi
+
 # --------------------- #
 # Check for libpython.  #
 # --------------------- #
Index: binutils-gdb/gdb/configure
===================================================================
--- binutils-gdb.orig/gdb/configure
+++ binutils-gdb/gdb/configure
@@ -682,6 +682,9 @@ PYTHON_LIBS
 PYTHON_CPPFLAGS
 PYTHON_CFLAGS
 python_prog_path
+LTLIBMPFR
+LIBMPFR
+HAVE_LIBMPFR
 LTLIBEXPAT
 LIBEXPAT
 HAVE_LIBEXPAT
@@ -838,6 +841,8 @@ with_system_readline
 with_jit_reader_dir
 with_expat
 with_libexpat_prefix
+with_mpfr
+with_libmpfr_prefix
 with_python
 with_guile
 enable_libmcheck
@@ -1560,6 +1565,9 @@ Optional Packages:
   --with-expat            include expat support (auto/yes/no)
   --with-libexpat-prefix[=DIR]  search for libexpat in DIR/include and DIR/lib
   --without-libexpat-prefix     don't search for libexpat in includedir and libdir
+  --with-mpfr             include MPFR support (auto/yes/no)
+  --with-libmpfr-prefix[=DIR]  search for libmpfr in DIR/include and DIR/lib
+  --without-libmpfr-prefix     don't search for libmpfr in includedir and libdir
   --with-python[=PYTHON]  include python support
                           (auto/yes/no/<python-program>)
   --with-guile[=GUILE]    include guile support
@@ -9643,6 +9651,497 @@ done
   fi
 fi
 
+
+# Check whether --with-mpfr was given.
+if test "${with_mpfr+set}" = set; then :
+  withval=$with_mpfr;
+else
+  with_mpfr=auto
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use MPFR" >&5
+$as_echo_n "checking whether to use MPFR... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_mpfr" >&5
+$as_echo "$with_mpfr" >&6; }
+
+if test "${with_mpfr}" = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: MPFR support disabled; some features may be unavailable." >&5
+$as_echo "$as_me: WARNING: MPFR support disabled; some features may be unavailable." >&2;}
+  HAVE_LIBMPFR=no
+else
+
+
+
+
+
+
+
+
+    use_additional=yes
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+    eval additional_includedir=\"$includedir\"
+    eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+
+# Check whether --with-libmpfr-prefix was given.
+if test "${with_libmpfr_prefix+set}" = set; then :
+  withval=$with_libmpfr_prefix;
+    if test "X$withval" = "Xno"; then
+      use_additional=no
+    else
+      if test "X$withval" = "X"; then
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+
+          eval additional_includedir=\"$includedir\"
+          eval additional_libdir=\"$libdir\"
+
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      else
+        additional_includedir="$withval/include"
+        additional_libdir="$withval/lib"
+      fi
+    fi
+
+fi
+
+      LIBMPFR=
+  LTLIBMPFR=
+  INCMPFR=
+  rpathdirs=
+  ltrpathdirs=
+  names_already_handled=
+  names_next_round='mpfr '
+  while test -n "$names_next_round"; do
+    names_this_round="$names_next_round"
+    names_next_round=
+    for name in $names_this_round; do
+      already_handled=
+      for n in $names_already_handled; do
+        if test "$n" = "$name"; then
+          already_handled=yes
+          break
+        fi
+      done
+      if test -z "$already_handled"; then
+        names_already_handled="$names_already_handled $name"
+                        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+        eval value=\"\$HAVE_LIB$uppername\"
+        if test -n "$value"; then
+          if test "$value" = yes; then
+            eval value=\"\$LIB$uppername\"
+            test -z "$value" || LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$value"
+            eval value=\"\$LTLIB$uppername\"
+            test -z "$value" || LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }$value"
+          else
+                                    :
+          fi
+        else
+                              found_dir=
+          found_la=
+          found_so=
+          found_a=
+          if test $use_additional = yes; then
+            if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
+              found_dir="$additional_libdir"
+              found_so="$additional_libdir/lib$name.$shlibext"
+              if test -f "$additional_libdir/lib$name.la"; then
+                found_la="$additional_libdir/lib$name.la"
+              fi
+            else
+              if test -f "$additional_libdir/lib$name.$libext"; then
+                found_dir="$additional_libdir"
+                found_a="$additional_libdir/lib$name.$libext"
+                if test -f "$additional_libdir/lib$name.la"; then
+                  found_la="$additional_libdir/lib$name.la"
+                fi
+              fi
+            fi
+          fi
+          if test "X$found_dir" = "X"; then
+            for x in $LDFLAGS $LTLIBMPFR; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+              case "$x" in
+                -L*)
+                  dir=`echo "X$x" | sed -e 's/^X-L//'`
+                  if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
+                    found_dir="$dir"
+                    found_so="$dir/lib$name.$shlibext"
+                    if test -f "$dir/lib$name.la"; then
+                      found_la="$dir/lib$name.la"
+                    fi
+                  else
+                    if test -f "$dir/lib$name.$libext"; then
+                      found_dir="$dir"
+                      found_a="$dir/lib$name.$libext"
+                      if test -f "$dir/lib$name.la"; then
+                        found_la="$dir/lib$name.la"
+                      fi
+                    fi
+                  fi
+                  ;;
+              esac
+              if test "X$found_dir" != "X"; then
+                break
+              fi
+            done
+          fi
+          if test "X$found_dir" != "X"; then
+                        LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }-L$found_dir -l$name"
+            if test "X$found_so" != "X"; then
+                                                        if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
+                                LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$found_so"
+              else
+                                                                                haveit=
+                for x in $ltrpathdirs; do
+                  if test "X$x" = "X$found_dir"; then
+                    haveit=yes
+                    break
+                  fi
+                done
+                if test -z "$haveit"; then
+                  ltrpathdirs="$ltrpathdirs $found_dir"
+                fi
+                                if test "$hardcode_direct" = yes; then
+                                                      LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$found_so"
+                else
+                  if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
+                                                            LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$found_so"
+                                                            haveit=
+                    for x in $rpathdirs; do
+                      if test "X$x" = "X$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      rpathdirs="$rpathdirs $found_dir"
+                    fi
+                  else
+                                                                                haveit=
+                    for x in $LDFLAGS $LIBMPFR; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                      if test "X$x" = "X-L$found_dir"; then
+                        haveit=yes
+                        break
+                      fi
+                    done
+                    if test -z "$haveit"; then
+                      LIBMPFR="${LIBMPFR}${LIBMPFR:+ }-L$found_dir"
+                    fi
+                    if test "$hardcode_minus_L" != no; then
+                                                                                        LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$found_so"
+                    else
+                                                                                                                                                                                LIBMPFR="${LIBMPFR}${LIBMPFR:+ }-l$name"
+                    fi
+                  fi
+                fi
+              fi
+            else
+              if test "X$found_a" != "X"; then
+                                LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$found_a"
+              else
+                                                LIBMPFR="${LIBMPFR}${LIBMPFR:+ }-L$found_dir -l$name"
+              fi
+            fi
+                        additional_includedir=
+            case "$found_dir" in
+              */lib | */lib/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
+                additional_includedir="$basedir/include"
+                ;;
+            esac
+            if test "X$additional_includedir" != "X"; then
+                                                                                                                if test "X$additional_includedir" != "X/usr/include"; then
+                haveit=
+                if test "X$additional_includedir" = "X/usr/local/include"; then
+                  if test -n "$GCC"; then
+                    case $host_os in
+                      linux*) haveit=yes;;
+                    esac
+                  fi
+                fi
+                if test -z "$haveit"; then
+                  for x in $CPPFLAGS $INCMPFR; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                    if test "X$x" = "X-I$additional_includedir"; then
+                      haveit=yes
+                      break
+                    fi
+                  done
+                  if test -z "$haveit"; then
+                    if test -d "$additional_includedir"; then
+                                            INCMPFR="${INCMPFR}${INCMPFR:+ }-I$additional_includedir"
+                    fi
+                  fi
+                fi
+              fi
+            fi
+                        if test -n "$found_la"; then
+                                                        save_libdir="$libdir"
+              case "$found_la" in
+                */* | *\\*) . "$found_la" ;;
+                *) . "./$found_la" ;;
+              esac
+              libdir="$save_libdir"
+                            for dep in $dependency_libs; do
+                case "$dep" in
+                  -L*)
+                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                                                                                                                                                                if test "X$additional_libdir" != "X/usr/lib"; then
+                      haveit=
+                      if test "X$additional_libdir" = "X/usr/local/lib"; then
+                        if test -n "$GCC"; then
+                          case $host_os in
+                            linux*) haveit=yes;;
+                          esac
+                        fi
+                      fi
+                      if test -z "$haveit"; then
+                        haveit=
+                        for x in $LDFLAGS $LIBMPFR; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LIBMPFR="${LIBMPFR}${LIBMPFR:+ }-L$additional_libdir"
+                          fi
+                        fi
+                        haveit=
+                        for x in $LDFLAGS $LTLIBMPFR; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+                          if test "X$x" = "X-L$additional_libdir"; then
+                            haveit=yes
+                            break
+                          fi
+                        done
+                        if test -z "$haveit"; then
+                          if test -d "$additional_libdir"; then
+                                                        LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }-L$additional_libdir"
+                          fi
+                        fi
+                      fi
+                    fi
+                    ;;
+                  -R*)
+                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
+                    if test "$enable_rpath" != no; then
+                                                                  haveit=
+                      for x in $rpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        rpathdirs="$rpathdirs $dir"
+                      fi
+                                                                  haveit=
+                      for x in $ltrpathdirs; do
+                        if test "X$x" = "X$dir"; then
+                          haveit=yes
+                          break
+                        fi
+                      done
+                      if test -z "$haveit"; then
+                        ltrpathdirs="$ltrpathdirs $dir"
+                      fi
+                    fi
+                    ;;
+                  -l*)
+                                        names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+                    ;;
+                  *.la)
+                                                                                names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+                    ;;
+                  *)
+                                        LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$dep"
+                    LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }$dep"
+                    ;;
+                esac
+              done
+            fi
+          else
+                                                            LIBMPFR="${LIBMPFR}${LIBMPFR:+ }-l$name"
+            LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }-l$name"
+          fi
+        fi
+      fi
+    done
+  done
+  if test "X$rpathdirs" != "X"; then
+    if test -n "$hardcode_libdir_separator"; then
+                        alldirs=
+      for found_dir in $rpathdirs; do
+        alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
+      done
+            acl_save_libdir="$libdir"
+      libdir="$alldirs"
+      eval flag=\"$hardcode_libdir_flag_spec\"
+      libdir="$acl_save_libdir"
+      LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$flag"
+    else
+            for found_dir in $rpathdirs; do
+        acl_save_libdir="$libdir"
+        libdir="$found_dir"
+        eval flag=\"$hardcode_libdir_flag_spec\"
+        libdir="$acl_save_libdir"
+        LIBMPFR="${LIBMPFR}${LIBMPFR:+ }$flag"
+      done
+    fi
+  fi
+  if test "X$ltrpathdirs" != "X"; then
+            for found_dir in $ltrpathdirs; do
+      LTLIBMPFR="${LTLIBMPFR}${LTLIBMPFR:+ }-R$found_dir"
+    done
+  fi
+
+
+        ac_save_CPPFLAGS="$CPPFLAGS"
+
+  for element in $INCMPFR; do
+    haveit=
+    for x in $CPPFLAGS; do
+
+  acl_save_prefix="$prefix"
+  prefix="$acl_final_prefix"
+  acl_save_exec_prefix="$exec_prefix"
+  exec_prefix="$acl_final_exec_prefix"
+  eval x=\"$x\"
+  exec_prefix="$acl_save_exec_prefix"
+  prefix="$acl_save_prefix"
+
+      if test "X$x" = "X$element"; then
+        haveit=yes
+        break
+      fi
+    done
+    if test -z "$haveit"; then
+      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+    fi
+  done
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmpfr" >&5
+$as_echo_n "checking for libmpfr... " >&6; }
+if test "${ac_cv_libmpfr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_save_LIBS="$LIBS"
+    LIBS="$LIBS $LIBMPFR"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <mpfr.h>
+int
+main ()
+{
+mpfr_exp_t exp; mpfr_t x;
+			 mpfr_frexp (&exp, x, x, MPFR_RNDN);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_libmpfr=yes
+else
+  ac_cv_libmpfr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LIBS="$ac_save_LIBS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libmpfr" >&5
+$as_echo "$ac_cv_libmpfr" >&6; }
+  if test "$ac_cv_libmpfr" = yes; then
+    HAVE_LIBMPFR=yes
+
+$as_echo "#define HAVE_LIBMPFR 1" >>confdefs.h
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libmpfr" >&5
+$as_echo_n "checking how to link with libmpfr... " >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBMPFR" >&5
+$as_echo "$LIBMPFR" >&6; }
+  else
+    HAVE_LIBMPFR=no
+            CPPFLAGS="$ac_save_CPPFLAGS"
+    LIBMPFR=
+    LTLIBMPFR=
+  fi
+
+
+
+
+
+
+  if test "$HAVE_LIBMPFR" != yes; then
+    if test "$with_mpfr" = yes; then
+      as_fn_error "MPFR is missing or unusable" "$LINENO" 5
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: MPFR is missing or unusable; some features may be unavailable." >&5
+$as_echo "$as_me: WARNING: MPFR is missing or unusable; some features may be unavailable." >&2;}
+    fi
+  fi
+fi
+
 # --------------------- #
 # Check for libpython.  #
 # --------------------- #

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-11-16 19:00 [RFC v2][2/2] Target FP: Make use of MPFR if available Ulrich Weigand
@ 2017-11-29  0:37 ` John Baldwin
  2017-11-29 17:55   ` Ulrich Weigand
  2017-12-10 15:10 ` Regression on i686 host: gdb.base/floatn.exp: " Jan Kratochvil
  2018-06-20  8:55 ` New FAIL gdb.base/float128.exp on ppc64le [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available] Jan Kratochvil
  2 siblings, 1 reply; 15+ messages in thread
From: John Baldwin @ 2017-11-29  0:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Ulrich Weigand

On Thursday, November 16, 2017 08:00:08 PM Ulrich Weigand wrote:
> [RFC v2][2/2] Target FP: Make use of MPFR if available
> 
> This second patch introduces mfpr_float_ops, an new implementation
> of target_float_ops.  This implements precise emulation of target
> floating-point formats using the MPFR library.  This is then used
> to perform operations on types that do not match any host type.
> 
> Note that use of MPFR is still not required.  The patch adds
> a configure option --with-mpfr similar to --with-expat.  If use of
> MPFR is disabled via the option or MPFR is not available, code will
> fall back to current behavior.  This means that operations on types
> that do not match any host type will be implemented on the host
> long double type instead.
> 
> A new test case verifies that we can correctly print the largest
> __float128 value now.

This might need a stricter configure check perhaps?  I'm getting the
following build failure compiling GDB on FreeBSD 11.x with mpfr-3.1.5
installed:

c++ -x c++ -std=gnu++11 -pipe -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable -Wno-absolute-value -Wno-parentheses-equality -Wno-unknown-warning-option -g -DLIBICONV_PLUG -g -fno-strict-aliasing   -I. -I../../gdb -I../../gdb/common -I../../gdb/config -DLOCALEDIR="\"/usr/local/share/locale\"" -DHAVE_CONFIG_H -I../../gdb/../include/opcode -I../../gdb/../opcodes/.. -I../../gdb/../readline/.. -I../../gdb/../zlib -I../bfd -I../../gdb/../bfd -I../../gdb/../include -I../libdecnumber -I../../gdb/../libdecnumber  -I../../gdb/gnulib/import -Ibuild-gnulib/import   -DTUI=1  -I/usr/local/include  -I/usr/local/include/python2.7 -I/usr/local/include/python2.7 -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wformat-nonliteral  `echo " -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-narrowing -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wformat-nonliteral " | sed "s/ -Wformat-nonliteral / -Wno-format-nonliteral /g"` \
        -c -o target-float.o -MT target-float.o -MMD -MP -MF ./.deps/target-float.Tpo ../../gdb/target-float.c
../../gdb/target-float.c:1567:10: error: use of undeclared identifier
      'mpfr_get_sj'; did you mean 'mpfr_get_si'?
  return mpfr_get_sj (tmp.val, MPFR_RNDZ);
         ^~~~~~~~~~~
         mpfr_get_si                                                            
/usr/local/include/mpfr.h:413:22: note: 'mpfr_get_si' declared here
__MPFR_DECLSPEC long mpfr_get_si _MPFR_PROTO ((mpfr_srcptr, mpfr_rnd_t));
                     ^
../../gdb/target-float.c:1578:3: error: use of undeclared identifier
      'mpfr_set_sj'; did you mean 'mpfr_set_si'?
  mpfr_set_sj (tmp.val, val, MPFR_RNDN);
  ^~~~~~~~~~~
  mpfr_set_si
/usr/local/include/mpfr.h:370:21: note: 'mpfr_set_si' declared here
__MPFR_DECLSPEC int mpfr_set_si _MPFR_PROTO ((mpfr_ptr, long, mpfr_rnd_t));
                    ^
../../gdb/target-float.c:1590:3: error: use of undeclared identifier
      'mpfr_set_uj'; did you mean 'mpfr_set_ui'?
  mpfr_set_uj (tmp.val, val, MPFR_RNDN);
  ^~~~~~~~~~~
  mpfr_set_ui
/usr/local/include/mpfr.h:372:3: note: 'mpfr_set_ui' declared here
  mpfr_set_ui _MPFR_PROTO ((mpfr_ptr, unsigned long, mpfr_rnd_t));
  ^
3 errors generated.
gmake[2]: *** [Makefile:2402: target-float.o] Error 1
gmake[2]: Leaving directory '/usr/home/john/work/git/gdb/obj/gdb'
gmake[1]: *** [Makefile:10100: all-gdb] Error 2
gmake[1]: Leaving directory '/usr/home/john/work/git/gdb/obj'
gmake: *** [Makefile:849: all] Error 2

Hmmm, it seems that mpfr.h depends on this conditional to decide if
intmax_t is available:

/* Check if <stdint.h> / <inttypes.h> is included or if the user
   explicitly wants intmax_t. Automatical detection is done by
   checking:
     - INTMAX_C and UINTMAX_C, but not if the compiler is a C++ one
       (as suggested by Patrick Pelissier) because the test does not
       work well in this case. See:
         https://sympa.inria.fr/sympa/arc/mpfr/2010-02/msg00025.html
       We do not check INTMAX_MAX and UINTMAX_MAX because under Solaris,
       these macros are always defined by <limits.h> (i.e. even when
       <stdint.h> and <inttypes.h> are not included).
     - _STDINT_H (defined by the glibc), _STDINT_H_ (defined under
       Mac OS X) and _STDINT (defined under MS Visual Studio), but
       this test may not work with all implementations.
       Portable software should not rely on these tests.
*/
#if (defined (INTMAX_C) && defined (UINTMAX_C) && !defined(__cplusplus)) || \
  defined (MPFR_USE_INTMAX_T) || \
  defined (_STDINT_H) || defined (_STDINT_H_) || defined (_STDINT)
# ifndef _MPFR_H_HAVE_INTMAX_T
# define _MPFR_H_HAVE_INTMAX_T 1

FreeBSD's stdint.h uses _SYS_STDINT_H_ as it's include guard for <stdint.h>,
so this check doesn't work.  Perhaps GDB's sources should just define
MPFR_USE_INTMAX_T explicitly after ensuring <stdint.h> is included?  That
would seem to be the most portable approach and I think is what the "Portable
software should not rely on these tests" implies.

target-float.c always includes <stdint.h> via "defs.h" ->
"common/common-defs.h", so just adding the #define should be sufficient.

Indeed, this does fix the build on FreeBSD:

diff --git a/gdb/target-float.c b/gdb/target-float.c
index 32237ec9d9..b40b6416c1 100644
--- a/gdb/target-float.c
+++ b/gdb/target-float.c
@@ -1147,6 +1147,8 @@ host_float_ops<T>::compare (const gdb_byte *x, const struct type *type_x,
 
 #ifdef HAVE_LIBMPFR
 
+#define MPFR_USE_INTMAX_T
+
 #include <mpfr.h>
 
 class mpfr_float_ops : public target_float_ops

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-11-29  0:37 ` John Baldwin
@ 2017-11-29 17:55   ` Ulrich Weigand
  2017-11-29 18:04     ` Pedro Alves
  2017-11-30  0:27     ` John Baldwin
  0 siblings, 2 replies; 15+ messages in thread
From: Ulrich Weigand @ 2017-11-29 17:55 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches

John Baldwin wrote:

> FreeBSD's stdint.h uses _SYS_STDINT_H_ as it's include guard for <stdint.h>,
> so this check doesn't work.  Perhaps GDB's sources should just define
> MPFR_USE_INTMAX_T explicitly after ensuring <stdint.h> is included?  That
> would seem to be the most portable approach and I think is what the
> "Portable software should not rely on these tests" implies.

I agree.  GDB now requires C++11, which always has intmax_t, so it should
be fine to simply always require this.

> target-float.c always includes <stdint.h> via "defs.h" ->
> "common/common-defs.h", so just adding the #define should be sufficient.
> 
> Indeed, this does fix the build on FreeBSD:
> 
> diff --git a/gdb/target-float.c b/gdb/target-float.c
> index 32237ec9d9..b40b6416c1 100644
> --- a/gdb/target-float.c
> +++ b/gdb/target-float.c
> @@ -1147,6 +1147,8 @@ host_float_ops<T>::compare (const gdb_byte *x, const
> struct type *type_x,
> 
>  #ifdef HAVE_LIBMPFR
> 
> +#define MPFR_USE_INTMAX_T
> +
>  #include <mpfr.h>
> 
>  class mpfr_float_ops : public target_float_ops

This looks good to me.  Can you check this in?

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-11-29 17:55   ` Ulrich Weigand
@ 2017-11-29 18:04     ` Pedro Alves
  2017-11-30  0:27     ` John Baldwin
  1 sibling, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2017-11-29 18:04 UTC (permalink / raw)
  To: Ulrich Weigand, John Baldwin; +Cc: gdb-patches

On 11/29/2017 05:55 PM, Ulrich Weigand wrote:
> John Baldwin wrote:
> 
>> FreeBSD's stdint.h uses _SYS_STDINT_H_ as it's include guard for <stdint.h>,
>> so this check doesn't work.  Perhaps GDB's sources should just define
>> MPFR_USE_INTMAX_T explicitly after ensuring <stdint.h> is included?  That
>> would seem to be the most portable approach and I think is what the
>> "Portable software should not rely on these tests" implies.
> 
> I agree.  GDB now requires C++11, which always has intmax_t, so it should
> be fine to simply always require this.

And even if a compiler isn't compliant for some reason, we'd
get a stdint.h replacement via gnulib that provides intmax_t.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-11-29 17:55   ` Ulrich Weigand
  2017-11-29 18:04     ` Pedro Alves
@ 2017-11-30  0:27     ` John Baldwin
  1 sibling, 0 replies; 15+ messages in thread
From: John Baldwin @ 2017-11-30  0:27 UTC (permalink / raw)
  To: gdb-patches; +Cc: Ulrich Weigand

On Wednesday, November 29, 2017 06:55:36 PM Ulrich Weigand wrote:
> John Baldwin wrote:
> > Indeed, this does fix the build on FreeBSD:
> > 
> > diff --git a/gdb/target-float.c b/gdb/target-float.c
> > index 32237ec9d9..b40b6416c1 100644
> > --- a/gdb/target-float.c
> > +++ b/gdb/target-float.c
> > @@ -1147,6 +1147,8 @@ host_float_ops<T>::compare (const gdb_byte *x, const
> > struct type *type_x,
> > 
> >  #ifdef HAVE_LIBMPFR
> > 
> > +#define MPFR_USE_INTMAX_T
> > +
> >  #include <mpfr.h>
> > 
> >  class mpfr_float_ops : public target_float_ops
> 
> This looks good to me.  Can you check this in?

Will do, thanks.

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Regression on i686 host: gdb.base/floatn.exp: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-11-16 19:00 [RFC v2][2/2] Target FP: Make use of MPFR if available Ulrich Weigand
  2017-11-29  0:37 ` John Baldwin
@ 2017-12-10 15:10 ` Jan Kratochvil
  2017-12-10 15:13   ` Jan Kratochvil
  2018-06-20  8:55 ` New FAIL gdb.base/float128.exp on ppc64le [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available] Jan Kratochvil
  2 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2017-12-10 15:10 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

Hi Ulrich,

2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Date:   Wed Nov 22 13:53:43 2017 +0100
    Target FP: Make use of MPFR if available

FAIL: gdb.base/floatn.exp: the original value of f128 is 3.375
FAIL: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'
FAIL: gdb.base/floatn.exp: the value of f128 is changed to 30.375
FAIL: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I

It is reproducible on Fedora Rawhide i686.  Not reproducible on Fedora Rawhide
x86_64 and not even on x86_64 -m32.  I haven't tried other OSes/versions.


Jan


 print f128^M
-$3 = 3.375^M
-(gdb) PASS: gdb.base/floatn.exp: the original value of f128 is 3.375
+$3 = 1.375^M
+(gdb) FAIL: gdb.base/floatn.exp: the original value of f128 is 3.375

 print f128=-3.375^M
-$8 = -3.375^M
-(gdb) PASS: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'
+$8 = -1.375^M
+(gdb) FAIL: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'

 print f128^M
-$13 = 30.375^M
-(gdb) PASS: gdb.base/floatn.exp: the value of f128 is changed to 30.375
+$13 = 6.375^M
+(gdb) FAIL: gdb.base/floatn.exp: the value of f128 is changed to 30.375

-$18 = 3.375 + 1 * I^M
-(gdb) PASS: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I
+$18 = 1.375 + 1 * I^M
+(gdb) FAIL: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Regression on i686 host: gdb.base/floatn.exp: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-12-10 15:10 ` Regression on i686 host: gdb.base/floatn.exp: " Jan Kratochvil
@ 2017-12-10 15:13   ` Jan Kratochvil
  2017-12-11 14:14     ` Ulrich Weigand
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2017-12-10 15:13 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

On Sun, 10 Dec 2017 16:09:56 +0100, Jan Kratochvil wrote:
> Hi Ulrich,
> 
> 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
> commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
> Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
> Date:   Wed Nov 22 13:53:43 2017 +0100
>     Target FP: Make use of MPFR if available
> 
> FAIL: gdb.base/floatn.exp: the original value of f128 is 3.375
> FAIL: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'
> FAIL: gdb.base/floatn.exp: the value of f128 is changed to 30.375
> FAIL: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I

I have seen now also there, that will be probably the same, I did not check
more:
	-PASS: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
	+FAIL: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
	-PASS: gdb.base/float128.exp: the value of f128 is changed to 20.375
	+FAIL: gdb.base/float128.exp: the value of f128 is changed to 20.375
	+FAIL: gdb.base/float128.exp: print large128


Jan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Regression on i686 host: gdb.base/floatn.exp: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-12-10 15:13   ` Jan Kratochvil
@ 2017-12-11 14:14     ` Ulrich Weigand
  2017-12-11 14:30       ` Ulrich Weigand
  0 siblings, 1 reply; 15+ messages in thread
From: Ulrich Weigand @ 2017-12-11 14:14 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

Jan Kratochvil wrote:
> On Sun, 10 Dec 2017 16:09:56 +0100, Jan Kratochvil wrote:
> > Hi Ulrich,
> > 
> > 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
> > commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
> > Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
> > Date:   Wed Nov 22 13:53:43 2017 +0100
> >     Target FP: Make use of MPFR if available
> > 
> > FAIL: gdb.base/floatn.exp: the original value of f128 is 3.375
> > FAIL: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'
> > FAIL: gdb.base/floatn.exp: the value of f128 is changed to 30.375
> > FAIL: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I
> 
> I have seen now also there, that will be probably the same, I did not check
> more:
> 	-PASS: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
> 	+FAIL: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
> 	-PASS: gdb.base/float128.exp: the value of f128 is changed to 20.375
> 	+FAIL: gdb.base/float128.exp: the value of f128 is changed to 20.375
> 	+FAIL: gdb.base/float128.exp: print large128

Hi Jan,

I was able to reproduce this problem by building GDB itself as a 32-bit binary.

I'm currently testing a fix ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Regression on i686 host: gdb.base/floatn.exp: [RFC v2][2/2] Target FP: Make use of MPFR if available
  2017-12-11 14:14     ` Ulrich Weigand
@ 2017-12-11 14:30       ` Ulrich Weigand
  0 siblings, 0 replies; 15+ messages in thread
From: Ulrich Weigand @ 2017-12-11 14:30 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Jan Kratochvil, gdb-patches

> Jan Kratochvil wrote:
> > On Sun, 10 Dec 2017 16:09:56 +0100, Jan Kratochvil wrote:
> > > Hi Ulrich,
> > > 
> > > 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
> > > commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
> > > Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
> > > Date:   Wed Nov 22 13:53:43 2017 +0100
> > >     Target FP: Make use of MPFR if available
> > > 
> > > FAIL: gdb.base/floatn.exp: the original value of f128 is 3.375
> > > FAIL: gdb.base/floatn.exp: try to change f128 to -3.375 with 'print f128=-3.375'
> > > FAIL: gdb.base/floatn.exp: the value of f128 is changed to 30.375
> > > FAIL: gdb.base/floatn.exp: the original value of c128 is 3.375 + 1 * I
> > 
> > I have seen now also there, that will be probably the same, I did not check
> > more:
> > 	-PASS: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
> > 	+FAIL: gdb.base/float128.exp: try to change f128 to -2.375 with 'print f128=-2.375l'
> > 	-PASS: gdb.base/float128.exp: the value of f128 is changed to 20.375
> > 	+FAIL: gdb.base/float128.exp: the value of f128 is changed to 20.375
> > 	+FAIL: gdb.base/float128.exp: print large128
> 
> Hi Jan,
> 
> I was able to reproduce this problem by building GDB itself as a 32-bit binary.
> 
> I'm currently testing a fix ...

Fix pushed as f2f9e7ecc1f02bfe5da83c38cf356ea96d428c6d.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2017-11-16 19:00 [RFC v2][2/2] Target FP: Make use of MPFR if available Ulrich Weigand
  2017-11-29  0:37 ` John Baldwin
  2017-12-10 15:10 ` Regression on i686 host: gdb.base/floatn.exp: " Jan Kratochvil
@ 2018-06-20  8:55 ` Jan Kratochvil
  2018-06-20 12:33   ` Ulrich Weigand
  2 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2018-06-20  8:55 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

On Thu, 16 Nov 2017 20:00:08 +0100, Ulrich Weigand wrote:
> [RFC v2][2/2] Target FP: Make use of MPFR if available

2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Date:   Wed Nov 22 13:53:43 2017 +0100
    Target FP: Make use of MPFR if available

FAIL: gcc-7.3.1-5.fc27.ppc64le
FAIL: gcc-8.1.1-1.fc28.ppc64le
160d1b3d74593bf42155da24569f54a6e7140f65 gdb trunk

On ppc64le:
gdb.base/float128.exp
__float128 large128 = 1.18973149535723176508575932662800702e+4932q;
(gdb) p large128
$3 = inf
(gdb) FAIL: gdb.base/float128.exp: print large128

But this is a new test by this patch, I guess it needs some ABI options
gdb.arch/ppc-longdouble.exp is using as that one PASSes on ppc64le in all
cases.


Jan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2018-06-20  8:55 ` New FAIL gdb.base/float128.exp on ppc64le [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available] Jan Kratochvil
@ 2018-06-20 12:33   ` Ulrich Weigand
  2018-06-20 12:50     ` Jan Kratochvil
  0 siblings, 1 reply; 15+ messages in thread
From: Ulrich Weigand @ 2018-06-20 12:33 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

Jan Kratochvil wrote:
> On Thu, 16 Nov 2017 20:00:08 +0100, Ulrich Weigand wrote:
> > [RFC v2][2/2] Target FP: Make use of MPFR if available
> 
> 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a is the first bad commit
> commit 2400729ecfd2c7be8b18aeaa822fef5a4b503f8a
> Author: Ulrich Weigand <ulrich.weigand@de.ibm.com>
> Date:   Wed Nov 22 13:53:43 2017 +0100
>     Target FP: Make use of MPFR if available
> 
> FAIL: gcc-7.3.1-5.fc27.ppc64le
> FAIL: gcc-8.1.1-1.fc28.ppc64le
> 160d1b3d74593bf42155da24569f54a6e7140f65 gdb trunk
> 
> On ppc64le:
> gdb.base/float128.exp
> __float128 large128 = 1.18973149535723176508575932662800702e+4932q;
> (gdb) p large128
> $3 = inf
> (gdb) FAIL: gdb.base/float128.exp: print large128
> 
> But this is a new test by this patch, I guess it needs some ABI options
> gdb.arch/ppc-longdouble.exp is using as that one PASSes on ppc64le in all
> cases.

This shouldn't need any ABI options, since the test case explicitly uses
the __float128 type, which doesn't depend on ABI options (except for
-mfloat128, which the test case does pass).

A result of "inf" instead of the large number is exactly the problem that
is fixed by using MPFR.  So I'm wondering: is the GDB that shows the FAIL
actually built against MPFR?  If at build time MPFR was not detected,
then this failure is exactly what you'd expect ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2018-06-20 12:33   ` Ulrich Weigand
@ 2018-06-20 12:50     ` Jan Kratochvil
  2018-06-20 13:39       ` Ulrich Weigand
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2018-06-20 12:50 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches, Sergio Durigan Junior

On Wed, 20 Jun 2018 14:33:30 +0200, Ulrich Weigand wrote:
> A result of "inf" instead of the large number is exactly the problem that
> is fixed by using MPFR.  So I'm wondering: is the GDB that shows the FAIL
> actually built against MPFR?  If at build time MPFR was not detected,
> then this failure is exactly what you'd expect ...

Thanks for the heads up, our GDB build was really missing this dependency.

Still maybe the testcase should contain such explanation of the FAIL.
Moreover maybe it could be an XFAIL.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2018-06-20 12:50     ` Jan Kratochvil
@ 2018-06-20 13:39       ` Ulrich Weigand
  2018-06-20 13:47         ` Jan Kratochvil
  0 siblings, 1 reply; 15+ messages in thread
From: Ulrich Weigand @ 2018-06-20 13:39 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, Sergio Durigan Junior

Jan Kratochvil wrote:
> On Wed, 20 Jun 2018 14:33:30 +0200, Ulrich Weigand wrote:
> > A result of "inf" instead of the large number is exactly the problem that
> > is fixed by using MPFR.  So I'm wondering: is the GDB that shows the FAIL
> > actually built against MPFR?  If at build time MPFR was not detected,
> > then this failure is exactly what you'd expect ...
> 
> Thanks for the heads up, our GDB build was really missing this dependency.

Ah good, that explains it.
 
> Still maybe the testcase should contain such explanation of the FAIL.

Agreed.  The attached patch adds a comment, and also updates the FAIL
message to indicate possible lack of MPFR support as reason.  Does
this look good to you?

> Moreover maybe it could be an XFAIL.

I guess ...  On the other hand, it does indicate a real bug in GDB;
if it had been an XFAIL, you probably wouldn't have noticed missing
MPFR support in your build now.

Bye,
Ulrich

testsuite/ChangeLog:

	* gdb.base/float128.exp: Add comment and improved fail message
	to the failure case of "print large128" test.

diff --git a/gdb/testsuite/gdb.base/float128.exp b/gdb/testsuite/gdb.base/float128.exp
index 4c322b8ab3..26cabac776 100644
--- a/gdb/testsuite/gdb.base/float128.exp
+++ b/gdb/testsuite/gdb.base/float128.exp
@@ -75,5 +75,19 @@ gdb_test "print ld" ".* = 10\\.375.*" "the value of ld is changed to 10.375"
 gdb_test "print f128" ".* = 20\\.375.*" "the value of f128 is changed to 20.375"
 
 # Test that we can correctly handle the largest IEEE-128 value
-gdb_test "print large128" ".* = 1\\.18973149535723176508575932662800702e\\+4932" "print large128"
+# Note: If we get "inf" instead of the correct result, we may have run into
+# an internal overflow.  This typically happens on host platforms without
+# native IEEE-128 support where GDB was built without MPFR support.
+set test "print large128"
+gdb_test_multiple "print large128" "$test" {
+    -re ".* = 1\\.18973149535723176508575932662800702e\\+4932.*$gdb_prompt $" {
+	pass "$test"
+    }
+    -re ".* = inf.*$gdb_prompt $" {
+	fail "$test (GDB may be missing MPFR support!)"
+    }
+    -re ".*$gdb_prompt $" {
+	fail "$test"
+    }
+}
 

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2018-06-20 13:39       ` Ulrich Weigand
@ 2018-06-20 13:47         ` Jan Kratochvil
  2018-06-20 14:28           ` Ulrich Weigand
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Kratochvil @ 2018-06-20 13:47 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches, Sergio Durigan Junior

On Wed, 20 Jun 2018 15:39:05 +0200, Ulrich Weigand wrote:
> Jan Kratochvil wrote:
> > Still maybe the testcase should contain such explanation of the FAIL.
> 
> Agreed.  The attached patch adds a comment, and also updates the FAIL
> message to indicate possible lack of MPFR support as reason.  Does
> this look good to you?

Yes, thanks.


Jan

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: New FAIL gdb.base/float128.exp on ppc64le  [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available]
  2018-06-20 13:47         ` Jan Kratochvil
@ 2018-06-20 14:28           ` Ulrich Weigand
  0 siblings, 0 replies; 15+ messages in thread
From: Ulrich Weigand @ 2018-06-20 14:28 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches, Sergio Durigan Junior

Jan Kratochvil wrote:
> On Wed, 20 Jun 2018 15:39:05 +0200, Ulrich Weigand wrote:
> > Jan Kratochvil wrote:
> > > Still maybe the testcase should contain such explanation of the FAIL.
> > 
> > Agreed.  The attached patch adds a comment, and also updates the FAIL
> > message to indicate possible lack of MPFR support as reason.  Does
> > this look good to you?
> 
> Yes, thanks.

OK, I've checked this in now.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-06-20 14:28 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-16 19:00 [RFC v2][2/2] Target FP: Make use of MPFR if available Ulrich Weigand
2017-11-29  0:37 ` John Baldwin
2017-11-29 17:55   ` Ulrich Weigand
2017-11-29 18:04     ` Pedro Alves
2017-11-30  0:27     ` John Baldwin
2017-12-10 15:10 ` Regression on i686 host: gdb.base/floatn.exp: " Jan Kratochvil
2017-12-10 15:13   ` Jan Kratochvil
2017-12-11 14:14     ` Ulrich Weigand
2017-12-11 14:30       ` Ulrich Weigand
2018-06-20  8:55 ` New FAIL gdb.base/float128.exp on ppc64le [Re: [RFC v2][2/2] Target FP: Make use of MPFR if available] Jan Kratochvil
2018-06-20 12:33   ` Ulrich Weigand
2018-06-20 12:50     ` Jan Kratochvil
2018-06-20 13:39       ` Ulrich Weigand
2018-06-20 13:47         ` Jan Kratochvil
2018-06-20 14:28           ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).