aboutsummaryrefslogtreecommitdiff
path: root/gdb/printcmd.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2017-05-22 18:43:59 -0600
committerTom Tromey <tom@tromey.com>2017-06-12 15:04:57 -0600
commitd9109c8080ac0a2caeaa5f3d51e8a3b4891a68a8 (patch)
tree362a17ed87d4511432d07f78230be25a3341bab5 /gdb/printcmd.c
parent4ac0cb1cf04f105586746a6cce5b0f93d76f2b33 (diff)
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-12 Tom Tromey <tom@tromey.com> * printcmd.c (print_scalar_formatted): Unify the two switches. Don't convert scalars to LONGEST. 2017-06-12 Tom Tromey <tom@tromey.com> * gdb.arch/altivec-regs.exp: Expect decimal results for uint128.
Diffstat (limited to 'gdb/printcmd.c')
-rw-r--r--gdb/printcmd.c198
1 files changed, 73 insertions, 125 deletions
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 84f41f5b74..152c2c6d7c 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);
}