public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFA 0/5] improve printing of 128 bit ints
@ 2017-06-02 19:36 Tom Tromey
  2017-06-02 19:37 ` [RFA 3/5] Simplify print_scalar_formatted Tom Tromey
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:36 UTC (permalink / raw)
  To: gdb-patches

I wanted to improve 128-bit integer support, primarily for Rust,
though I see in Bugzilla that I reported this bug at least twice for C
as well.

Full 128 bit integer support has two main aspects: printing and
arithmetic (including parser support).  This series cleans up
printing, (bug 16225); leaving arithmetic for a future bug (bug
20991).

Previous printing was implemented, but always zero-padded and did not
correctly handle signed values.  This series fixes that and removes
some redundant code as well.

Regtested on the buildbot.

Tom

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

* [RFA 2/5] Let print_decimal_chars handle signed values
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
                   ` (3 preceding siblings ...)
  2017-06-02 19:37 ` [RFA 1/5] Don't always zero pad in print_*_chars Tom Tromey
@ 2017-06-02 19:37 ` Tom Tromey
  2017-06-05 17:22   ` Pedro Alves
  2017-06-05 17:35 ` [RFA 0/5] improve printing of 128 bit ints Pedro Alves
  2017-06-08 14:32 ` Tom Tromey
  6 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes print_decimal_chars to handle signed values.

gdb/ChangeLog
2017-06-02  Tom Tromey  <tom@tromey.com>

	PR exp/16225:
	* valprint.h (print_decimal_chars): Update.
	* valprint.c (maybe_negate_by_bytes): New function.
	(print_decimal_chars): Add "is_signed" argument.
	* printcmd.c (print_scalar_formatted): Update.
---
 gdb/ChangeLog  |  8 ++++++++
 gdb/printcmd.c |  3 ++-
 gdb/valprint.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 gdb/valprint.h |  2 +-
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bc2ac04..a529694 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,6 +1,14 @@
 2017-06-02  Tom Tromey  <tom@tromey.com>
 
 	PR exp/16225:
+	* valprint.h (print_decimal_chars): Update.
+	* valprint.c (maybe_negate_by_bytes): New function.
+	(print_decimal_chars): Add "is_signed" argument.
+	* printcmd.c (print_scalar_formatted): Update.
+
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
+	PR exp/16225:
 	* valprint.h (print_binary_chars, print_hex_chars): Update.
 	* valprint.c (val_print_type_code_int): Update.
 	(print_binary_chars): Add "zero_pad" argument.
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 66395d5..84f41f5 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -374,7 +374,8 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 	  return;
 	case 'u':
 	case 'd':
-	  print_decimal_chars (stream, valaddr, len, byte_order);
+	  print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
+			       byte_order);
 	  return;
 	case 't':
 	  print_binary_chars (stream, valaddr, len, byte_order, size > 0);
diff --git a/gdb/valprint.c b/gdb/valprint.c
index aa34b68..fcd74f1 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1763,12 +1763,58 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 
 }
 
+/* Possibly negate the integer represented by BYTES.  It contains LEN
+   bytes in the specified byte order.  If the integer is negative,
+   copy it into OUT_VEC, negate it, and return true.  Otherwise, do
+   nothing and return false.  */
+
+static bool
+maybe_negate_by_bytes (const gdb_byte *bytes, unsigned len,
+		       enum bfd_endian byte_order,
+		       std::vector<gdb_byte> *out_vec)
+{
+  gdb_byte sign_byte;
+  if (byte_order == BFD_ENDIAN_BIG)
+    sign_byte = bytes[0];
+  else
+    sign_byte = bytes[len - 1];
+  if ((sign_byte & 0x80) == 0)
+    return false;
+
+  out_vec->reserve (len);
+
+  /* Compute -x == 1 + ~x.  */
+  if (byte_order == BFD_ENDIAN_LITTLE)
+    {
+      unsigned carry = 1;
+      for (unsigned i = 0; i < len; ++i)
+	{
+	  unsigned tem = (0xff & ~bytes[i]) + carry;
+	  (*out_vec)[i] = tem & 0xff;
+	  carry = tem / 256;
+	}
+    }
+  else
+    {
+      unsigned carry = 1;
+      for (unsigned i = len; i > 0; --i)
+	{
+	  unsigned tem = (0xff & ~bytes[i - 1]) + carry;
+	  (*out_vec)[i - 1] = tem & 0xff;
+	  carry = tem / 256;
+	}
+    }
+
+  return true;
+}
+
 /* VALADDR points to an integer of LEN bytes.
    Print it in decimal on stream or format it in buf.  */
 
 void
 print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
-		     unsigned len, enum bfd_endian byte_order)
+		     unsigned len, bool is_signed,
+		     enum bfd_endian byte_order)
 {
 #define TEN             10
 #define CARRY_OUT(  x ) ((x) / TEN)	/* extend char to int */
@@ -1784,6 +1830,14 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
   int dummy;
   int flip;
 
+  std::vector<gdb_byte> negated_bytes;
+  if (is_signed
+      && maybe_negate_by_bytes (valaddr, len, byte_order, &negated_bytes))
+    {
+      fputs_filtered ("-", stream);
+      valaddr = negated_bytes.data ();
+    }
+
   /* Base-ten number is less than twice as many digits
      as the base 16 number, which is 2 digits per byte.  */
 
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 8bfad21..f71d4ab 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -138,7 +138,7 @@ extern void print_octal_chars (struct ui_file *, const gdb_byte *,
 			       unsigned int, enum bfd_endian);
 
 extern void print_decimal_chars (struct ui_file *, const gdb_byte *,
-				 unsigned int, enum bfd_endian);
+				 unsigned int, bool, enum bfd_endian);
 
 extern void print_hex_chars (struct ui_file *, const gdb_byte *,
 			     unsigned int, enum bfd_endian, bool);
-- 
2.9.3

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

* [RFA 3/5] Simplify print_scalar_formatted
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
@ 2017-06-02 19:37 ` Tom Tromey
  2017-06-05 17:27   ` Pedro Alves
  2017-06-02 19:37 ` [RFA 4/5] Remove val_print_type_code_int Tom Tromey
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This unifies the two switches in print_scalar_formatted, removing some
now-redundant code.  Now scalar types are never converted to LONGEST,
instead printing is done using print_*_chars, operating on the byte
representation.

ChangeLog
2017-06-02  Tom Tromey  <tom@tromey.com>

	* printcmd.c (print_scalar_formatted): Unify the two switches.
	Don't convert scalars to LONGEST.
---
 gdb/ChangeLog  |   5 ++
 gdb/printcmd.c | 181 ++++++++++++++++++---------------------------------------
 2 files changed, 61 insertions(+), 125 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a529694..731d908 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2017-06-02  Tom Tromey  <tom@tromey.com>
 
+	* printcmd.c (print_scalar_formatted): Unify the two switches.
+	Don't convert scalars to LONGEST.
+
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
 	PR exp/16225:
 	* valprint.h (print_decimal_chars): Update.
 	* valprint.c (maybe_negate_by_bytes): New function.
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 84f41f5..91cc4ff 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -356,47 +356,12 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 			int size, struct ui_file *stream)
 {
   struct gdbarch *gdbarch = get_type_arch (type);
-  LONGEST val_long = 0;
   unsigned int len = TYPE_LENGTH (type);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* String printing should go through val_print_scalar_formatted.  */
   gdb_assert (options->format != 's');
 
-  if (len > sizeof(LONGEST)
-      && (TYPE_CODE (type) == TYPE_CODE_INT
-	  || TYPE_CODE (type) == TYPE_CODE_ENUM))
-    {
-      switch (options->format)
-	{
-	case 'o':
-	  print_octal_chars (stream, valaddr, len, byte_order);
-	  return;
-	case 'u':
-	case 'd':
-	  print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
-			       byte_order);
-	  return;
-	case 't':
-	  print_binary_chars (stream, valaddr, len, byte_order, size > 0);
-	  return;
-	case 'x':
-	  print_hex_chars (stream, valaddr, len, byte_order, size > 0);
-	  return;
-	case 'z':
-	  print_hex_chars (stream, valaddr, len, byte_order, true);
-	  return;
-	case 'c':
-	  print_char_chars (stream, type, valaddr, len, byte_order);
-	  return;
-	default:
-	  break;
-	};
-    }
-
-  if (options->format != 'f')
-    val_long = unpack_long (type, valaddr);
-
   /* If the value is a pointer, and pointers and addresses are not the
      same, then at this point, the value's length (in target bytes) is
      gdbarch_addr_bit/TARGET_CHAR_BIT, not TYPE_LENGTH (type).  */
@@ -406,58 +371,76 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
   /* If we are printing it as unsigned, truncate it in case it is actually
      a negative signed value (e.g. "print/u (short)-1" should print 65535
      (if shorts are 16 bits) instead of 4294967295).  */
-  if (options->format != 'd' || TYPE_UNSIGNED (type))
+  if (options->format != 'c'
+      && (options->format != 'd' || TYPE_UNSIGNED (type)))
     {
-      if (len < sizeof (LONGEST))
-	val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1;
+      if (len < TYPE_LENGTH (type) && byte_order == BFD_ENDIAN_BIG)
+	valaddr += TYPE_LENGTH (type) - len;
     }
 
