sim: bfin: add exhaustive parallel-insn tests
[deliverable/binutils-gdb.git] / gdb / i387-tdep.c
index 450b8f21a1c2f2f606ae8b8687cef5d571c36cef..26e4e50d6372866b231799a34328f237d6719bf9 100644 (file)
@@ -113,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" : "  ");
@@ -143,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" : "  ");
@@ -205,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
 
@@ -725,6 +779,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   const gdb_byte *regs = xsave;
   int i;
   unsigned int clear_bv;
+  static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
   const gdb_byte *p;
   enum
     {
@@ -735,6 +790,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       all = x87 | sse | avxh
     } regclass;
 
+  gdb_assert (regs != NULL);
   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
   gdb_assert (tdep->num_xmm_regs > 0);
 
@@ -752,7 +808,7 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   else
     regclass = none;
 
-  if (regs != NULL && regclass != none)
+  if (regclass != none)
     {
       /* Get `xstat_bv'.  */
       const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
@@ -764,6 +820,15 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   else
     clear_bv = I386_XSTATE_AVX_MASK;
 
+  /* With the delayed xsave mechanism, in between the program
+     starting, and the program accessing the vector registers for the
+     first time, the register's values are invalid.  The kernel
+     initializes register states to zero when they are set the first
+     time in a program.  This means that from the user-space programs'
+     perspective, it's the same as if the registers have always been
+     zero from the start of the program.  Therefore, the debugger
+     should provide the same illusion to the user.  */
+
   switch (regclass)
     {
     case none:
@@ -771,26 +836,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
 
     case avxh:
       if ((clear_bv & I386_XSTATE_AVX))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, zero);
       else
-       p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            XSAVE_AVXH_ADDR (tdep, regs, regnum));
       return;
 
     case sse:
       if ((clear_bv & I386_XSTATE_SSE))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, zero);
       else
-       p = FXSAVE_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            FXSAVE_ADDR (tdep, regs, regnum));
       return;
 
     case x87:
       if ((clear_bv & I386_XSTATE_X87))
-       p = NULL;
+       regcache_raw_supply (regcache, regnum, zero);
       else
-       p = FXSAVE_ADDR (tdep, regs, regnum);
-      regcache_raw_supply (regcache, regnum, p);
+       regcache_raw_supply (regcache, regnum,
+                            FXSAVE_ADDR (tdep, regs, regnum));
       return;
 
     case all:
@@ -798,16 +863,19 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_AVX))
        {
          if ((clear_bv & I386_XSTATE_AVX))
-           p = NULL;
+           {
+             for (i = I387_YMM0H_REGNUM (tdep);
+                  i < I387_YMMENDH_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_YMM0H_REGNUM (tdep);
-              i < I387_YMMENDH_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = XSAVE_AVXH_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_YMM0H_REGNUM (tdep);
+                  i < I387_YMMENDH_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i,
+                                    XSAVE_AVXH_ADDR (tdep, regs, i));
            }
        }
 
@@ -815,16 +883,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_SSE))
        {
          if ((clear_bv & I386_XSTATE_SSE))
-           p = NULL;
+           {
+             for (i = I387_XMM0_REGNUM (tdep);
+                  i < I387_MXCSR_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_XMM0_REGNUM (tdep);
-              i < I387_MXCSR_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = FXSAVE_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_XMM0_REGNUM (tdep);
+                  i < I387_MXCSR_REGNUM (tdep); i++)
+               regcache_raw_supply (regcache, i,
+                                    FXSAVE_ADDR (tdep, regs, i));
            }
        }
 
@@ -832,16 +902,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       if ((tdep->xcr0 & I386_XSTATE_X87))
        {
          if ((clear_bv & I386_XSTATE_X87))
-           p = NULL;
+           {
+             for (i = I387_ST0_REGNUM (tdep);
+                  i < I387_FCTRL_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, zero);
+           }
          else
-           p = regs;
-
-         for (i = I387_ST0_REGNUM (tdep);
-              i < I387_FCTRL_REGNUM (tdep); i++)
            {
-             if (p != NULL)
-               p = FXSAVE_ADDR (tdep, regs, i);
-             regcache_raw_supply (regcache, i, p);
+             for (i = I387_ST0_REGNUM (tdep);
+                  i < I387_FCTRL_REGNUM (tdep);
+                  i++)
+               regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
            }
        }
       break;
@@ -851,12 +923,6 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
   for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
     if (regnum == -1 || regnum == i)
       {
-       if (regs == NULL)
-         {
-           regcache_raw_supply (regcache, i, NULL);
-           continue;
-         }
-
        /* Most of the FPU control registers occupy only 16 bits in
           the xsave extended state.  Give those a special treatment.  */
        if (i != I387_FIOFF_REGNUM (tdep)
@@ -907,10 +973,8 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
       }
 
   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
-    {
-      p = regs == NULL ? NULL : FXSAVE_MXCSR_ADDR (regs);
-      regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), p);
-    }
+    regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
+                        FXSAVE_MXCSR_ADDR (regs));
 }
 
 /* Similar to i387_collect_fxsave, but use XSAVE extended state.  */
This page took 0.028795 seconds and 4 git commands to generate.