+2017-11-06  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * 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  <uweigand@de.ibm.com>
 
        * Makefile.c (SFILES): Add target-float.c.
 
 #include "inferior.h"
 #include "gdbthread.h"
 #include "target.h"
+#include "target-float.h"
 
 namespace selftests {
 
 
              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
                {
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #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"
      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 ());
 }
 
 
 #include "user-regs.h"
 #include "valprint.h"
 #include "ax.h"
+#include "target-float.h"
 #include <algorithm>
 
 static const struct objfile_data *mips_pdr_data;
   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 *)
       /* 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,
       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 ());
        }
 
       /* 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,
 
 #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"
 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));
 }
 \f
 /* Stuff for maintaining a stack of types.  Currently just used by C, but
 
 #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"
   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);
 }
 
 
 #include "arch-utils.h"
 #include "regcache.h"
 #include "osabi.h"
+#include "target-float.h"
 #include "valprint.h"
 
 #include "elf-bfd.h"
                                        (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.  */
 
 #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 <ctype.h>
        {
        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;
 
   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");
+}
 
 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
 
 #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"
 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);
 }