-  switch (options->format)
+  if (size != 0 && (options->format == 'x' || options->format == 't'))
     {
-    case 'x':
-      if (!size)
+      /* Truncate to fit.  */
+      unsigned newlen;
+      switch (size)
 	{
-	  /* No size specified, like in print.  Print varying # of digits.  */
-	  print_longest (stream, 'x', 1, val_long);
+	case 'b':
+	  newlen = 1;
+	  break;
+	case 'h':
+	  newlen = 2;
+	  break;
+	case 'w':
+	  newlen = 4;
+	  break;
+	case 'g':
+	  newlen = 8;
+	  break;
+	default:
+	  error (_("Undefined output size \"%c\"."), size);
 	}
-      else
-	switch (size)
-	  {
-	  case 'b':
-	  case 'h':
-	  case 'w':
-	  case 'g':
-	    print_longest (stream, size, 1, val_long);
-	    break;
-	  default:
-	    error (_("Undefined output size \"%c\"."), size);
-	  }
-      break;
+      if (newlen < len && byte_order == BFD_ENDIAN_BIG)
+	valaddr += len - newlen;
+      len = newlen;
+    }
 
-    case 'd':
-      print_longest (stream, 'd', 1, val_long);
+  switch (options->format)
+    {
+    case 'o':
+      print_octal_chars (stream, valaddr, len, byte_order);
       break;
-
     case 'u':
-      print_longest (stream, 'u', 0, val_long);
+      print_decimal_chars (stream, valaddr, len, false, byte_order);
       break;
-
-    case 'o':
-      print_longest (stream, 'o', 1, val_long);
+    case 0:
+    case 'd':
+      if (TYPE_CODE (type) != TYPE_CODE_FLT)
+	{
+	  print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
+			       byte_order);
+	  break;
+	}
+      /* FALLTHROUGH */
+    case 'f':
+      type = float_type_from_length (type);
+      print_floating (valaddr, type, stream);
       break;
 
-    case 'a':
-      {
-	CORE_ADDR addr = unpack_pointer (type, valaddr);
-
-	print_address (gdbarch, addr, stream);
-      }
+    case 't':
+      print_binary_chars (stream, valaddr, len, byte_order, size > 0);
+      break;
+    case 'x':
+      print_hex_chars (stream, valaddr, len, byte_order, size > 0);
+      break;
+    case 'z':
+      print_hex_chars (stream, valaddr, len, byte_order, true);
       break;
-
     case 'c':
       {
 	struct value_print_options opts = *options;
 
+	LONGEST val_long = unpack_long (type, valaddr);
+
 	opts.format = 0;
 	if (TYPE_UNSIGNED (type))
 	  type = builtin_type (gdbarch)->builtin_true_unsigned_char;
@@ -468,66 +451,14 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
       }
       break;
 
-    case 'f':
-      type = float_type_from_length (type);
-      print_floating (valaddr, type, stream);
-      break;
-
-    case 0:
-      internal_error (__FILE__, __LINE__,
-		      _("failed internal consistency check"));
-
-    case 't':
-      /* Binary; 't' stands for "two".  */
+    case 'a':
       {
-	char bits[8 * (sizeof val_long) + 1];
-	char buf[8 * (sizeof val_long) + 32];
-	char *cp = bits;
-	int width;
-
-	if (!size)
-	  width = 8 * (sizeof val_long);
-	else
-	  switch (size)
-	    {
-	    case 'b':
-	      width = 8;
-	      break;
-	    case 'h':
-	      width = 16;
-	      break;
-	    case 'w':
-	      width = 32;
-	      break;
-	    case 'g':
-	      width = 64;
-	      break;
-	    default:
-	      error (_("Undefined output size \"%c\"."), size);
-	    }
+	CORE_ADDR addr = unpack_pointer (type, valaddr);
 
-	bits[width] = '\0';
-	while (width-- > 0)
-	  {
-	    bits[width] = (val_long & 1) ? '1' : '0';
-	    val_long >>= 1;
-	  }
-	if (!size)
-	  {
-	    while (*cp && *cp == '0')
-	      cp++;
-	    if (*cp == '\0')
-	      cp--;
-	  }
-	strncpy (buf, cp, sizeof (bits));
-	fputs_filtered (buf, stream);
+	print_address (gdbarch, addr, stream);
       }
       break;
 
-    case 'z':
-      print_hex_chars (stream, valaddr, len, byte_order, true);
-      break;
-
     default:
       error (_("Undefined output format \"%c\"."), options->format);
     }
-- 
2.9.3

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

* [RFA 4/5] Remove val_print_type_code_int
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
  2017-06-02 19:37 ` [RFA 3/5] Simplify print_scalar_formatted Tom Tromey
@ 2017-06-02 19:37 ` Tom Tromey
  2017-06-02 19:37 ` [RFA 5/5] Add some 128-bit integer tests Tom Tromey
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

Now that print_scalar_formatted is more capable, there's no need for
val_print_type_code_int.  This patch removes it in favor of
val_print_scalar_formatted.

2017-06-02  Tom Tromey  <tom@tromey.com>

	* valprint.h (val_print_type_code_int): Remove.
	* valprint.c (generic_val_print_int): Always call
	val_print_scalar_formatted.
	(val_print_type_code_int): Remove.
	* printcmd.c (print_scalar_formatted): Handle options->format==0.
	* f-valprint.c (f_val_print): Use val_print_scalar_formatted.
	* c-valprint.c (c_val_print_int): Use val_print_scalar_formatted.
	* ada-valprint.c (ada_val_print_num): Use
	val_print_scalar_formatted.
---
 gdb/ChangeLog      | 12 +++++++++++
 gdb/ada-valprint.c |  3 ++-
 gdb/c-valprint.c   |  4 ++--
 gdb/f-valprint.c   |  3 ++-
 gdb/valprint.c     | 60 +++++-------------------------------------------------
 gdb/valprint.h     |  3 ---
 6 files changed, 23 insertions(+), 62 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 731d908..55bb725 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,17 @@
 2017-06-02  Tom Tromey  <tom@tromey.com>
 
+	* valprint.h (val_print_type_code_int): Remove.
+	* valprint.c (generic_val_print_int): Always call
+	val_print_scalar_formatted.
+	(val_print_type_code_int): Remove.
+	* printcmd.c (print_scalar_formatted): Handle options->format==0.
+	* f-valprint.c (f_val_print): Use val_print_scalar_formatted.
+	* c-valprint.c (c_val_print_int): Use val_print_scalar_formatted.
+	* ada-valprint.c (ada_val_print_num): Use
+	val_print_scalar_formatted.
+
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
 	* printcmd.c (print_scalar_formatted): Unify the two switches.
 	Don't convert scalars to LONGEST.
 
diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c
index d2489a2..8095eed 100644
--- a/gdb/ada-valprint.c
+++ b/gdb/ada-valprint.c
@@ -859,7 +859,8 @@ ada_val_print_num (struct type *type, const gdb_byte *valaddr,
 	}
       else
 	{
-	  val_print_type_code_int (type, valaddr + offset_aligned, stream);
+	  val_print_scalar_formatted (type, offset_aligned,
+				      original_value, options, 0, stream);
 	  if (ada_is_character_type (type))
 	    {
 	      LONGEST c;
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c
index ab1de5c..653fed6 100644
--- a/gdb/c-valprint.c
+++ b/gdb/c-valprint.c
@@ -454,8 +454,8 @@ c_val_print_int (struct type *type, struct type *unresolved_type,
     }
   else
     {
-      val_print_type_code_int (type, valaddr + embedded_offset * unit_size,
-			       stream);
+      val_print_scalar_formatted (type, embedded_offset,
+				  original_value, options, 0, stream);
       /* C and C++ has no single byte int type, char is used
 	 instead.  Since we don't know whether the value is really
 	 intended to be used as an integer or a character, print
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index a517406..4234447 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -311,7 +311,8 @@ f_val_print (struct type *type, int embedded_offset,
 	}
       else
 	{
-	  val_print_type_code_int (type, valaddr + embedded_offset, stream);
+	  val_print_scalar_formatted (type, embedded_offset,
+				      original_value, options, 0, stream);
 	  /* C and C++ has no single byte int type, char is used instead.
 	     Since we don't know whether the value is really intended to
 	     be used as an integer or a character, print the character
diff --git a/gdb/valprint.c b/gdb/valprint.c
index fcd74f1..67b737f 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -781,25 +781,12 @@ generic_val_print_int (struct type *type,
 		       struct value *original_value,
 		       const struct value_print_options *options)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
-
-  if (options->format || options->output_format)
-    {
-      struct value_print_options opts = *options;
-
-      opts.format = (options->format ? options->format
-		     : options->output_format);
-      val_print_scalar_formatted (type, embedded_offset,
-				  original_value, &opts, 0, stream);
-    }
-  else
-    {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
+  struct value_print_options opts = *options;
 
-      val_print_type_code_int (type, valaddr + embedded_offset * unit_size,
-			       stream);
-    }
+  opts.format = (options->format ? options->format
+		 : options->output_format);
+  val_print_scalar_formatted (type, embedded_offset,
+			      original_value, &opts, 0, stream);
 }
 
 /* generic_val_print helper for TYPE_CODE_CHAR.  */
@@ -1237,43 +1224,6 @@ value_print (struct value *val, struct ui_file *stream,
   LA_VALUE_PRINT (val, stream, options);
 }
 
-/* Called by various <lang>_val_print routines to print
-   TYPE_CODE_INT's.  TYPE is the type.  VALADDR is the address of the
-   value.  STREAM is where to print the value.  */
-
-void
-val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
-			 struct ui_file *stream)
-{
-  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
-
-  if (TYPE_LENGTH (type) > sizeof (LONGEST))
-    {
-      LONGEST val;
-
-      if (TYPE_UNSIGNED (type)
-	  && extract_long_unsigned_integer (valaddr, TYPE_LENGTH (type),
-					    byte_order, &val))
-	{
-	  print_longest (stream, 'u', 0, val);
-	}
-      else
-	{
-	  /* Signed, or we couldn't turn an unsigned value into a
-	     LONGEST.  For signed values, one could assume two's
-	     complement (a reasonable assumption, I think) and do
-	     better than this.  */
-	  print_hex_chars (stream, (unsigned char *) valaddr,
-			   TYPE_LENGTH (type), byte_order, false);
-	}
-    }
-  else
-    {
-      print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0,
-		     unpack_long (type, valaddr));
-    }
-}
-
 static void
 val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
 			   struct ui_file *stream)
diff --git a/gdb/valprint.h b/gdb/valprint.h
index f71d4ab..302626d 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -121,9 +121,6 @@ extern void val_print_array_elements (struct type *, LONGEST,
 				      const struct value_print_options *,
 				      unsigned int);
 
-extern void val_print_type_code_int (struct type *, const gdb_byte *,
-				     struct ui_file *);
-
 extern void val_print_scalar_formatted (struct type *,
 					LONGEST,
 					struct value *,
-- 
2.9.3

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

* [RFA 5/5] Add some 128-bit integer tests
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
  2017-06-02 19:37 ` [RFA 3/5] Simplify print_scalar_formatted Tom Tromey
  2017-06-02 19:37 ` [RFA 4/5] Remove val_print_type_code_int Tom Tromey
@ 2017-06-02 19:37 ` Tom Tromey
  2017-06-05 17:33   ` Pedro Alves
  2017-06-02 19:37 ` [RFA 1/5] Don't always zero pad in print_*_chars Tom Tromey
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This adds some tests for printing 128-bit integers.

