* gdbint.texinfo: Add a cautionary note about macro use.
[deliverable/binutils-gdb.git] / gdb / i386v4-nat.c
index 10802cb730b8d88183b33711f799916b5351ab75..8de253d7329ec8558e027693f2c262b3dcd6d6d8 100644 (file)
@@ -1,5 +1,6 @@
 /* Native-dependent code for SVR4 Unix running on i386's, for GDB.
-   Copyright 1988, 1989, 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
+   Copyright 1988, 1989, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +22,7 @@
 #include "defs.h"
 #include "value.h"
 #include "inferior.h"
+#include "regcache.h"
 
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
@@ -31,6 +33,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 +94,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)
@@ -109,8 +114,7 @@ void fill_fpregset PARAMS ((fpregset_t *, int));
    register values. */
 
 void
-supply_gregset (gregsetp)
-     gregset_t *gregsetp;
+supply_gregset (gregset_t *gregsetp)
 {
   register int regi;
   register greg_t *regp = (greg_t *) gregsetp;
@@ -123,9 +127,7 @@ supply_gregset (gregsetp)
 }
 
 void
-fill_gregset (gregsetp, regno)
-     gregset_t *gregsetp;
-     int regno;
+fill_gregset (gregset_t *gregsetp, int regno)
 {
   int regi;
   register greg_t *regp = (greg_t *) gregsetp;
@@ -142,17 +144,64 @@ 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;
+supply_fpregset (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
@@ -161,13 +210,43 @@ supply_fpregset (fpregsetp)
    them all. */
 
 void
-fill_fpregset (fpregsetp, regno)
-     fpregset_t *fpregsetp;
-     int regno;
+fill_fpregset (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.027531 seconds and 4 git commands to generate.