From f69fdf9bca80ac703890a51e124e408cbccbb743 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 6 Nov 2017 15:56:35 +0100 Subject: [PATCH] Target FP: Add string routines to target-float.{c,h} This adds target_float_to_string and target_float_from_string, which dispatch to the corresponding floatformat_ or decimal_ routines. Existing users of those routines are changed to use the new target-float routines instead (most of those places already handle both binary and decimal FP). In addition, two other places are changes to use target_float_from_string: - define_symbol in stabsread.c, when parsing a floating-point literal from stabs debug info - gdbarch-selftest.c when initializing a target format values (to eliminate use of DOUBLEST there). gdb/ChangeLog: 2017-11-06 Ulrich Weigand * target-float.c (target_float_to_string): New function. (target_float_from_string): New function. * target-float.h (target_float_to_string): Add prototype. (target_float_from_string): Add prototype. * valprint.c: Include "target-float.h". Do not include "doublest.h" and "dfp.h". (print_floating): Use target_float_to_string. * printcmd.c: Include "target-float.h". Do not include "dfp.h". (printf_floating): Use target_float_to_string. * i387-tdep.c: Include "target-float.h". Do not include "doublest.h". (print_i387_value): Use target_float_to_string. * mips-tdep.c: Include "target-float.h". (mips_print_fp_register): Use target_float_to_string. * sh64-tdep.c: Include "target-float.h". (sh64_do_fp_register): Use target_float_to_string. * parse.c: Include "target-float.h". Do not include "doublest.h" and "dfp.h". (parse_float): Use target_float_from_string. * stabsread.c: Include "target-float.h". Do not include "doublest.h". (define_symbol): Use target_float_from_string. * gdbarch-selftests.c: Include "target-float.h". (register_to_value_test): Use target_float_from_string. --- gdb/ChangeLog | 27 +++++++++++++++++++++++++++ gdb/gdbarch-selftests.c | 6 ++---- gdb/i387-tdep.c | 7 +++---- gdb/mips-tdep.c | 15 +++++++-------- gdb/parse.c | 11 ++--------- gdb/printcmd.c | 11 +++-------- gdb/sh64-tdep.c | 6 +++--- gdb/stabsread.c | 10 +++------- gdb/target-float.c | 37 +++++++++++++++++++++++++++++++++++++ gdb/target-float.h | 7 +++++++ gdb/valprint.c | 16 ++-------------- 11 files changed, 96 insertions(+), 57 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index df06c84e29..6ee299d07c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2017-11-06 Ulrich Weigand + + * target-float.c (target_float_to_string): New function. + (target_float_from_string): New function. + * target-float.h (target_float_to_string): Add prototype. + (target_float_from_string): Add prototype. + + * valprint.c: Include "target-float.h". Do not include + "doublest.h" and "dfp.h". + (print_floating): Use target_float_to_string. + * printcmd.c: Include "target-float.h". Do not include "dfp.h". + (printf_floating): Use target_float_to_string. + * i387-tdep.c: Include "target-float.h". Do not include "doublest.h". + (print_i387_value): Use target_float_to_string. + * mips-tdep.c: Include "target-float.h". + (mips_print_fp_register): Use target_float_to_string. + * sh64-tdep.c: Include "target-float.h". + (sh64_do_fp_register): Use target_float_to_string. + + * parse.c: Include "target-float.h". Do not include + "doublest.h" and "dfp.h". + (parse_float): Use target_float_from_string. + * stabsread.c: Include "target-float.h". Do not include "doublest.h". + (define_symbol): Use target_float_from_string. + * gdbarch-selftests.c: Include "target-float.h". + (register_to_value_test): Use target_float_from_string. + 2017-11-06 Ulrich Weigand * Makefile.c (SFILES): Add target-float.c. diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c index 58ed11287a..c748fcc660 100644 --- a/gdb/gdbarch-selftests.c +++ b/gdb/gdbarch-selftests.c @@ -24,6 +24,7 @@ #include "inferior.h" #include "gdbthread.h" #include "target.h" +#include "target-float.h" namespace selftests { @@ -178,11 +179,8 @@ register_to_value_test (struct gdbarch *gdbarch) if (TYPE_CODE (type) == TYPE_CODE_FLT) { - DOUBLEST d = 1.25; - /* Generate valid float format. */ - floatformat_from_doublest (floatformat_from_type (type), - &d, expected.data ()); + target_float_from_string (expected.data (), type, "1.25"); } else { diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index cfaccedb9b..8de0431f37 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -18,12 +18,12 @@ along with this program. If not, see . */ #include "defs.h" -#include "doublest.h" #include "frame.h" #include "gdbcore.h" #include "inferior.h" #include "language.h" #include "regcache.h" +#include "target-float.h" #include "value.h" #include "i386-tdep.h" @@ -40,9 +40,8 @@ print_i387_value (struct gdbarch *gdbarch, garbage, but we'd better print one too many. We need enough room to print the value, 1 position for the sign, 1 for the decimal point, 19 for the digits and 6 for the exponent adds up to 27. */ - const struct floatformat *fmt - = floatformat_from_type (i387_ext_type (gdbarch)); - std::string str = floatformat_to_string (fmt, raw, " %-+27.19g"); + const struct type *type = i387_ext_type (gdbarch); + std::string str = target_float_to_string (raw, type, " %-+27.19g"); fprintf_filtered (file, "%s", str.c_str ()); } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 20bd5d37bb..039b541f9d 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -55,6 +55,7 @@ #include "user-regs.h" #include "valprint.h" #include "ax.h" +#include "target-float.h" #include static const struct objfile_data *mips_pdr_data; @@ -6258,10 +6259,8 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, gdb_byte *raw_buffer; std::string flt_str, dbl_str; - const struct floatformat *flt_fmt - = floatformat_from_type (builtin_type (gdbarch)->builtin_float); - const struct floatformat *dbl_fmt - = floatformat_from_type (builtin_type (gdbarch)->builtin_double); + const struct type *flt_type = builtin_type (gdbarch)->builtin_float; + const struct type *dbl_type = builtin_type (gdbarch)->builtin_double; raw_buffer = ((gdb_byte *) @@ -6279,7 +6278,7 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, /* 4-byte registers: Print hex and floating. Also print even numbered registers as doubles. */ mips_read_fp_register_single (frame, regnum, raw_buffer); - flt_str = floatformat_to_string (flt_fmt, raw_buffer, "%-17.9g"); + flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g"); get_formatted_print_options (&opts, 'x'); print_scalar_formatted (raw_buffer, @@ -6291,7 +6290,7 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0) { mips_read_fp_register_double (frame, regnum, raw_buffer); - dbl_str = floatformat_to_string (dbl_fmt, raw_buffer, "%-24.17g"); + dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g"); fprintf_filtered (file, " dbl: %s", dbl_str.c_str ()); } @@ -6302,10 +6301,10 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, /* Eight byte registers: print each one as hex, float and double. */ mips_read_fp_register_single (frame, regnum, raw_buffer); - flt_str = floatformat_to_string (flt_fmt, raw_buffer, "%-17.9g"); + flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g"); mips_read_fp_register_double (frame, regnum, raw_buffer); - dbl_str = floatformat_to_string (dbl_fmt, raw_buffer, "%-24.17g"); + dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g"); get_formatted_print_options (&opts, 'x'); print_scalar_formatted (raw_buffer, diff --git a/gdb/parse.c b/gdb/parse.c index a4058c377b..506efa38fb 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -44,8 +44,7 @@ #include "gdbcmd.h" #include "symfile.h" /* for overlay functions */ #include "inferior.h" -#include "doublest.h" -#include "dfp.h" +#include "target-float.h" #include "block.h" #include "source.h" #include "objfiles.h" @@ -1338,13 +1337,7 @@ bool parse_float (const char *p, int len, const struct type *type, gdb_byte *data) { - if (TYPE_CODE (type) == TYPE_CODE_FLT) - return floatformat_from_string (floatformat_from_type (type), - data, std::string (p, len)); - else - return decimal_from_string (data, TYPE_LENGTH (type), - gdbarch_byte_order (get_type_arch (type)), - std::string (p, len)); + return target_float_from_string (data, type, std::string (p, len)); } /* Stuff for maintaining a stack of types. Currently just used by C, but diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 4323475939..017c7bee07 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -38,7 +38,7 @@ #include "ui-out.h" #include "block.h" #include "disasm.h" -#include "dfp.h" +#include "target-float.h" #include "observer.h" #include "solist.h" #include "parser-defs.h" @@ -2360,13 +2360,8 @@ printf_floating (struct ui_file *stream, const char *format, value = value_cast (fmt_type, value); /* Convert the value to a string and print it. */ - std::string str; - if (TYPE_CODE (fmt_type) == TYPE_CODE_FLT) - str = floatformat_to_string (floatformat_from_type (fmt_type), - value_contents (value), format); - else - str = decimal_to_string (value_contents (value), - TYPE_LENGTH (fmt_type), byte_order, format); + std::string str + = target_float_to_string (value_contents (value), fmt_type, format); fputs_filtered (str.c_str (), stream); } diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c index e7fb7f377b..6d27909bed 100644 --- a/gdb/sh64-tdep.c +++ b/gdb/sh64-tdep.c @@ -35,6 +35,7 @@ #include "arch-utils.h" #include "regcache.h" #include "osabi.h" +#include "target-float.h" #include "valprint.h" #include "elf-bfd.h" @@ -1931,9 +1932,8 @@ sh64_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, (gdbarch, regnum)), file); /* Print the value. */ - const struct floatformat *fmt - = floatformat_from_type (builtin_type (gdbarch)->builtin_float); - std::string str = floatformat_to_string (fmt, raw_buffer, "%-10.9g"); + const struct type *flt_type = builtin_type (gdbarch)->builtin_float; + std::string str = target_float_to_string (raw_buffer, flt_type, "%-10.9g"); fprintf_filtered (file, "%s", str.c_str ()); /* Print the fp register as hex. */ diff --git a/gdb/stabsread.c b/gdb/stabsread.c index c51b3c7bf1..830138b1b3 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -41,7 +41,7 @@ #include "demangle.h" #include "gdb-demangle.h" #include "language.h" -#include "doublest.h" +#include "target-float.h" #include "cp-abi.h" #include "cp-support.h" #include @@ -798,19 +798,15 @@ define_symbol (CORE_ADDR valu, const char *string, int desc, int type, { case 'r': { - double d = atof (p); gdb_byte *dbl_valu; struct type *dbl_type; - /* FIXME-if-picky-about-floating-accuracy: Should be using - target arithmetic to get the value. real.c in GCC - probably has the necessary code. */ - dbl_type = objfile_type (objfile)->builtin_double; dbl_valu = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, TYPE_LENGTH (dbl_type)); - store_typed_floating (dbl_valu, dbl_type, d); + + target_float_from_string (dbl_valu, dbl_type, std::string (p)); SYMBOL_TYPE (sym) = dbl_type; SYMBOL_VALUE_BYTES (sym) = dbl_valu; diff --git a/gdb/target-float.c b/gdb/target-float.c index a082b9c567..e90cf03786 100644 --- a/gdb/target-float.c +++ b/gdb/target-float.c @@ -60,3 +60,40 @@ target_float_is_zero (const gdb_byte *addr, const struct type *type) gdb_assert_not_reached ("unexpected type code"); } +/* Convert the byte-stream ADDR, interpreted as floating-point type TYPE, + to a string, optionally using the print format FORMAT. */ +std::string +target_float_to_string (const gdb_byte *addr, const struct type *type, + const char *format) +{ + if (TYPE_CODE (type) == TYPE_CODE_FLT) + return floatformat_to_string (floatformat_from_type (type), addr, format); + + if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT) + return decimal_to_string (addr, TYPE_LENGTH (type), + gdbarch_byte_order (get_type_arch (type)), + format); + + gdb_assert_not_reached ("unexpected type code"); +} + +/* Parse string STRING into a target floating-number of type TYPE and + store it as byte-stream ADDR. Return whether parsing succeeded. */ +bool +target_float_from_string (gdb_byte *addr, const struct type *type, + const std::string &string) +{ + /* Ensure possible padding bytes in the target buffer are zeroed out. */ + memset (addr, 0, TYPE_LENGTH (type)); + + if (TYPE_CODE (type) == TYPE_CODE_FLT) + return floatformat_from_string (floatformat_from_type (type), addr, + string); + + if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT) + return decimal_from_string (addr, TYPE_LENGTH (type), + gdbarch_byte_order (get_type_arch (type)), + string); + + gdb_assert_not_reached ("unexpected type code"); +} diff --git a/gdb/target-float.h b/gdb/target-float.h index 43709f776a..317e98e332 100644 --- a/gdb/target-float.h +++ b/gdb/target-float.h @@ -25,4 +25,11 @@ extern bool target_float_is_valid (const gdb_byte *addr, extern bool target_float_is_zero (const gdb_byte *addr, const struct type *type); +extern std::string target_float_to_string (const gdb_byte *addr, + const struct type *type, + const char *format = nullptr); +extern bool target_float_from_string (gdb_byte *addr, + const struct type *type, + const std::string &string); + #endif diff --git a/gdb/valprint.c b/gdb/valprint.c index 9ea8d9ca5d..0cdb23f1b9 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -27,8 +27,7 @@ #include "language.h" #include "annotate.h" #include "valprint.h" -#include "doublest.h" -#include "dfp.h" +#include "target-float.h" #include "extension.h" #include "ada-lang.h" #include "gdb_obstack.h" @@ -1366,18 +1365,7 @@ void print_floating (const gdb_byte *valaddr, struct type *type, struct ui_file *stream) { - std::string str; - if (TYPE_CODE (type) == TYPE_CODE_FLT) - { - const struct floatformat *fmt = floatformat_from_type (type); - str = floatformat_to_string (fmt, valaddr); - } - else - { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - unsigned len = TYPE_LENGTH (type); - str = decimal_to_string (valaddr, len, byte_order); - } + std::string str = target_float_to_string (valaddr, type); fputs_filtered (str.c_str (), stream); } -- 2.34.1