2017-06-02  Tom Tromey  <tom@tromey.com>

	* gdb.dwarf2/formdata16.exp: Add tests.
---
 gdb/testsuite/ChangeLog                 |  4 ++++
 gdb/testsuite/gdb.dwarf2/formdata16.exp | 31 +++++++++++++++++++++++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 1b72c3a..9c4abe4 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2017-06-02  Tom Tromey  <tom@tromey.com>
 
+	* gdb.dwarf2/formdata16.exp: Add tests.
+
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
 	PR exp/16225:
 	* gdb.reverse/i386-sse-reverse.exp: Update tests.
 	* gdb.arch/vsx-regs.exp: Update tests.
diff --git a/gdb/testsuite/gdb.dwarf2/formdata16.exp b/gdb/testsuite/gdb.dwarf2/formdata16.exp
index bba2015..a3ccbd3 100644
--- a/gdb/testsuite/gdb.dwarf2/formdata16.exp
+++ b/gdb/testsuite/gdb.dwarf2/formdata16.exp
@@ -41,18 +41,22 @@ set high "0x123456789abcdef0"
 set low "0x0fedcba987654321"
 if { $endianness == "big" } {
     set pair $high,$low
+    set pair2 0x0,$low
+    set negative 0xffffffffffffffff,$low
 } else {
     set pair $low,$high
+    set pair2 $low,0x0
+    set negative $low,0xffffffffffffffff
 }
 
 # Make some DWARF for the test.
 set asm_file [standard_output_file $srcfile2]
 Dwarf::assemble $asm_file {
-    global pair
+    global pair pair2 negative
 
     cu { addr_size 4 } {
  	compile_unit {} {
-	    declare_labels int_label
+	    declare_labels int_label sint_label
 
 	    int_label: DW_TAG_base_type {
 		{DW_AT_byte_size 16 DW_FORM_udata}
@@ -60,11 +64,29 @@ Dwarf::assemble $asm_file {
 		{DW_AT_name "__uint128"}
 	    }
 
+	    sint_label: DW_TAG_base_type {
+		{DW_AT_byte_size 16 DW_FORM_udata}
+		{DW_AT_encoding @DW_ATE_signed}
+		{DW_AT_name "__int128"}
+	    }
+
 	    DW_TAG_variable {
 		{name xxx}
 		{type :$int_label}
 		{const_value $pair DW_FORM_data16}
 	    }
+
+	    DW_TAG_variable {
+		{name yyy}
+		{type :$int_label}
+		{const_value $pair2 DW_FORM_data16}
+	    }
+
+	    DW_TAG_variable {
+		{name sss}
+		{type :$sint_label}
+		{const_value $negative DW_FORM_data16}
+	    }
 	}
     }
 }
@@ -75,3 +97,8 @@ if { [prepare_for_testing "failed to prepare" ${testfile} \
 }
 
 gdb_test "p/x xxx" " = 0x123456789abcdef00fedcba987654321"
+gdb_test "p xxx" "= 24197857203266734864629346612071973665"
+gdb_test "p/x yyy" " = 0xfedcba987654321"
+gdb_test "p yyy" "= 1147797409030816545"
+gdb_test "p/x sss" " = 0xffffffffffffffff0fedcba987654321"
+gdb_test "p sss" "= -17298946664678735071"
-- 
2.9.3

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

* [RFA 1/5] Don't always zero pad in print_*_chars
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
                   ` (2 preceding siblings ...)
  2017-06-02 19:37 ` [RFA 5/5] Add some 128-bit integer tests Tom Tromey
@ 2017-06-02 19:37 ` Tom Tromey
  2017-06-05 17:27   ` Pedro Alves
  2017-06-02 19:37 ` [RFA 2/5] Let print_decimal_chars handle signed values Tom Tromey
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-02 19:37 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes print_octal_chars and print_decimal_chars to never zero
pad, and changes print_binary_chars and print_hex_chars to only
optionally zero-pad, based on a flag.

ChangeLog
2017-06-02  Tom Tromey  <tom@tromey.com>

	PR exp/16225:
	* valprint.h (print_binary_chars, print_hex_chars): Update.
	* valprint.c (val_print_type_code_int): Update.
	(print_binary_chars): Add "zero_pad" argument.
	(emit_octal_digit): New function.
	(print_octal_chars): Don't zero-pad.
	(print_decimal_chars): Likewise.
	(print_hex_chars): Add "zero_pad" argument.
	* sh64-tdep.c (sh64_do_fp_register): Update.
	* regcache.c (regcache::dump): Update.
	* printcmd.c (print_scalar_formatted): Update.
	* infcmd.c (default_print_one_register_info): Update.

2017-06-02  Tom Tromey  <tom@tromey.com>

	PR exp/16225:
	* gdb.reverse/i386-sse-reverse.exp: Update tests.
	* gdb.arch/vsx-regs.exp: Update tests.
	* gdb.arch/s390-vregs.exp (hex128): New proc.
	Update test.
	* gdb.arch/altivec-regs.exp: Update tests.
---
 gdb/ChangeLog                                  |  15 +++
 gdb/infcmd.c                                   |   3 +-
 gdb/printcmd.c                                 |  14 +--
 gdb/regcache.c                                 |   4 +-
 gdb/sh64-tdep.c                                |   2 +-
 gdb/testsuite/ChangeLog                        |   9 ++
 gdb/testsuite/gdb.arch/altivec-regs.exp        |   8 +-
 gdb/testsuite/gdb.arch/s390-vregs.exp          |  17 ++-
 gdb/testsuite/gdb.arch/vsx-regs.exp            |   8 +-
 gdb/testsuite/gdb.reverse/i386-sse-reverse.exp |  94 ++++++++---------
 gdb/valprint.c                                 | 137 +++++++++++++++++--------
 gdb/valprint.h                                 |   4 +-
 12 files changed, 197 insertions(+), 118 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 263d57f..bc2ac04 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
+	PR exp/16225:
+	* valprint.h (print_binary_chars, print_hex_chars): Update.
+	* valprint.c (val_print_type_code_int): Update.
+	(print_binary_chars): Add "zero_pad" argument.
+	(emit_octal_digit): New function.
+	(print_octal_chars): Don't zero-pad.
+	(print_decimal_chars): Likewise.
+	(print_hex_chars): Add "zero_pad" argument.
+	* sh64-tdep.c (sh64_do_fp_register): Update.
+	* regcache.c (regcache::dump): Update.
+	* printcmd.c (print_scalar_formatted): Update.
+	* infcmd.c (default_print_one_register_info): Update.
+
 2017-05-31  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* memattr.c (mem_info_command): Rename to ...
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 09060b5..db09f19 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2310,7 +2310,8 @@ default_print_one_register_info (struct ui_file *file,
       if (print_raw_format)
 	{
 	  fprintf_filtered (file, "\t(raw ");
-	  print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order);
+	  print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order,
+			   true);
 	  fprintf_filtered (file, ")");
 	}
     }
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 02d6e1c..66395d5 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -377,10 +377,13 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 	  print_decimal_chars (stream, valaddr, len, byte_order);
 	  return;
 	case 't':
-	  print_binary_chars (stream, valaddr, len, byte_order);
+	  print_binary_chars (stream, valaddr, len, byte_order, size > 0);
 	  return;
 	case 'x':
-	  print_hex_chars (stream, valaddr, len, byte_order);
+	  print_hex_chars (stream, valaddr, len, byte_order, size > 0);
+	  return;
+	case 'z':
+	  print_hex_chars (stream, valaddr, len, byte_order, true);
 	  return;
 	case 'c':
 	  print_char_chars (stream, type, valaddr, len, byte_order);
@@ -439,10 +442,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
       break;
 
     case 'o':
-      if (val_long)
-	print_longest (stream, 'o', 1, val_long);
-      else
-	fprintf_filtered (stream, "0");
+      print_longest (stream, 'o', 1, val_long);
       break;
 
     case 'a':
@@ -524,7 +524,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
       break;
 
     case 'z':
-      print_hex_chars (stream, valaddr, len, byte_order);
+      print_hex_chars (stream, valaddr, len, byte_order, true);
       break;
 
     default:
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 3798f0a..dd22909 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1600,7 +1600,7 @@ regcache::dump (ui_file *file, enum regcache_dump_what what_to_dump)
 	      raw_read (regnum, buf);
 	      print_hex_chars (file, buf,
 			       m_descr->sizeof_register[regnum],
-			       gdbarch_byte_order (gdbarch));
+			       gdbarch_byte_order (gdbarch), true);
 	    }
 	}
 
@@ -1621,7 +1621,7 @@ regcache::dump (ui_file *file, enum regcache_dump_what what_to_dump)
 	      else
 		print_hex_chars (file, buf,
 				 m_descr->sizeof_register[regnum],
-				 gdbarch_byte_order (gdbarch));
+				 gdbarch_byte_order (gdbarch), true);
 	    }
 	}
 
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 06ae04e..5136932 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1949,7 +1949,7 @@ sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file,
   fprintf_filtered (file, "\t(raw ");
   print_hex_chars (file, raw_buffer,
 		   register_size (gdbarch, regnum),
-		   gdbarch_byte_order (gdbarch));
+		   gdbarch_byte_order (gdbarch), true);
   fprintf_filtered (file, ")");
   fprintf_filtered (file, "\n");
 }
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index cb1d8ec..1b72c3a 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2017-06-02  Tom Tromey  <tom@tromey.com>
+
+	PR exp/16225:
+	* gdb.reverse/i386-sse-reverse.exp: Update tests.
+	* gdb.arch/vsx-regs.exp: Update tests.
+	* gdb.arch/s390-vregs.exp (hex128): New proc.
+	Update test.
+	* gdb.arch/altivec-regs.exp: Update tests.
+
 2017-05-30  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* gdb.base/watch-cond-infcall.exp: Don't run if target doesn't
diff --git a/gdb/testsuite/gdb.arch/altivec-regs.exp b/gdb/testsuite/gdb.arch/altivec-regs.exp
index 680b512..cc679b2 100644
--- a/gdb/testsuite/gdb.arch/altivec-regs.exp
+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp
@@ -94,9 +94,9 @@ gdb_test_multiple "show endian" "$msg" {
 # b) the register read (below) also works.
 
 if {$endianness == "big"} {
-set vector_register ".uint128 = 0x00000001000000010000000100000001, 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_register ".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.."
 } else {
-set vector_register ".uint128 = 0x00000001000000010000000100000001, 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_register ".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.."
 }
 
 for {set i 0} {$i < 32} {incr i 1} {
@@ -113,9 +113,9 @@ gdb_test "info reg vscr" "vscr.*0x1\t1" "info reg vscr"
 # the way gdb works.
 
 if {$endianness == "big"} {
-     set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."
+     set decimal_vector ".uint128 = 0x1000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."
 } else {
-     set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.."
+     set decimal_vector ".uint128 = 0x1000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.."
 }
 
 for {set i 0} {$i < 32} {incr i 1} {
diff --git a/gdb/testsuite/gdb.arch/s390-vregs.exp b/gdb/testsuite/gdb.arch/s390-vregs.exp
index 800cc0b..078c153 100644
--- a/gdb/testsuite/gdb.arch/s390-vregs.exp
+++ b/gdb/testsuite/gdb.arch/s390-vregs.exp
@@ -146,16 +146,23 @@ if { $i != 32 } {
 gdb_continue_to_breakpoint "change vrs"
 set vregs [capture_command_output "info registers vector" ""]
 
+# Format a 128-bit value, given individual 4-byte values, as hex.
+# Leading zeros are suppressed.
+proc hex128 {a_high a_low b_high b_low} {
+    set result [format %08x%08x%08x%08x \
+		    [expr $a_high * ($i + 1) * $a_high ] \
+		    [expr $a_low * ($i + 1) * $a_low ] \
+		    [expr $b_high * (32 - $i) * $b_high * 32] \
+		    [expr $b_low * (32 - $i) * $b_low * 32] ]
+    return [regsub -- "^0*" $result ""]
+}
+
 set j 1
 foreach {- r i val} [regexp -all -inline -line \
 			 {^(\D*)(\d+)\s+.*?uint128 = 0x([0-9a-f]+?)} $vregs] {
     if { $r ne "v" } {
 	fail "info registers vector: bad line $j"
-    } elseif { $val ne [format %08x%08x%08x%08x \
-			    [expr $a_high * ($i + 1) * $a_high ] \
-			    [expr $a_low * ($i + 1) * $a_low ] \
-			    [expr $b_high * (32 - $i) * $b_high * 32] \
-			    [expr $b_low * (32 - $i) * $b_low * 32] ] } {
+    } elseif { $val ne [hex128 $a_high $a_low $b_high $b_low] } {
 	fail "compare \$v$i"
     }
     incr j 1
diff --git a/gdb/testsuite/gdb.arch/vsx-regs.exp b/gdb/testsuite/gdb.arch/vsx-regs.exp
index bedbcaa..15e7196 100644
--- a/gdb/testsuite/gdb.arch/vsx-regs.exp
+++ b/gdb/testsuite/gdb.arch/vsx-regs.exp
@@ -79,9 +79,9 @@ if {$endianness == "big"} {
 
     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_register3 ".uint128 = 0x00000001000000010000000100000001, 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 = .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_vr ".uint128 = 0x00000001000000010000000100000001, 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 = .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.."
 } 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.."
 
@@ -91,9 +91,9 @@ if {$endianness == "big"} {
 
     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_register3 ".uint128 = 0x00000001000000010000000100000001, 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 = .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_vr ".uint128 = 0x00000001000000010000000100000001, 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 = .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 float_register ".raw 0xdeadbeefdeadbeef."
diff --git a/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp b/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp
index 1d9cd19..6f36476 100644
--- a/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/i386-sse-reverse.exp
@@ -200,7 +200,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "orpd.*" "reverse-step to orpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse orps"
 
 gdb_test "info register xmm1" \
@@ -214,7 +214,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "mulss.*" "reverse-step to mulss"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse orpd"
 
 gdb_test "info register xmm1" \
@@ -228,7 +228,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "mulsd.*" "reverse-step to mulsd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse mulss"
 
 gdb_test "info register xmm1" \
@@ -242,7 +242,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "mulps.*" "reverse-step to mulps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse mulsd"
 
 gdb_test "info register xmm1" \
@@ -256,7 +256,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "mulpd.*" "reverse-step to mulpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse mulps"
 
 gdb_test "info register xmm1" \
@@ -270,7 +270,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "divss.*" "reverse-step to divss"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0000000000000000fff80000ffc00000.*" \
+    "xmm0 .*uint128 = 0xfff80000ffc00000.*" \
     "verify xmm0 after reverse mulpd"
 
 gdb_test "info register xmm1" \
@@ -284,7 +284,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "divsd.*" "reverse-step to divsd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x00000000000000008000000080000000.*" \
+    "xmm0 .*uint128 = 0x8000000080000000.*" \
     "verify xmm0 after reverse divss"
 
 gdb_test "info register xmm1" \
@@ -298,11 +298,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "divps.*" "reverse-step to divps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x00000000000000008000000080000000.*" \
+    "xmm0 .*uint128 = 0x8000000080000000.*" \
     "verify xmm0 after reverse divsd"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x00000000000000000000000080000000.*" \
+    "xmm1 .*uint128 = 0x80000000.*" \
     "verify xmm1 after reverse divsd"
 
 gdb_test "info register xmm2" \
@@ -312,11 +312,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "divpd.*" "reverse-step to divpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x00000000000000008000000080000000.*" \
+    "xmm0 .*uint128 = 0x8000000080000000.*" \
     "verify xmm0 after reverse divps"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x00000000000000000000000080000000.*" \
+    "xmm1 .*uint128 = 0x80000000.*" \
     "verify xmm1 after reverse divps"
 
 gdb_test "info register xmm2" \
@@ -326,7 +326,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cvtpd2ps.*" "reverse-step to cvtpd2ps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x00000000000000008000000080000000.*" \
+    "xmm0 .*uint128 = 0x8000000080000000.*" \
     "verify xmm0 after reverse divpd"
 
 gdb_test "info register xmm1" \
@@ -340,7 +340,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cvtpd2dq.*" "reverse-step to cvtpd2dq"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a090807060504ffffffff.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a090807060504ffffffff.*" \
     "verify xmm0 after reverse cvtpd2ps"
 
 gdb_test "info register xmm1" \
@@ -354,11 +354,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cvtdq2ps.*" "reverse-step to cvtdq2ps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a090807060504ffffffff.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a090807060504ffffffff.*" \
     "verify xmm0 after reverse cvtpd2dq"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0000000000000000ffffffffffffffff.*" \
+    "xmm1 .*uint128 = 0xffffffffffffffff.*" \
     "verify xmm1 after reverse cvtpd2dq"
 
 gdb_test "info register xmm2" \
@@ -368,11 +368,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cvtdq2pd.*" "reverse-step to cvtdq2pd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a090807060504ffffffff.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a090807060504ffffffff.*" \
     "verify xmm0 after reverse cvtdq2ps"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0000000000000000ffffffffffffffff.*" \
+    "xmm1 .*uint128 = 0xffffffffffffffff.*" \
     "verify xmm1 after reverse cvtdq2ps"
 
 gdb_test "info register xmm2" \
@@ -382,11 +382,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "comiss.*" "reverse-step to comiss"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a090807060504ffffffff.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a090807060504ffffffff.*" \
     "verify xmm0 after reverse cvtdq2pd"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0000000000000000ffffffffffffffff.*" \
+    "xmm1 .*uint128 = 0xffffffffffffffff.*" \
     "verify xmm1 after reverse cvtdq2pd"
 
 gdb_test "info register xmm2" \
@@ -396,11 +396,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "comisd.*" "reverse-step to comisd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a090807060504ffffffff.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a090807060504ffffffff.*" \
     "verify xmm0 after reverse comiss"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0000000000000000ffffffffffffffff.*" \
+    "xmm1 .*uint128 = 0xffffffffffffffff.*" \
     "verify xmm1 after reverse comiss"
 
 gdb_test "info register xmm2" \
@@ -410,11 +410,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cmpss.*" "reverse-step to cmpss"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse comisd"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0000000000000000ffffffffffffffff.*" \
+    "xmm1 .*uint128 = 0xffffffffffffffff.*" \
     "verify xmm1 after reverse comisd"
 
 gdb_test "info register xmm2" \
@@ -424,11 +424,11 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cmpsd.*" "reverse-step to cmpsd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse cmpss"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x00000000000000000000000000000000.*" \
+    "xmm1 .*uint128 = 0x.*" \
     "verify xmm1 after reverse cmpss"
 
 gdb_test "info register xmm2" \
@@ -438,35 +438,35 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "cmpps.*" "reverse-step to cmpps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse cmpsd"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x00000000000000000000000000000000.*" \
+    "xmm1 .*uint128 = 0x.*" \
     "verify xmm1 after reverse cmpsd"
 
 gdb_test "info register xmm2" \
-    "xmm2 .*uint128 = 0x0f0e0d0c0b0a09082726252400000000.*" \
+    "xmm2 .*uint128 = 0xf0e0d0c0b0a09082726252400000000.*" \
     "verify xmm2 after reverse cmpsd"
 
 gdb_test "reverse-step" "cmppd.*" "reverse-step to cmppd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse cmpps"
 
 gdb_test "info register xmm1" \
-    "xmm1 .*uint128 = 0x0f0e0d0c0b0a09082726252400000000.*" \
+    "xmm1 .*uint128 = 0xf0e0d0c0b0a09082726252400000000.*" \
     "verify xmm1 after reverse cmpps"
 
 gdb_test "info register xmm2" \
-    "xmm2 .*uint128 = 0x0f0e0d0c0b0a09082726252400000000.*" \
+    "xmm2 .*uint128 = 0xf0e0d0c0b0a09082726252400000000.*" \
     "verify xmm2 after reverse cmpps"
 
 gdb_test "reverse-step" "andps.*" "reverse-step to andps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse cmppd"
 
 gdb_test "info register xmm1" \
@@ -474,13 +474,13 @@ gdb_test "info register xmm1" \
     "verify xmm1 after reverse cmppd"
 
 gdb_test "info register xmm2" \
-    "xmm2 .*uint128 = 0x0f0e0d0c0b0a09082726252400000000.*" \
+    "xmm2 .*uint128 = 0xf0e0d0c0b0a09082726252400000000.*" \
     "verify xmm2 after reverse cmppd"
 
 gdb_test "reverse-step" "andpd.*" "reverse-step to andpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse andps"
 
 gdb_test "info register xmm1" \
@@ -494,7 +494,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addsubps.*" "reverse-step to addsubps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse andpd"
 
 gdb_test "info register xmm1" \
@@ -508,7 +508,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addsubpd.*" "reverse-step to addsubpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050423222120.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050423222120.*" \
     "verify xmm0 after reverse addsubps"
 
 gdb_test "info register xmm1" \
@@ -522,7 +522,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addss.*" "reverse-step to addss"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse addsubpd"
 
 gdb_test "info register xmm1" \
@@ -536,7 +536,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addsd.*" "reverse-step to addsd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse addss"
 
 gdb_test "info register xmm1" \
@@ -550,7 +550,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addps.*" "reverse-step to addps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse addsd"
 
 gdb_test "info register xmm1" \
@@ -564,7 +564,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "addpd.*" "reverse-step to addpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse addps"
 
 gdb_test "info register xmm1" \
@@ -612,7 +612,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "pabsd.*" "reverse-step to pabsd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse pabsd"
 
 gdb_test "info register xmm1" \
@@ -626,7 +626,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "pabsw.*" "reverse-step to pabsw"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse pabsw"
 
 gdb_test "info register xmm1" \
@@ -640,7 +640,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "pabsb.*" "reverse-step to pabsb"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse pabsb"
 
 gdb_test "info register xmm1" \
@@ -676,7 +676,7 @@ gdb_test_multiple "continue" $test {
 gdb_test "reverse-step" "blendvps.*" "reverse-step to blendvps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09082726252413121110.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09082726252413121110.*" \
     "verify xmm0 at end of sse4_test"
 
 gdb_test "info register xmm1" \
@@ -690,7 +690,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "blendvpd.*" "reverse-step to blendvpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09082726252413121110.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09082726252413121110.*" \
     "verify xmm0 after reverse blendvps"
 
 gdb_test "info register xmm1" \
@@ -704,7 +704,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "blendps.*" "reverse-step to blendps"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09081716151413121110.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09081716151413121110.*" \
     "verify xmm0 after reverse blendvpd"
 
 gdb_test "info register xmm1" \
@@ -718,7 +718,7 @@ gdb_test "info register xmm2" \
 gdb_test "reverse-step" "blendpd.*" "reverse-step to blendpd"
 
 gdb_test "info register xmm0" \
-    "xmm0 .*uint128 = 0x0f0e0d0c0b0a09080706050403020100.*" \
+    "xmm0 .*uint128 = 0xf0e0d0c0b0a09080706050403020100.*" \
     "verify xmm0 after reverse blendps"
 
 gdb_test "info register xmm1" \
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 6937dab..aa34b68 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1264,7 +1264,7 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
 	     complement (a reasonable assumption, I think) and do
 	     better than this.  */
 	  print_hex_chars (stream, (unsigned char *) valaddr,
-			   TYPE_LENGTH (type), byte_order);
+			   TYPE_LENGTH (type), byte_order, false);
 	}
     }
   else
@@ -1537,7 +1537,7 @@ print_decimal_floating (const gdb_byte *valaddr, struct type *type,
 
 void
 print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
-		    unsigned len, enum bfd_endian byte_order)
+		    unsigned len, enum bfd_endian byte_order, bool zero_pad)
 {
 
 #define BITS_IN_BYTES 8
@@ -1545,14 +1545,13 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
   const gdb_byte *p;
   unsigned int i;
   int b;
+  bool seen_a_one = false;
 
   /* Declared "int" so it will be signed.
      This ensures that right shift will shift in zeros.  */
 
   const int mask = 0x080;
 
-  /* FIXME: We should be not printing leading zeroes in most cases.  */
-
   if (byte_order == BFD_ENDIAN_BIG)
     {
       for (p = valaddr;
@@ -1565,11 +1564,14 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	  for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++)
 	    {
 	      if (*p & (mask >> i))
-		b = 1;
+		b = '1';
 	      else
-		b = 0;
+		b = '0';
 
-	      fprintf_filtered (stream, "%1d", b);
+	      if (zero_pad || seen_a_one || b == '1')
+		fputc_filtered (b, stream);
+	      if (b == '1')
+		seen_a_one = true;
 	    }
 	}
     }
@@ -1582,14 +1584,34 @@ print_binary_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	  for (i = 0; i < (BITS_IN_BYTES * sizeof (*p)); i++)
 	    {
 	      if (*p & (mask >> i))
-		b = 1;
+		b = '1';
 	      else
-		b = 0;
+		b = '0';
 
-	      fprintf_filtered (stream, "%1d", b);
+	      if (zero_pad || seen_a_one || b == '1')
+		fputc_filtered (b, stream);
+	      if (b == '1')
+		seen_a_one = true;
 	    }
 	}
     }
+
+  /* When not zero-padding, ensure that something is printed when the
+     input is 0.  */
+  if (!zero_pad && !seen_a_one)
+    fputc_filtered ('0', stream);
+}
+
+/* A helper for print_octal_chars that emits a single octal digit,
+   optionally suppressing it if is zero and updating SEEN_A_ONE.  */
+
+static void
+emit_octal_digit (struct ui_file *stream, bool *seen_a_one, int digit)
+{
+  if (*seen_a_one || digit != 0)
+    fprintf_filtered (stream, "%o", digit);
+  if (digit != 0)
+    *seen_a_one = true;
 }
 
 /* VALADDR points to an integer of LEN bytes.
@@ -1603,9 +1625,6 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
   unsigned char octa1, octa2, octa3, carry;
   int cycle;
 
-  /* FIXME: We should be not printing leading zeroes in most cases.  */
-
-
   /* Octal is 3 bits, which doesn't fit.  Yuk.  So we have to track
    * the extra bits, which cycle every three bytes:
    *
@@ -1640,6 +1659,7 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
   carry = 0;
 
   fputs_filtered ("0", stream);
+  bool seen_a_one = false;
   if (byte_order == BFD_ENDIAN_BIG)
     {
       for (p = valaddr;
@@ -1654,8 +1674,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa1 = (HIGH_ZERO & *p) >> 5;
 	      octa2 = (LOW_ZERO & *p) >> 2;
 	      carry = (CARRY_ZERO & *p);
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
 	      break;
 
 	    case 1:
@@ -1665,9 +1685,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa2 = (MID_ONE & *p) >> 4;
 	      octa3 = (LOW_ONE & *p) >> 1;
 	      carry = (CARRY_ONE & *p);
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
-	      fprintf_filtered (stream, "%o", octa3);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa3);
 	      break;
 
 	    case 2:
@@ -1677,9 +1697,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa2 = (MID_TWO & *p) >> 3;
 	      octa3 = (LOW_TWO & *p);
 	      carry = 0;
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
-	      fprintf_filtered (stream, "%o", octa3);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa3);
 	      break;
 
 	    default:
@@ -1704,8 +1724,8 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa1 = (HIGH_ZERO & *p) >> 5;
 	      octa2 = (LOW_ZERO & *p) >> 2;
 	      carry = (CARRY_ZERO & *p);
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
 	      break;
 
 	    case 1:
@@ -1715,9 +1735,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa2 = (MID_ONE & *p) >> 4;
 	      octa3 = (LOW_ONE & *p) >> 1;
 	      carry = (CARRY_ONE & *p);
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
-	      fprintf_filtered (stream, "%o", octa3);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa3);
 	      break;
 
 	    case 2:
@@ -1727,9 +1747,9 @@ print_octal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 	      octa2 = (MID_TWO & *p) >> 3;
 	      octa3 = (LOW_TWO & *p);
 	      carry = 0;
-	      fprintf_filtered (stream, "%o", octa1);
-	      fprintf_filtered (stream, "%o", octa2);
-	      fprintf_filtered (stream, "%o", octa3);
+	      emit_octal_digit (stream, &seen_a_one, octa1);
+	      emit_octal_digit (stream, &seen_a_one, octa2);
+	      emit_octal_digit (stream, &seen_a_one, octa3);
 	      break;
 
 	    default:
@@ -1758,7 +1778,6 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
 #define HIGH_NIBBLE( x ) (((x) & 0x0F0) >> 4)
 
   const gdb_byte *p;
-  unsigned char *digits;
   int carry;
   int decimal_len;
   int i, j, decimal_digits;
@@ -1769,12 +1788,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
      as the base 16 number, which is 2 digits per byte.  */
 
   decimal_len = len * 2 * 2;
-  digits = (unsigned char *) xmalloc (decimal_len);
-
-  for (i = 0; i < decimal_len; i++)
-    {
-      digits[i] = 0;
-    }
+  std::vector<unsigned char> digits (decimal_len, 0);
 
   /* Ok, we have an unknown number of bytes of data to be printed in
    * decimal.
@@ -1868,40 +1882,73 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
   /* Ok, now "digits" is the decimal representation, with
      the "decimal_digits" actual digits.  Print!  */
 
-  for (i = decimal_digits - 1; i >= 0; i--)
+  for (i = decimal_digits - 1; i > 0 && digits[i] == 0; --i)
+    ;
+
+  for (; i >= 0; i--)
     {
       fprintf_filtered (stream, "%1d", digits[i]);
     }
-  xfree (digits);
 }
 
 /* VALADDR points to an integer of LEN bytes.  Print it in hex on stream.  */
 
 void
 print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
-		 unsigned len, enum bfd_endian byte_order)
+		 unsigned len, enum bfd_endian byte_order,
+		 bool zero_pad)
 {
   const gdb_byte *p;
 
-  /* FIXME: We should be not printing leading zeroes in most cases.  */
-
   fputs_filtered ("0x", stream);
   if (byte_order == BFD_ENDIAN_BIG)
     {
-      for (p = valaddr;
+      p = valaddr;
+
+      if (!zero_pad)
+	{
+	  /* Strip leading 0 bytes, but be sure to leave at least a
+	     single byte at the end.  */
+	  for (; p < valaddr + len - 1 && !*p; ++p)
+	    ;
+	}
+
+      const gdb_byte *first = p;
+      for (;
 	   p < valaddr + len;
 	   p++)
 	{
-	  fprintf_filtered (stream, "%02x", *p);
+	  /* When not zero-padding, use a different format for the
+	     very first byte printed.  */
+	  if (!zero_pad && p == first)
+	    fprintf_filtered (stream, "%x", *p);
+	  else
+	    fprintf_filtered (stream, "%02x", *p);
 	}
     }
   else
     {
-      for (p = valaddr + len - 1;
+      p = valaddr + len - 1;
+
+      if (!zero_pad)
+	{
+	  /* Strip leading 0 bytes, but be sure to leave at least a
+	     single byte at the end.  */
+	  for (; p >= valaddr + 1 && !*p; --p)
+	    ;
+	}
+
+      const gdb_byte *first = p;
+      for (;
 	   p >= valaddr;
 	   p--)
 	{
-	  fprintf_filtered (stream, "%02x", *p);
+	  /* When not zero-padding, use a different format for the
+	     very first byte printed.  */
+	  if (!zero_pad && p == first)
+	    fprintf_filtered (stream, "%x", *p);
+	  else
+	    fprintf_filtered (stream, "%02x", *p);
 	}
     }
 }
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 835296a..8bfad21 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -132,7 +132,7 @@ extern void val_print_scalar_formatted (struct type *,
 					struct ui_file *);
 
 extern void print_binary_chars (struct ui_file *, const gdb_byte *,
-				unsigned int, enum bfd_endian);
+				unsigned int, enum bfd_endian, bool);
 
 extern void print_octal_chars (struct ui_file *, const gdb_byte *,
 			       unsigned int, enum bfd_endian);
@@ -141,7 +141,7 @@ extern void print_decimal_chars (struct ui_file *, const gdb_byte *,
 				 unsigned int, enum bfd_endian);
 
 extern void print_hex_chars (struct ui_file *, const gdb_byte *,
-			     unsigned int, enum bfd_endian);
+			     unsigned int, enum bfd_endian, bool);
 
 extern void print_char_chars (struct ui_file *, struct type *,
 			      const gdb_byte *, unsigned int, enum bfd_endian);
-- 
2.9.3

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

* Re: [RFA 2/5] Let print_decimal_chars handle signed values
  2017-06-02 19:37 ` [RFA 2/5] Let print_decimal_chars handle signed values Tom Tromey
@ 2017-06-05 17:22   ` Pedro Alves
  2017-06-05 19:38     ` Tom Tromey
  0 siblings, 1 reply; 16+ messages in thread
From: Pedro Alves @ 2017-06-05 17:22 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 06/02/2017 08:36 PM, Tom Tromey wrote:
> +  out_vec->reserve (len);

std::vector::reserve() != std::vector::resize() ...

> +
> +  /* Compute -x == 1 + ~x.  */
> +  if (byte_order == BFD_ENDIAN_LITTLE)
> +    {
> +      unsigned carry = 1;
> +      for (unsigned i = 0; i < len; ++i)
> +	{
> +	  unsigned tem = (0xff & ~bytes[i]) + carry;
> +	  (*out_vec)[i] = tem & 0xff;

... so this is accessing beyond the std::vector's size.

Thanks,
Pedro Alves

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

* Re: [RFA 1/5] Don't always zero pad in print_*_chars
  2017-06-02 19:37 ` [RFA 1/5] Don't always zero pad in print_*_chars Tom Tromey
@ 2017-06-05 17:27   ` Pedro Alves
  0 siblings, 0 replies; 16+ messages in thread
From: Pedro Alves @ 2017-06-05 17:27 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 06/02/2017 08:36 PM, Tom Tromey wrote:
> This changes print_octal_chars and print_decimal_chars to never zero
> pad, and changes print_binary_chars and print_hex_chars to only
> optionally zero-pad, based on a flag.

Looks good.

Thanks,
Pedro Alves

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

* Re: [RFA 3/5] Simplify print_scalar_formatted
  2017-06-02 19:37 ` [RFA 3/5] Simplify print_scalar_formatted Tom Tromey
@ 2017-06-05 17:27   ` Pedro Alves
  0 siblings, 0 replies; 16+ messages in thread
From: Pedro Alves @ 2017-06-05 17:27 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 06/02/2017 08:36 PM, Tom Tromey wrote:
> This unifies the two switches in print_scalar_formatted, removing some
> now-redundant code.  Now scalar types are never converted to LONGEST,
> instead printing is done using print_*_chars, operating on the byte
> representation.

LGTM.

Thanks,
Pedro Alves

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

* Re: [RFA 5/5] Add some 128-bit integer tests
  2017-06-02 19:37 ` [RFA 5/5] Add some 128-bit integer tests Tom Tromey
@ 2017-06-05 17:33   ` Pedro Alves
  0 siblings, 0 replies; 16+ messages in thread
From: Pedro Alves @ 2017-06-05 17:33 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 06/02/2017 08:36 PM, Tom Tromey wrote:
> This adds some tests for printing 128-bit integers.
> 
> 2017-06-02  Tom Tromey  <tom@tromey.com>
> 
> 	* gdb.dwarf2/formdata16.exp: Add tests.

OK.

Thanks,
Pedro Alves

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

* Re: [RFA 0/5] improve printing of 128 bit ints
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
                   ` (4 preceding siblings ...)
  2017-06-02 19:37 ` [RFA 2/5] Let print_decimal_chars handle signed values Tom Tromey
@ 2017-06-05 17:35 ` Pedro Alves
  2017-06-08 14:32 ` Tom Tromey
  6 siblings, 0 replies; 16+ messages in thread
From: Pedro Alves @ 2017-06-05 17:35 UTC (permalink / raw)
  To: Tom Tromey, gdb-patches

On 06/02/2017 08:36 PM, Tom Tromey wrote:
> I wanted to improve 128-bit integer support, primarily for Rust,
> though I see in Bugzilla that I reported this bug at least twice for C
> as well.
> 
> Full 128 bit integer support has two main aspects: printing and
> arithmetic (including parser support).  This series cleans up
> printing, (bug 16225); leaving arithmetic for a future bug (bug
> 20991).
> 
> Previous printing was implemented, but always zero-padded and did not
> correctly handle signed values.  This series fixes that and removes
> some redundant code as well.
> 
> Regtested on the buildbot.

For some reason, I don't have a copy of patch #4.  But I read it
via the list archive, and it looks good to me.

Thanks,
Pedro Alves

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

* Re: [RFA 2/5] Let print_decimal_chars handle signed values
  2017-06-05 17:22   ` Pedro Alves
@ 2017-06-05 19:38     ` Tom Tromey
  0 siblings, 0 replies; 16+ messages in thread
From: Tom Tromey @ 2017-06-05 19:38 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> On 06/02/2017 08:36 PM, Tom Tromey wrote:
>> +  out_vec->reserve (len);

Pedro> std::vector::reserve() != std::vector::resize() ...

Yikes, sorry about that.

Maybe a buildbot instance could be set up to use libstdc++ debug mode
and ASAN?  That would help avoid this kind of error.

Tom

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

* Re: [RFA 0/5] improve printing of 128 bit ints
  2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
                   ` (5 preceding siblings ...)
  2017-06-05 17:35 ` [RFA 0/5] improve printing of 128 bit ints Pedro Alves
@ 2017-06-08 14:32 ` Tom Tromey
  2017-06-08 16:12   ` Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints) Pedro Alves
  6 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-08 14:32 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Tom> I wanted to improve 128-bit integer support, primarily for Rust,
Tom> though I see in Bugzilla that I reported this bug at least twice for C
Tom> as well.
[...]
Tom> Regtested on the buildbot.

I misread the results :(.  The powerpc64le builds come much later than
the other results, and this confused me because I was running several
buildbot tests at the same time.

Consider this excerpt from altivec-regs.exp:

set vector_register ".uint128 = 0x00000001000000010000000100000001, 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.."

This is an expected result from an "info regs".

This looks to me like there's a specific 128-bit value with a 1 in the
low byte of each 4-byte word, but the test is expecting that the
v4_float part will print as 0x0.  However, with my patches, the v4_float
parts print as 0x1.

I tend to think the test here is incorrect.  But, I thought I would
check in first.  What should this actually print, and why?

thanks,
Tom

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

* Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints)
  2017-06-08 14:32 ` Tom Tromey
@ 2017-06-08 16:12   ` Pedro Alves
  2017-06-12 14:34     ` Tom Tromey
  0 siblings, 1 reply; 16+ messages in thread
From: Pedro Alves @ 2017-06-08 16:12 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 06/08/2017 03:32 PM, Tom Tromey wrote:
> Tom> I wanted to improve 128-bit integer support, primarily for Rust,
> Tom> though I see in Bugzilla that I reported this bug at least twice for C
> Tom> as well.
> [...]
> Tom> Regtested on the buildbot.
> 
> I misread the results :(.  The powerpc64le builds come much later than
> the other results, and this confused me because I was running several
> buildbot tests at the same time.
> 
> Consider this excerpt from altivec-regs.exp:
> 
> set vector_register ".uint128 = 0x00000001000000010000000100000001, 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.."
> 
> This is an expected result from an "info regs".
> 
> This looks to me like there's a specific 128-bit value with a 1 in the
> low byte of each 4-byte word, but the test is expecting that the
> v4_float part will print as 0x0.  However, with my patches, the v4_float
> parts print as 0x1.
> 
> I tend to think the test here is incorrect.  But, I thought I would
> check in first.  What should this actually print, and why?

I'd expect that it prints 0x0 because "0x00000001", when reinterpreted (note,
not cast/converted) as the storage for a 32-bit float of whatever
format AltiVec uses, gives you a real number between 0 and 1.  And
then, considering <https://sourceware.org/bugzilla/show_bug.cgi?id=15318>,
when that number is converted to integer for printing as hex, it
it is converted to zero [as in, (int)0.1 => 0].

The test just below that one expects the same value to match "1.*e-45":

     set decimal_vector ".uint128 = 0x00000001000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."

Which seems to confirm it.

I'm not really sure whether PR 15318 applies in this case, the Power
backend may be doing something else, but that's my guess.

I've changed to subject to see if it draws the attention of someone
who might know for sure.

Thanks,
Pedro Alves

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

* Re: Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints)
  2017-06-08 16:12   ` Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints) Pedro Alves
@ 2017-06-12 14:34     ` Tom Tromey
  2017-06-12 18:26       ` Pedro Alves
  0 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2017-06-12 14:34 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Tom Tromey, gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> I'd expect that it prints 0x0 because "0x00000001", when reinterpreted (note,
Pedro> not cast/converted) as the storage for a 32-bit float of whatever
Pedro> format AltiVec uses, gives you a real number between 0 and 1.  And
Pedro> then, considering <https://sourceware.org/bugzilla/show_bug.cgi?id=15318>,
Pedro> when that number is converted to integer for printing as hex, it
Pedro> it is converted to zero [as in, (int)0.1 => 0].

That doesn't seem too useful to me, but I've managed to preserve the behavior.

Here's an updated version of patch #2 from the series.
With this the series tests cleanly on the buildbot.

Tom

commit baa4f3cf4dae51541dcec33c8733aa2d5ee9e7c1
Author: Tom Tromey <tom@tromey.com>
Date:   Mon May 22 18:43:59 2017 -0600

    Simplify print_scalar_formatted
    
    This unifies the two switches in print_scalar_formatted, removing some
    now-redundant code.  Now scalar types are never converted to LONGEST,
    instead printing is done using print_*_chars, operating on the byte
    representation.
    
    ChangeLog
    2017-06-05  Tom Tromey  <tom@tromey.com>
    
            * printcmd.c (print_scalar_formatted): Unify the two switches.
            Don't convert scalars to LONGEST.
    
    2017-06-11  Tom Tromey  <tom@tromey.com>
    
            * gdb.arch/altivec-regs.exp: Expect decimal results for uint128.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 27d7162..a0dc332 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2017-06-05  Tom Tromey  <tom@tromey.com>
 
+	* printcmd.c (print_scalar_formatted): Unify the two switches.
+	Don't convert scalars to LONGEST.
+
+2017-06-05  Tom Tromey  <tom@tromey.com>
+
 	PR exp/16225:
 	* valprint.h (print_decimal_chars): Update.
 	* valprint.c (maybe_negate_by_bytes): New function.
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 84f41f5..152c2c6 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -356,47 +356,12 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 			int size, struct ui_file *stream)
 {
   struct gdbarch *gdbarch = get_type_arch (type);
-  LONGEST val_long = 0;
   unsigned int len = TYPE_LENGTH (type);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* String printing should go through val_print_scalar_formatted.  */
   gdb_assert (options->format != 's');
 
-  if (len > sizeof(LONGEST)
-      && (TYPE_CODE (type) == TYPE_CODE_INT
-	  || TYPE_CODE (type) == TYPE_CODE_ENUM))
-    {
-      switch (options->format)
-	{
-	case 'o':
-	  print_octal_chars (stream, valaddr, len, byte_order);
-	  return;
-	case 'u':
-	case 'd':
-	  print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
-			       byte_order);
-	  return;
-	case 't':
-	  print_binary_chars (stream, valaddr, len, byte_order, size > 0);
-	  return;
-	case 'x':
-	  print_hex_chars (stream, valaddr, len, byte_order, size > 0);
-	  return;
-	case 'z':
-	  print_hex_chars (stream, valaddr, len, byte_order, true);
-	  return;
-	case 'c':
-	  print_char_chars (stream, type, valaddr, len, byte_order);
-	  return;
-	default:
-	  break;
-	};
-    }
-
-  if (options->format != 'f')
-    val_long = unpack_long (type, valaddr);
-
   /* If the value is a pointer, and pointers and addresses are not the
      same, then at this point, the value's length (in target bytes) is
      gdbarch_addr_bit/TARGET_CHAR_BIT, not TYPE_LENGTH (type).  */
