2012-03-01 Pedro Alves <palves@redhat.com>
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
index 826746667ed6c92f0733301c00b6c30390e85e80..27f3c5b6050c2685663c8ab9564084056279bef2 100644 (file)
@@ -1,8 +1,7 @@
 /* Intel 387 floating point stuff.
 
-   Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1988-1989, 1991-1994, 1998-2005, 2007-2012 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -114,13 +113,21 @@ print_i387_ext (struct gdbarch *gdbarch,
     fputs_filtered (" Unsupported", file);
 }
 
-/* Print the status word STATUS.  */
+/* Print the status word STATUS.  If STATUS_P is false, then STATUS
+   was unavailable.  */
 
 static void
-print_i387_status_word (unsigned int status, struct ui_file *file)
+print_i387_status_word (int status_p,
+                       unsigned int status, struct ui_file *file)
 {
-  fprintf_filtered (file, "Status Word:         %s",
-                   hex_string_custom (status, 4));
+  fprintf_filtered (file, "Status Word:         ");
+  if (!status_p)
+    {
+      fprintf_filtered (file, "%s\n", _("<unavailable>"));
+      return;
+    }
+
+  fprintf_filtered (file, "%s", hex_string_custom (status, 4));
   fputs_filtered ("  ", file);
   fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : "  ");
   fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : "  ");
@@ -144,13 +151,21 @@ print_i387_status_word (unsigned int status, struct ui_file *file)
                    "                       TOP: %d\n", ((status >> 11) & 7));
 }
 
-/* Print the control word CONTROL.  */
+/* Print the control word CONTROL.  If CONTROL_P is false, then
+   CONTROL was unavailable.  */
 
 static void
-print_i387_control_word (unsigned int control, struct ui_file *file)
+print_i387_control_word (int control_p,
+                        unsigned int control, struct ui_file *file)
 {
-  fprintf_filtered (file, "Control Word:        %s",
-                   hex_string_custom (control, 4));
+  fprintf_filtered (file, "Control Word:        ");
+  if (!control_p)
+    {
+      fprintf_filtered (file, "%s\n", _("<unavailable>"));
+      return;
+    }
+
+  fprintf_filtered (file, "%s", hex_string_custom (control, 4));
   fputs_filtered ("  ", file);
   fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : "  ");
   fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : "  ");
@@ -206,81 +221,119 @@ i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
 {
   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 = get_frame_register_unsigned (frame, I387_FCTRL_REGNUM (tdep));
-  fstat = get_frame_register_unsigned (frame, I387_FSTAT_REGNUM (tdep));
-  ftag = get_frame_register_unsigned (frame, I387_FTAG_REGNUM (tdep));
-  fiseg = get_frame_register_unsigned (frame, I387_FISEG_REGNUM (tdep));
-  fioff = get_frame_register_unsigned (frame, I387_FIOFF_REGNUM (tdep));
-  foseg = get_frame_register_unsigned (frame, I387_FOSEG_REGNUM (tdep));
-  fooff = get_frame_register_unsigned (frame, I387_FOOFF_REGNUM (tdep));
-  fop = get_frame_register_unsigned (frame, I387_FOP_REGNUM (tdep));
+  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);
 
-  top = ((fstat >> 11) & 7);
+      for (fpreg = 7; fpreg >= 0; fpreg--)
+       {
+         struct value *regval;
+         int regnum;
+         int i;
+         int tag = -1;
 
-  for (fpreg = 7; fpreg >= 0; fpreg--)
-    {
-      gdb_byte raw[I386_MAX_REGISTER_SIZE];
-      int tag = (ftag >> (fpreg * 2)) & 3;
-      int i;
+         fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : "  ", fpreg);
 
-      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;
-       }
+             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);
 
-      get_frame_register (frame,
-                         (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep),
-                         raw);
+         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]);
+             fputs_filtered ("0x", file);
+             for (i = 9; i >= 0; i--)
+               fprintf_filtered (file, "%02x", raw[i]);
 
-      if (tag != 3)
-       print_i387_ext (gdbarch, raw, file);
+             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);
+       }
     }
 
   fputs_filtered ("\n", file);
-
-  print_i387_status_word (fstat, file);
-  print_i387_control_word (fctrl, file);
+  print_i387_status_word (fstat_p, fstat, file);
+  print_i387_control_word (fctrl_p, fctrl, file);
   fprintf_filtered (file, "Tag Word:            %s\n",
-                   hex_string_custom (ftag, 4));
+                   ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
   fprintf_filtered (file, "Instruction Pointer: %s:",
-                   hex_string_custom (fiseg, 2));
-  fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
+                   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:",
-                   hex_string_custom (foseg, 2));
-  fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
+                   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",
-                   hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
+                   fop_p
+                   ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
+                   : _("<unavailable>"));
 }
 \f
 
@@ -307,9 +360,10 @@ i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
    return its contents in TO.  */
 
-void
+int
 i387_register_to_value (struct frame_info *frame, int regnum,
-                       struct type *type, gdb_byte *to)
+                       struct type *type, gdb_byte *to,
+                       int *optimizedp, int *unavailablep)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   gdb_byte from[I386_MAX_REGISTER_SIZE];
@@ -321,12 +375,18 @@ i387_register_to_value (struct frame_info *frame, int regnum,
     {
       warning (_("Cannot convert floating-point register value "
               "to non-floating-point type."));
-      return;
+      *optimizedp = *unavailablep = 0;
+      return 0;
     }
 
   /* Convert to TYPE.  */
-  get_frame_register (frame, regnum, from);
+  if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
+                                from, optimizedp, unavailablep))
+    return 0;
+
   convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
+  *optimizedp = *unavailablep = 0;
+  return 1;
 }
 
 /* Write the contents FROM of a value of type TYPE into register
@@ -587,9 +647,9 @@ i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
 
                    if (val[0] & (1 << fpreg))
                      {
-                       int regnum = (fpreg + 8 - top) % 8 
-                                      + I387_ST0_REGNUM (tdep);
-                       tag = i387_tag (FXSAVE_ADDR (tdep, regs, regnum));
+                       int thisreg = (fpreg + 8 - top) % 8 
+                                      + I387_ST0_REGNUM (tdep);
+                       tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
                      }
                    else
                      tag = 3;          /* Empty */
@@ -788,7 +848,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       return;
 
     case all:
-      /* Hanle the upper YMM registers.  */
+      /* Handle the upper YMM registers.  */
       if ((tdep->xcr0 & I386_XSTATE_AVX))
        {
          if ((clear_bv & I386_XSTATE_AVX))
This page took 0.027554 seconds and 4 git commands to generate.