+}
+
+/* Print out the i387 floating point state. Note that we ignore FRAME
+ in the code below. That's OK since floating-point registers are
+ never saved on the stack. */
+
+void
+i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
+ struct frame_info *frame, const char *args)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
+ ULONGEST fctrl;
+ int fctrl_p;
+ ULONGEST fstat;
+ int fstat_p;
+ ULONGEST ftag;
+ int ftag_p;
+ ULONGEST fiseg;
+ int fiseg_p;
+ ULONGEST fioff;
+ int fioff_p;
+ ULONGEST foseg;
+ int foseg_p;
+ ULONGEST fooff;
+ int fooff_p;
+ ULONGEST fop;
+ int fop_p;
+ int fpreg;
+ int fpreg_p;
+ int top;
+ int top_p;
+
+ gdb_assert (gdbarch == get_frame_arch (frame));
+
+ fctrl_p = read_frame_register_unsigned (frame,
+ I387_FCTRL_REGNUM (tdep), &fctrl);
+ fstat_p = read_frame_register_unsigned (frame,
+ I387_FSTAT_REGNUM (tdep), &fstat);
+ ftag_p = read_frame_register_unsigned (frame,
+ I387_FTAG_REGNUM (tdep), &ftag);
+ fiseg_p = read_frame_register_unsigned (frame,
+ I387_FISEG_REGNUM (tdep), &fiseg);
+ fioff_p = read_frame_register_unsigned (frame,
+ I387_FIOFF_REGNUM (tdep), &fioff);
+ foseg_p = read_frame_register_unsigned (frame,
+ I387_FOSEG_REGNUM (tdep), &foseg);
+ fooff_p = read_frame_register_unsigned (frame,
+ I387_FOOFF_REGNUM (tdep), &fooff);
+ fop_p = read_frame_register_unsigned (frame,
+ I387_FOP_REGNUM (tdep), &fop);
+
+ if (fstat_p)
+ {
+ top = ((fstat >> 11) & 7);
+
+ for (fpreg = 7; fpreg >= 0; fpreg--)
+ {
+ struct value *regval;
+ int regnum;
+ int i;
+ int tag = -1;
+
+ fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : " ", fpreg);
+
+ if (ftag_p)
+ {
+ tag = (ftag >> (fpreg * 2)) & 3;
+
+ switch (tag)
+ {
+ case 0:
+ fputs_filtered ("Valid ", file);
+ break;
+ case 1:
+ fputs_filtered ("Zero ", file);
+ break;
+ case 2:
+ fputs_filtered ("Special ", file);
+ break;
+ case 3:
+ fputs_filtered ("Empty ", file);
+ break;
+ }
+ }
+ else
+ fputs_filtered ("Unknown ", file);
+
+ regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep);
+ regval = get_frame_register_value (frame, regnum);
+
+ if (value_entirely_available (regval))
+ {
+ const char *raw = value_contents (regval);
+
+ fputs_filtered ("0x", file);
+ for (i = 9; i >= 0; i--)
+ fprintf_filtered (file, "%02x", raw[i]);
+
+ if (tag != -1 && tag != 3)
+ print_i387_ext (gdbarch, raw, file);
+ }
+ else
+ fprintf_filtered (file, "%s", _("<unavailable>"));
+
+ fputs_filtered ("\n", file);
+ }
+ }
+
+ fputs_filtered ("\n", file);
+ print_i387_status_word (fstat_p, fstat, file);
+ print_i387_control_word (fctrl_p, fctrl, file);
+ fprintf_filtered (file, "Tag Word: %s\n",
+ ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
+ fprintf_filtered (file, "Instruction Pointer: %s:",
+ fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>"));
+ fprintf_filtered (file, "%s\n",
+ fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>"));
+ fprintf_filtered (file, "Operand Pointer: %s:",
+ foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>"));
+ fprintf_filtered (file, "%s\n",
+ fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>"));
+ fprintf_filtered (file, "Opcode: %s\n",
+ fop_p
+ ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
+ : _("<unavailable>"));
+}
+\f
+
+/* Return nonzero if a value of type TYPE stored in register REGNUM
+ needs any special handling. */
+
+int
+i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
+{
+ if (i386_fp_regnum_p (gdbarch, regnum))
+ {
+ /* Floating point registers must be converted unless we are
+ accessing them in their hardware type. */
+ if (type == i387_ext_type (gdbarch))
+ return 0;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Read a value of type TYPE from register REGNUM in frame FRAME, and
+ return its contents in TO. */
+
+int
+i387_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, gdb_byte *to,
+ int *optimizedp, int *unavailablep)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ gdb_byte from[I386_MAX_REGISTER_SIZE];
+
+ gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
+
+ /* We only support floating-point values. */
+ if (TYPE_CODE (type) != TYPE_CODE_FLT)