@@ -406,58 +371,93 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
   /* If we are printing it as unsigned, truncate it in case it is actually
      a negative signed value (e.g. "print/u (short)-1" should print 65535
      (if shorts are 16 bits) instead of 4294967295).  */
-  if (options->format != 'd' || TYPE_UNSIGNED (type))
+  if (options->format != 'c'
+      && (options->format != 'd' || TYPE_UNSIGNED (type)))
     {
-      if (len < sizeof (LONGEST))
-	val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1;
+      if (len < TYPE_LENGTH (type) && byte_order == BFD_ENDIAN_BIG)
+	valaddr += TYPE_LENGTH (type) - len;
     }
 
-  switch (options->format)
+  if (size != 0 && (options->format == 'x' || options->format == 't'))
     {
-    case 'x':
-      if (!size)
+      /* Truncate to fit.  */
+      unsigned newlen;
+      switch (size)
 	{
-	  /* No size specified, like in print.  Print varying # of digits.  */
-	  print_longest (stream, 'x', 1, val_long);
+	case 'b':
+	  newlen = 1;
+	  break;
+	case 'h':
+	  newlen = 2;
+	  break;
+	case 'w':
+	  newlen = 4;
+	  break;
+	case 'g':
+	  newlen = 8;
+	  break;
+	default:
+	  error (_("Undefined output size \"%c\"."), size);
 	}
-      else
-	switch (size)
-	  {
-	  case 'b':
-	  case 'h':
-	  case 'w':
-	  case 'g':
-	    print_longest (stream, size, 1, val_long);
-	    break;
-	  default:
-	    error (_("Undefined output size \"%c\"."), size);
-	  }
-      break;
+      if (newlen < len && byte_order == BFD_ENDIAN_BIG)
+	valaddr += len - newlen;
+      len = newlen;
+    }
 
