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.
This commit is contained in:
Tom Tromey 2017-05-22 18:43:59 -06:00
parent 4ac0cb1cf0
commit d9109c8080
4 changed files with 88 additions and 131 deletions

View File

@ -1,3 +1,8 @@
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>
PR exp/16225:

View File

@ -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;
}
if (size != 0 && (options->format == 'x' || options->format == 't'))
{
/* Truncate to fit. */
unsigned newlen;
switch (size)
{
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);
}
if (newlen < len && byte_order == BFD_ENDIAN_BIG)
valaddr += len - newlen;
len = newlen;
}
/* 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 'x':
if (!size)
{
/* No size specified, like in print. Print varying # of digits. */
print_longest (stream, 'x', 1, val_long);
}
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;
case 'd':
print_longest (stream, 'd', 1, val_long);
break;
case 'u':
print_longest (stream, 'u', 0, val_long);
break;
case 'o':
print_longest (stream, 'o', 1, val_long);
print_octal_chars (stream, valaddr, len, byte_order);
break;
case 'u':
print_decimal_chars (stream, valaddr, len, false, byte_order);
break;
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;
CORE_ADDR addr = unpack_pointer (type, valaddr);
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);
}
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);
}

View File

@ -1,3 +1,7 @@
2017-06-12 Tom Tromey <tom@tromey.com>
* gdb.arch/altivec-regs.exp: Expect decimal results for uint128.
2017-06-12 Tom Tromey <tom@tromey.com>
PR exp/16225:

View File

@ -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} {