diff mbox

[RFC,19/19] Target FP: Implement binary FP operations via MPFR

Message ID 20170905182205.975B6D8086F@oc3748833570.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Sept. 5, 2017, 6:22 p.m. UTC
[RFC][19/19] Target FP: Implement binary FP operations via MPFR

Up until now, all new code in target-float.c still uses DOUBLEST to
implement binary floating-point operations.  This patch now finally
changes this to use MPFR instead.

At this point, 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 behaviour (implement binary FP via DOUBLEST).

If MPFR is available, target-float.c is changed to *not* define
DOUBLEST.  All floatformat_... binary helpers are reimplemented
in terms of MPFR operations instead of using host DOUBLEST.

In order to convert between target FP format and MPFR, two new
routines are implemented:
 - floatformat_to_mpfr
 - floatformat_from_mpfr
These use the same basic algorithms as the existing
floatformat_to/from_doublest, except they work on mpfr_t opjects.

All other floatformat_... binary helpers then simply use these
two conversion routines together with standard MPFR routines
to implement the binary FP operations.

Bye,
Ulrich


ChangeLog:

	* target-float.c [HAVE_LIBMPFR]: Include <mpfr.h>.
	[HAVE_LIBMPFR] Do not include <math.h>.
	(DOUBLEST): Only provide if !HAVE_LIBMPFR.
	[HAVE_LIBMPFR] (floatformat_to_mpfr): New function.
	[HAVE_LIBMPFR] (floatformat_from_mpfr): Likewise.
        (host_float_format): Only provide if !HAVE_LIBMPFR.
	(host_double_format, host_long_double_format): Likewise.
        (floatformat_to_doublest, floatformat_from_doublest): Likewise.
	(floatformat_to_string): Implement using MPFR if HAVE_LIBMPFR.
	(floatformat_from_string): Likewise.
	(floatformat_to_longest): Likewise.
	(floatformat_from_longest, floatformat_from_ulongest): Likewise.
	(floatformat_to_host_double): Likewise.
	(floatformat_from_host_double): Likewise.
	(floatformat_convert): Likewise.
	(floatformat_binop, floatformat_compare): Likewise.

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

testsuite/ChangeLog:

	* gdb.arch/vsx-regs.exp: Update register content checks.
diff mbox

Patch

Index: binutils-gdb/gdb/target-float.c
===================================================================
--- binutils-gdb.orig/gdb/target-float.c
+++ binutils-gdb/gdb/target-float.c
@@ -25,6 +25,9 @@ 
 
 /* Helper routines operating on binary floating-point data.  */
 
+#ifdef HAVE_LIBMPFR
+#include <mpfr.h>
+#else
 #include <math.h>
 
 #if (defined HAVE_LONG_DOUBLE && defined PRINTF_HAS_LONG_DOUBLE \
@@ -38,6 +41,7 @@  typedef double DOUBLEST;
 # undef PRINTF_HAS_LONG_DOUBLE
 # undef SCANF_HAS_LONG_DOUBLE
 #endif