-    case 'd':
-      print_longest (stream, 'd', 1, val_long);
-      break;
+  /* Historically gdb has printed floats by first casting them to a
+     long, and then printing the long.  PR cli/16242 suggests changing
+     this to using C-style hex float format.  */
+  std::vector<gdb_byte> converted_float_bytes;
+  if (TYPE_CODE (type) == TYPE_CODE_FLT
+      && (options->format == 'o'
+	  || options->format == 'x'
+	  || options->format == 't'
+	  || options->format == 'z'))
+    {
+      LONGEST val_long = unpack_long (type, valaddr);
+      converted_float_bytes.resize (TYPE_LENGTH (type));
+      store_signed_integer (converted_float_bytes.data (), TYPE_LENGTH (type),
+			    byte_order, val_long);
+      valaddr = converted_float_bytes.data ();
+    }
 
+  switch (options->format)
+    {
+    case 'o':
+      print_octal_chars (stream, valaddr, len, byte_order);
+      break;
     case 'u':
-      print_longest (stream, 'u', 0, val_long);
+      print_decimal_chars (stream, valaddr, len, false, byte_order);
       break;
-
-    case 'o':
-      print_longest (stream, 'o', 1, val_long);
+    case 0:
+    case 'd':
+      if (TYPE_CODE (type) != TYPE_CODE_FLT)
+	{
+	  print_decimal_chars (stream, valaddr, len, !TYPE_UNSIGNED (type),
+			       byte_order);
+	  break;
+	}
+      /* FALLTHROUGH */
+    case 'f':
+      type = float_type_from_length (type);
+      print_floating (valaddr, type, stream);
       break;
 
-    case 'a':
-      {
-	CORE_ADDR addr = unpack_pointer (type, valaddr);
-
-	print_address (gdbarch, addr, stream);
-      }
+    case 't':
+      print_binary_chars (stream, valaddr, len, byte_order, size > 0);
+      break;
+    case 'x':
+      print_hex_chars (stream, valaddr, len, byte_order, size > 0);
+      break;
+    case 'z':
+      print_hex_chars (stream, valaddr, len, byte_order, true);
       break;
-
     case 'c':
       {
 	struct value_print_options opts = *options;
 
+	LONGEST val_long = unpack_long (type, valaddr);
+
 	opts.format = 0;
 	if (TYPE_UNSIGNED (type))
 	  type = builtin_type (gdbarch)->builtin_true_unsigned_char;
@@ -468,66 +468,14 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
       }
       break;
 
-    case 'f':
-      type = float_type_from_length (type);
-      print_floating (valaddr, type, stream);
-      break;
-
-    case 0:
-      internal_error (__FILE__, __LINE__,
-		      _("failed internal consistency check"));
-
-    case 't':
-      /* Binary; 't' stands for "two".  */
+    case 'a':
       {
-	char bits[8 * (sizeof val_long) + 1];
-	char buf[8 * (sizeof val_long) + 32];
-	char *cp = bits;
-	int width;
-
-	if (!size)
-	  width = 8 * (sizeof val_long);
-	else
-	  switch (size)
-	    {
-	    case 'b':
-	      width = 8;
-	      break;
-	    case 'h':
-	      width = 16;
-	      break;
-	    case 'w':
-	      width = 32;
-	      break;
-	    case 'g':
-	      width = 64;
-	      break;
-	    default:
-	      error (_("Undefined output size \"%c\"."), size);
-	    }
+	CORE_ADDR addr = unpack_pointer (type, valaddr);
 
-	bits[width] = '\0';
-	while (width-- > 0)
-	  {
-	    bits[width] = (val_long & 1) ? '1' : '0';
-	    val_long >>= 1;
-	  }
-	if (!size)
-	  {
-	    while (*cp && *cp == '0')
-	      cp++;
-	    if (*cp == '\0')
-	      cp--;
-	  }
-	strncpy (buf, cp, sizeof (bits));
-	fputs_filtered (buf, stream);
+	print_address (gdbarch, addr, stream);
       }
       break;
 
-    case 'z':
-      print_hex_chars (stream, valaddr, len, byte_order, true);
-      break;
-
     default:
       error (_("Undefined output format \"%c\"."), options->format);
     }
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 8ddac54..854cbf0 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-11  Tom Tromey  <tom@tromey.com>
+
+	* gdb.arch/altivec-regs.exp: Expect decimal results for uint128.
+
 2017-06-05  Tom Tromey  <tom@tromey.com>
 
 	PR exp/16225:
