This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / gdb / i386v4-nat.c
index 10802cb730b8d88183b33711f799916b5351ab75..a2664233e1b6885241be352e3105f783d86cfa75 100644 (file)
@@ -31,6 +31,9 @@
 
 #include <sys/procfs.h>
 
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
 /*  The /proc interface divides the target machine's register set up into
    two different sets, the general register set (gregset) and the floating
    point register set (fpregset).  For each set, there is an ioctl to get
@@ -89,13 +92,13 @@ static int regmap[] =
 
 /* Prototypes for local functions */
 
-void fill_gregset PARAMS ((gregset_t *, int));
+void fill_gregset (gregset_t *, int);
 
-void supply_gregset PARAMS ((gregset_t *));
+void supply_gregset (gregset_t *);
 
-void supply_fpregset PARAMS ((fpregset_t *));
+void supply_fpregset (fpregset_t *);
 
-void fill_fpregset PARAMS ((fpregset_t *, int));
+void fill_fpregset (fpregset_t *, int);
 
 
 /*  FIXME:  These routine absolutely depends upon (NUM_REGS - NUM_FREGS)
@@ -142,17 +145,65 @@ fill_gregset (gregsetp, regno)
 
 #endif /* HAVE_GREGSET_T */
 
-#if defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T)
+#if defined (HAVE_FPREGSET_T)
 
 /*  Given a pointer to a floating point register set in /proc format
    (fpregset_t *), unpack the register contents and supply them as gdb's
    idea of the current floating point register values. */
 
+/* FIXME: Assumes that fpregsetp contains an i387 FSAVE area. */
+static const int freg_offset_map[] =
+{
+#if !defined(FPREGSET_FSAVE_OFFSET)
+#define FPREGSET_FSAVE_OFFSET  0
+#endif
+  FPREGSET_FSAVE_OFFSET + 28 + 0 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 1 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 2 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 3 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 4 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 5 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 6 * 10,
+  FPREGSET_FSAVE_OFFSET + 28 + 7 * 10,
+  FPREGSET_FSAVE_OFFSET + 0,
+  FPREGSET_FSAVE_OFFSET + 4,
+  FPREGSET_FSAVE_OFFSET + 8,
+  FPREGSET_FSAVE_OFFSET + 16,
+  FPREGSET_FSAVE_OFFSET + 12,
+  FPREGSET_FSAVE_OFFSET + 24,
+  FPREGSET_FSAVE_OFFSET + 20,
+  FPREGSET_FSAVE_OFFSET + 16
+};
+
 void
 supply_fpregset (fpregsetp)
      fpregset_t *fpregsetp;
 {
-  /* FIXME: see m68k-tdep.c for an example, for the m68k. */
+  int regi;
+  
+  if (NUM_FREGS == 0)
+    return;
+  for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
+    {
+      char tbuf[4];
+      ULONGEST tval;
+      char *from = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
+
+      if (regi == FCS_REGNUM)
+       {
+         tval = extract_unsigned_integer (from, 4) & 0xffff;
+         store_unsigned_integer (tbuf, 4, tval);
+         supply_register (regi, tbuf);
+       }
+      else if (regi == FOP_REGNUM)
+       {
+         tval = (extract_unsigned_integer (from, 4) >> 16) & ((1 << 11) - 1);
+         store_unsigned_integer (tbuf, 4, tval);
+         supply_register (regi, tbuf);
+       }
+      else
+       supply_register (regi, from);
+    }
 }
 
 /*  Given a pointer to a floating point register set in /proc format
@@ -165,9 +216,41 @@ fill_fpregset (fpregsetp, regno)
      fpregset_t *fpregsetp;
      int regno;
 {
-  /* FIXME: see m68k-tdep.c for an example, for the m68k. */
+  int regi;
+
+  if (NUM_FREGS == 0)
+    return;
+  for (regi = FP0_REGNUM; regi <= LAST_FPU_CTRL_REGNUM; regi++)
+    {
+      if ((regno == -1) || (regno == regi))
+       {
+         char *to = (char *) fpregsetp + freg_offset_map[regi - FP0_REGNUM];
+         char *from = (char *) &registers[REGISTER_BYTE (regi)];
+         ULONGEST valto;
+         ULONGEST valfrom;
+
+         if (regi == FCS_REGNUM)
+           {
+             valto = extract_unsigned_integer (to, 4);
+             valfrom = extract_unsigned_integer (from, 4);
+             valto = (valto & ~0xffff) | (valfrom & 0xffff);
+             store_unsigned_integer (to, 4, valto);
+           }
+         else if (regi == FOP_REGNUM)
+           {
+             valto = extract_unsigned_integer (to, 4);
+             valfrom = extract_unsigned_integer (from, 4);
+             valto = (valto & 0xffff) | ((valfrom & ((1 << 11) - 1)) << 16);
+             store_unsigned_integer (to, 4, valto);
+           }
+         else
+           {
+             memcpy (to, from, REGISTER_RAW_SIZE (regi));
+           }
+       }
+    }
 }
 
-#endif /* defined (FP0_REGNUM) && defined (HAVE_FPREGSET_T) */
+#endif /* defined (HAVE_FPREGSET_T) */
 
 #endif /* HAVE_SYS_PROCFS_H */
This page took 0.03109 seconds and 4 git commands to generate.