+#endif
 
 /* Different kinds of floatformat numbers recognized by
    floatformat_classify.  To avoid portability issues, we use local
@@ -447,6 +451,282 @@  floatformat_mantissa (const struct float
   return res;
 }
 
+#ifdef HAVE_LIBMPFR
+
+/* Convert TO/FROM target floating-point format to mpfr_t.  */
+
+static void
+floatformat_to_mpfr (const struct floatformat *fmt,
+		     const gdb_byte *orig_from, mpfr_ptr to)
+{
+  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, floatformat_is_negative (fmt, from) ? -1 : 1);
+      return;
+    }
+  if (kind == float_nan)
+    {
+      mpfr_set_nan (to);
+      return;
+    }
+
+  order = floatformat_normalize_byteorder (fmt, from, newfrom);
+
+  if (order != fmt->byteorder)
+    from = newfrom;
+
+  if (fmt->split_half)
+    {
+      mpfr_t top, bot;
+      mpfr_inits2 (floatformat_precision (fmt->split_half), top, bot, nullptr);
+
+      floatformat_to_mpfr (fmt->split_half, from, top);
+      /* Preserve the sign of 0, which is the sign of the top half.  */
+      if (mpfr_zero_p (top))
+	{
+	  mpfr_set (to, top, MPFR_RNDN);
+	  return;
+	}
+      floatformat_to_mpfr (fmt->split_half,
+			   from + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2,
+			   bot);
+      mpfr_add (to, top, bot, MPFR_RNDN);
+      mpfr_clears (top, bot, nullptr);
+      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, 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, 1, exponent, MPFR_RNDN);
+      else
+	exponent++;
+    }
+
+  mpfr_t tmp;
+  mpfr_init2 (tmp, mpfr_get_prec (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, mant, MPFR_RNDN);
+      mpfr_mul_2si (tmp, tmp, exponent - mant_bits, MPFR_RNDN);
+      mpfr_add (to, to, tmp, MPFR_RNDN);
+      exponent -= mant_bits;
+      mant_off += mant_bits;
+      mant_bits_left -= mant_bits;
+    }
+
+  mpfr_clear (tmp);
+
+  /* Negate it if negative.  */
+  if (get_field (from, order, fmt->totalsize, fmt->sign_start, 1))
+    mpfr_neg (to, to, MPFR_RNDN);
+}
+
+static void
+floatformat_from_mpfr (const struct floatformat *fmt,
+		       mpfr_srcptr from, gdb_byte *orig_to)
+{
+  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)
+    {
+      mpfr_t top, bot;
+      mpfr_inits2 (floatformat_precision (fmt->split_half), top, bot, nullptr);
+
+      mpfr_set (top, from, MPFR_RNDN);
+      /* If the rounded top half is Inf, the bottom must be 0 not NaN
+	 or Inf.  */
+      if (mpfr_inf_p (top))
+	mpfr_set_zero (bot, 0);
+      else
+	mpfr_sub (bot, from, top, MPFR_RNDN);
+
+      floatformat_from_mpfr (fmt->split_half, top, to);
+      floatformat_from_mpfr (fmt->split_half, bot,
+			     to + fmt->totalsize / FLOATFORMAT_CHAR_BIT / 2);
+
+      mpfr_clears (top, bot, nullptr);
+      return;
+    }
+
+  if (mpfr_zero_p (from))
+    return;			/* Result is zero */
+
+  mpfr_t tmp;
+  mpfr_init2 (tmp, mpfr_get_prec (from));
+  mpfr_set (tmp, from, MPFR_RNDN);
+
+  if (mpfr_nan_p (tmp))	/* 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) < 0)
+    {
+      put_field (to, order, fmt->totalsize, fmt->sign_start, 1, 1);
+      mpfr_neg (tmp, tmp, MPFR_RNDN);
+    }
+
+  if (mpfr_inf_p (tmp))		/* 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, tmp, 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, tmp, 32, MPFR_RNDN);
+      mant_long = mpfr_get_ui (tmp, MPFR_RNDZ) & 0xffffffffL;
+      mpfr_sub_ui (tmp, tmp, 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);
+
+  mpfr_clear (tmp);
+}
+
+#else
+
 /* Convert TO/FROM target to the hosts DOUBLEST floating-point format.
 
    If the host and target formats agree, we just copy the raw data
@@ -790,6 +1070,8 @@  floatformat_from_doublest (const struct
     floatformat_normalize_byteorder (fmt, newto, to);
 }
 
+#endif
+
 /* Convert the byte-stream ADDR, interpreted as floating-point format FMT,
    to a string, optionally using the print format FORMAT.  */
 static std::string
@@ -852,6 +1134,24 @@  floatformat_to_string (const struct floa
       host_format = std::string (format, len);
     }
 
+#ifdef HAVE_LIBMPFR
+  /* Add the length modifier and conversion character appropriate for
+     handling the mpfr_t type.  */
+  host_format += 'R';
+  host_format += conversion;
+
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+
+  floatformat_to_mpfr (fmt, in, tmp);
+
+  int size = mpfr_snprintf (NULL, 0, host_format.c_str (), tmp);
+  std::string str (size, '\0');
+  mpfr_sprintf (&str[0], host_format.c_str (), tmp);
+
+  mpfr_clear (tmp);
+  return str;
+#else
   /* Add the length modifier and conversion character appropriate for
      handling the host DOUBLEST type.  */
 #ifdef HAVE_LONG_DOUBLE