diff --git a/gdb/testsuite/gdb.arch/altivec-regs.exp b/gdb/testsuite/gdb.arch/altivec-regs.exp
index cc679b2..b3b5aed 100644
--- a/gdb/testsuite/gdb.arch/altivec-regs.exp
+++ b/gdb/testsuite/gdb.arch/altivec-regs.exp
@@ -113,9 +113,9 @@ gdb_test "info reg vscr" "vscr.*0x1\t1" "info reg vscr"
 # the way gdb works.
 
 if {$endianness == "big"} {
-     set decimal_vector ".uint128 = 0x1000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."
+     set decimal_vector ".uint128 = 79228162532711081671548469249, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .0, 1, 0, 1, 0, 1, 0, 1., v16_int8 = .0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1.."
 } else {
-     set decimal_vector ".uint128 = 0x1000000010000000100000001, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.."
+     set decimal_vector ".uint128 = 79228162532711081671548469249, v4_float = .1.*e-45, 1.*e-45, 1.*e-45, 1.*e-45., v4_int32 = .1, 1, 1, 1., v8_int16 = .1, 0, 1, 0, 1, 0, 1, 0., v16_int8 = .1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.."
 }
 
 for {set i 0} {$i < 32} {incr i 1} {

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

* Re: Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints)
  2017-06-12 14:34     ` Tom Tromey
@ 2017-06-12 18:26       ` Pedro Alves
  0 siblings, 0 replies; 16+ messages in thread
From: Pedro Alves @ 2017-06-12 18:26 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 06/12/2017 03:34 PM, Tom Tromey wrote:

> Here's an updated version of patch #2 from the series.
> With this the series tests cleanly on the buildbot.

Thanks.  Looks good.

Thanks,
Pedro Alves

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

end of thread, other threads:[~2017-06-12 18:26 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-02 19:36 [RFA 0/5] improve printing of 128 bit ints Tom Tromey
2017-06-02 19:37 ` [RFA 3/5] Simplify print_scalar_formatted Tom Tromey
2017-06-05 17:27   ` Pedro Alves
2017-06-02 19:37 ` [RFA 4/5] Remove val_print_type_code_int Tom Tromey
2017-06-02 19:37 ` [RFA 5/5] Add some 128-bit integer tests Tom Tromey
2017-06-05 17:33   ` Pedro Alves
2017-06-02 19:37 ` [RFA 1/5] Don't always zero pad in print_*_chars Tom Tromey
2017-06-05 17:27   ` Pedro Alves
2017-06-02 19:37 ` [RFA 2/5] Let print_decimal_chars handle signed values Tom Tromey
2017-06-05 17:22   ` Pedro Alves
2017-06-05 19:38     ` Tom Tromey
2017-06-05 17:35 ` [RFA 0/5] improve printing of 128 bit ints Pedro Alves
2017-06-08 14:32 ` Tom Tromey
2017-06-08 16:12   ` Power/AltiVec question (Re: [RFA 0/5] improve printing of 128 bit ints) Pedro Alves
2017-06-12 14:34     ` Tom Tromey
2017-06-12 18:26       ` Pedro Alves

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