@@ -862,6 +1162,7 @@  floatformat_to_string (const struct floa
   DOUBLEST doub;
   floatformat_to_doublest (fmt, in, &doub);
   return string_printf (host_format.c_str (), doub);
+#endif
 }
 
 /* Parse string STRING into a target floating-number of format FMT and
@@ -870,6 +1171,24 @@  static bool
 floatformat_from_string (const struct floatformat *fmt, gdb_byte *out,
 			 std::string in)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+
+  char *endptr;
+  mpfr_strtofr (tmp, in.c_str (), &endptr, 0, MPFR_RNDN);
+
+  /* We only accept the whole string.  */
+  if (*endptr)
+    {
+      mpfr_clear (tmp);
+      return false;
+    }
+
+  floatformat_from_mpfr (fmt, tmp, out);
+  mpfr_clear (tmp);
+  return true;
+#else
   DOUBLEST doub;
   int n, num;
 #ifdef HAVE_LONG_DOUBLE
@@ -891,6 +1210,7 @@  floatformat_from_string (const struct fl
 
   floatformat_from_doublest (fmt, &doub, out);
   return true;
+#endif
 }
 
 /* Convert the byte-stream ADDR, interpreted as floating-point format FMT,
@@ -898,9 +1218,18 @@  floatformat_from_string (const struct fl
 static LONGEST
 floatformat_to_longest (const struct floatformat *fmt, const gdb_byte *addr)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+  floatformat_to_mpfr (fmt, addr, tmp);
+  LONGEST val = mpfr_get_sj (tmp, MPFR_RNDZ);
+  mpfr_clear (tmp);
+  return val;
+#else
   DOUBLEST d;
   floatformat_to_doublest (fmt, addr, &d);
   return (LONGEST) d;
+#endif
 }
 
 /* Convert signed integer VAL to a target floating-number of format FMT
@@ -909,8 +1238,16 @@  static void
 floatformat_from_longest (const struct floatformat *fmt, gdb_byte *addr,
 			  LONGEST val)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+  mpfr_set_sj (tmp, val, MPFR_RNDN);
+  floatformat_from_mpfr (fmt, tmp, addr);
+  mpfr_clear (tmp);
+#else
   DOUBLEST d = (DOUBLEST) val;
   floatformat_from_doublest (fmt, &d, addr);
+#endif
 }
 
 /* Convert unsigned integer VAL to a target floating-number of format FMT
@@ -919,8 +1256,16 @@  static void
 floatformat_from_ulongest (const struct floatformat *fmt, gdb_byte *addr,
 			   ULONGEST val)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+  mpfr_set_uj (tmp, val, MPFR_RNDN);
+  floatformat_from_mpfr (fmt, tmp, addr);
+  mpfr_clear (tmp);
+#else
   DOUBLEST d = (DOUBLEST) val;
   floatformat_from_doublest (fmt, &d, addr);
+#endif
 }
 
 /* Convert the byte-stream ADDR, interpreted as floating-point format FMT,
@@ -929,9 +1274,18 @@  static double
 floatformat_to_host_double (const struct floatformat *fmt,
 			    const gdb_byte *addr)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+  floatformat_to_mpfr (fmt, addr, tmp);
+  LONGEST val = mpfr_get_d (tmp, MPFR_RNDN);
+  mpfr_clear (tmp);
+  return val;
+#else
   DOUBLEST d;
   floatformat_to_doublest (fmt, addr, &d);
   return (double) d;
+#endif
 }
 
 /* Convert floating-point value VAL in the host "double" format to a target
@@ -940,8 +1294,16 @@  static void
 floatformat_from_host_double (const struct floatformat *fmt, gdb_byte *addr,
 			      double val)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t tmp;
+  mpfr_init2 (tmp, floatformat_precision (fmt));
+  mpfr_set_d (tmp, val, MPFR_RNDN);
+  floatformat_from_mpfr (fmt, tmp, addr);
+  mpfr_clear (tmp);
+#else
   DOUBLEST d = (DOUBLEST) val;
   floatformat_from_doublest (fmt, &d, addr);
+#endif
 }
 
 /* Convert a floating-point number of format FROM_FMT from the target
@@ -958,6 +1320,18 @@  floatformat_convert (const gdb_byte *fro
     }
   else
     {
+#ifdef HAVE_LIBMPFR
+      mpfr_t from_tmp, to_tmp;
+      mpfr_init2 (from_tmp, floatformat_precision (from_fmt));
+      mpfr_init2 (to_tmp, floatformat_precision (to_fmt));
+
+      floatformat_to_mpfr (from_fmt, from, from_tmp);
+      mpfr_set (to_tmp, from_tmp, MPFR_RNDN);
+      floatformat_from_mpfr (to_fmt, to_tmp, to);
+
+      mpfr_clear (from_tmp);
+      mpfr_clear (to_tmp);
+#else
       /* The floating-point formats don't match.  The best we can do
 	 (apart from simulating the target FPU) is converting to the
 	 widest floating-point type supported by the host, and then
@@ -966,6 +1340,7 @@  floatformat_convert (const gdb_byte *fro
 
       floatformat_to_doublest (from_fmt, from, &d);
       floatformat_from_doublest (to_fmt, &d, to);
+#endif
     }
 }
 
@@ -979,6 +1354,56 @@  floatformat_binop (enum exp_opcode op,
 		   const struct floatformat *fmt_y, const gdb_byte *y,
 		   const struct floatformat *fmt_result, gdb_byte *result)
 {
+#ifdef HAVE_LIBMPFR
+  mpfr_t x_tmp, y_tmp, tmp;
+  mpfr_init2 (x_tmp, floatformat_precision (fmt_x));
+  mpfr_init2 (y_tmp, floatformat_precision (fmt_y));
+  mpfr_init2 (tmp, floatformat_precision (fmt_result));
+
+  floatformat_to_mpfr (fmt_x, x, x_tmp);
+  floatformat_to_mpfr (fmt_y, y, y_tmp);
+
+  switch (op)
+    {
+      case BINOP_ADD:
+	mpfr_add (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_SUB:
+	mpfr_sub (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_MUL:
+	mpfr_mul (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_DIV:
+	mpfr_div (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_EXP:
+	mpfr_pow (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_MIN:
+	mpfr_min (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      case BINOP_MAX:
+	mpfr_max (tmp, x_tmp, y_tmp, MPFR_RNDN);
+	break;
+
+      default:
+	error (_("Integer-only operation on floating point number."));
+	break;
+    }
+
+  floatformat_from_mpfr (fmt_result, tmp, result);
+
+  mpfr_clear (x_tmp);
+  mpfr_clear (y_tmp);
+  mpfr_clear (tmp);
+#else
   DOUBLEST v1, v2, v = 0;
 
   floatformat_to_doublest (fmt_x, x, &v1);
@@ -1024,6 +1449,7 @@  floatformat_binop (enum exp_opcode op,
     }
 
   floatformat_from_doublest (fmt_result, &v, result);
+#endif
 }
 
 /* Compare the two target byte streams X and Y, interpreted as floating-point
@@ -1033,6 +1459,28 @@  static int
 floatformat_compare (const struct floatformat *fmt_x, const gdb_byte *x,
 		     const struct floatformat *fmt_y, const gdb_byte *y)
 {
+#ifdef HAVE_LIBMPFR
+  int result;
+
+  mpfr_t x_tmp, y_tmp;
+  mpfr_init2 (x_tmp, floatformat_precision (fmt_x));
+  mpfr_init2 (y_tmp, floatformat_precision (fmt_y));
+
+  floatformat_to_mpfr (fmt_x, x, x_tmp);
+  floatformat_to_mpfr (fmt_y, y, y_tmp);
+
+  if (mpfr_equal_p (x_tmp, y_tmp))
+    result = 0;
+  else if (mpfr_less_p (x_tmp, y_tmp))
+    result = -1;
+  else
+    result = 1;
+
+  mpfr_clear (x_tmp);
+  mpfr_clear (y_tmp);
+
+  return result;
+#else
   DOUBLEST v1, v2;
 
   floatformat_to_doublest (fmt_x, x, &v1);
@@ -1043,6 +1491,7 @@  floatformat_compare (const struct floatf
   if (v1 < v2)
     return -1;
   return 1;
+#endif
 }
 
 
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)
@@ -692,7 +695,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
@@ -252,6 +252,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
@@ -691,6 +691,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
@@ -837,6 +840,8 @@  with_system_readline
 with_jit_reader_dir
 with_expat
 with_libexpat_prefix
+with_mpfr
+with_libmpfr_prefix
 with_python
 with_guile
 enable_libmcheck
@@ -1559,6 +1564,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
@@ -9691,6 +9699,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.  #
 # --------------------- #
Index: binutils-gdb/gdb/testsuite/gdb.arch/vsx-regs.exp
===================================================================
--- binutils-gdb.orig/gdb/testsuite/gdb.arch/vsx-regs.exp
+++ binutils-gdb/gdb/testsuite/gdb.arch/vsx-regs.exp
@@ -59,31 +59,34 @@  if ![runto_main] then {
 set endianness [get_endianness]
 
 # Data sets used throughout the test
+# The floating-point value 1.3 is supposed to be encoded as 0x3ff4cccccccccccd,
+# and we get this with MPFR.  Without MPFR we get instead 0x3ff4cccccccccccc.
+# Since we don't know here whether we do or do not have MPFR, accept both.
 
 if {$endianness == "big"} {
-    set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x1, 0x0., v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.."
+    set vector_register1 ".uint128 = 0x3ff4ccccccccccc\[cd\]0000000000000000, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x3ff4cccc, 0xccccccc\[cd\], 0x0, 0x0., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xccc\[cd\], 0x0, 0x0, 0x0, 0x0., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc\[cd\], 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0.."
 
-    set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x1, 0xf99999a0, 0x0, 0x0., v4_int32 = .0x3ff4cccc, 0xcccccccc, 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xcccc, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
+    set vector_register1_vr ".uint128 = 0x3ff4ccccccccccc\[cd\]0000000100000001, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x3ff4cccc, 0xccccccc\[cd\], 0x1, 0x1., v8_int16 = .0x3ff4, 0xcccc, 0xcccc, 0xccc\[cd\], 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x3f, 0xf4, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xc\[cd\], 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
 
-    set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
+    set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
 
-    set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
+    set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef., v16_int8 = .0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef.."
 
-    set vector_register3 ".uint128 = 0x1000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
+    set vector_register3 ".uint128 = 0x1000000010000000100000001, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
 
-    set vector_register3_vr ".uint128 = 0x1000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
+    set vector_register3_vr ".uint128 = 0x1000000010000000100000001, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1., v16_int8 = .0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1.."
 } else {
-    set vector_register1 ".uint128 = 0x3ff4cccccccccccc0000000000000000, v2_double = .0x0, 0x1., v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x0, 0x0, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x0, 0x0, 0x0, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
+    set vector_register1 ".uint128 = 0x3ff4ccccccccccc\[cd\]0000000000000000, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x0, 0x0, 0xccccccc\[cd\], 0x3ff4cccc., v8_int16 = .0x0, 0x0, 0x0, 0x0, 0xccc\[cd\], 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc\[cd\], 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
 
-    set vector_register1_vr ".uint128 = 0x3ff4cccccccccccc0000000100000001, v4_float = .0x0, 0x0, 0xf99999a0, 0x1., v4_int32 = .0x1, 0x1, 0xcccccccc, 0x3ff4cccc., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0xcccc, 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
+    set vector_register1_vr ".uint128 = 0x3ff4ccccccccccc\[cd\]0000000100000001, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x1, 0x1, 0xccccccc\[cd\], 0x3ff4cccc., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0xccc\[cd\], 0xcccc, 0xcccc, 0x3ff4., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xc\[cd\], 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf4, 0x3f.."
 
-    set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x1, 0x1., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
+    set vector_register2 "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
 
-    set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
+    set vector_register2_vr "uint128 = 0xdeadbeefdeadbeefdeadbeefdeadbeef, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef., v8_int16 = .0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead, 0xbeef, 0xdead., v16_int8 = .0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde.."
 
-    set vector_register3 ".uint128 = 0x1000000010000000100000001, v2_double = .0x0, 0x0., v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
+    set vector_register3 ".uint128 = 0x1000000010000000100000001, v2_double = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
 
-    set vector_register3_vr ".uint128 = 0x1000000010000000100000001, v4_float = .0x0, 0x0, 0x0, 0x0., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
+    set vector_register3_vr ".uint128 = 0x1000000010000000100000001, v4_float = .0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*, 0x\[0-9a-f\]*., v4_int32 = .0x1, 0x1, 0x1, 0x1., v8_int16 = .0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0., v16_int8 = .0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0.."
 }
 
 set float_register ".raw 0xdeadbeefdeadbeef."