This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MIPS: Handle the DSP registers


On Mon, 17 Dec 2007, Daniel Jacobowitz wrote:

> >  In particular, ptrace() calls may return a failure when called on a 
> > system that does not support the ASE.  In such a case the registers are 
> > marked as unavailable in the cache which has the effect of them being 
> > hardwired to zero (I have a patch in the queue that would mark them 
> > specially in the output; I will submit it later).
> 
> We have an even better way to handle this, nowadays.  Take a look at
> arm-linux-nat.c:arm_linux_read_description.  This lets the registers
> be completely hidden when they are not available.

 Thanks for the hint -- I have taken it into account.

> > +/* Names of Linux registers.  */
> > +static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
> > +  "sr", "lo", "hi", "bad", "cause", "pc",
> > +  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
> > +  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
> > +  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
> > +  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
> > +  "fsr", "fir", "hi1", "lo1", "hi2", "lo2", "hi3", "lo3",
> > +  "dspctl",
> > +};
> 
> If you're using a target description wherever you support these
> registers, then you shouldn't need another copy of them here.

 Well, I would have thought so, but before "run" is used 
mips_gdbarch_init() is called with the target description being 
unavailable.  I feel a bit uneasy about some default target configuration 
being selected in this case.

> > @@ -5270,11 +5341,11 @@
> >  
> >  
> >        valid_p &= tdesc_numbered_register (feature, tdesc_data,
> > -					  MIPS_EMBED_LO_REGNUM, "lo");
> > +					  mips_regnum.lo, "lo");
> 
> I went to a bit of trouble to be able to use constants here, please
> don't go back the other direction.  When all the raw registers use
> constant numbering, it's much easier to manage the GDB backend.

 The offsets are different for Linux and bare-iron; there is no way to go 
back as far as I can tell.  Suggestions are welcome.

> > +      if (mips_regnum.dspacc >= 0)
> > +	{
> > +	  feature = tdesc_find_feature (info.target_desc,
> > +					"org.gnu.gdb.mips.dsp");
> 
> Please add this to the manual section describing MIPS target features.

 Certainly.

> > Index: binutils-quilt/src/gdb/inf-ptrace.c
> > ===================================================================
> > --- binutils-quilt.orig/src/gdb/inf-ptrace.c	2007-12-07 15:08:21.000000000 +0000
> > +++ binutils-quilt/src/gdb/inf-ptrace.c	2007-12-07 15:13:02.000000000 +0000
> 
> Using a target description that accurately describes the target should
> eliminate the need for these.

 Done.

> > Index: binutils-quilt/src/gdb/testsuite/gdb.xml/tdesc-regs.exp
> > ===================================================================
> > --- binutils-quilt.orig/src/gdb/testsuite/gdb.xml/tdesc-regs.exp	2007-12-07 17:01:40.000000000 +0000
> > +++ binutils-quilt/src/gdb/testsuite/gdb.xml/tdesc-regs.exp	2007-12-07 17:02:17.000000000 +0000
> > @@ -33,7 +33,7 @@
> >          set core-regs {arm-core.xml}
> >      }
> >      "mips*-*-*" {
> > -	set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml}
> > +	set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml mips-dsp.xml}
> >      }
> >      "powerpc*-*-*" {
> >  	set regdir "rs6000/"
> 
> No need for this, since a MIPS target without the DSP registers is
> still valid.

 Removed now.

 Thanks for you review.  Here is a new version.

gdb:/
2008-03-19  Maciej W. Rozycki  <macro@mips.com>
            Chris Dearman  <chris@mips.com>

	* features/mips-dsp.xml: New file for DSP ASE registers.
	* features/mips64-dsp.xml: Likewise.
	* features/mips-linux.xml: Specify "regnum" for "restart"
	explicitly.
	* features/mips64-linux.xml: Likewise.
	* features/mips-dsp-linux.xml: New file for a DSP-enabled
	target.
	* features/mips64-dsp-linux.xml: Likewise.
	* features/mips-linux.c: Regenerate.
	* features/mips64-linux.c: Regenerate.
	* features/mips-dsp-linux.c: New generated file.
	* features/mips64-dsp-linux.c: Likewise.
	* mips-linux-nat.c: Include the new DSP target descriptions.
	(super_fetch_registers): Mark static.
	(super_store_registers): Likewise.
	(mips_linux_register_addr): Handle DSP registers.
	(mips64_linux_register_addr): Likewise.
	(mips64_linux_regsets_fetch_registers): Likewise.
	(mips64_linux_regsets_store_registers): Likewise.
	(mips_linux_read_description): Check for the presence of the
	DSP ASE and select the target description accordingly.
	(_initialize_mips_linux_nat): Initialize the new DSP target
	descriptions.
	* mips-linux-tdep.c (supply_gregset, mips64_supply_gregset):
	Remove padding as the register array does not use the layout
	defined for embedded targets anymore.
	* mips-linux-tdep.h (DSP_BASE, DSP_CONTROL): New macros.
	* mips-tdep.c (NUM_MIPS_PROCESSOR_REGS): Set from
	MIPS_LAST_EMBED_REGNUM.
	(mips_generic_reg_names): Remove trailing null strings.
	(mips_tx39_reg_names): Likewise.
	(mips_linux_reg_names): New array of register names for Linux
	targets.
	(mips_register_name): Check for a null pointer in
	mips_processor_reg_names and return an empty string.
	(mips_stab_reg_to_regnum): Handle the DSP accumulators.
	(mips_dwarf_dwarf2_ecoff_reg_to_regnum): Likewise.
	(mips_gdbarch_init): Likewise.  Handle the DSP ASE control
	register.  Initialize internal register indices for Linux.  Use
	MIPS_LAST_EMBED_REGNUM as appropriate.
	* mips-tdep.h (struct mips_regnum): Add dspacc/dspctl offsets.
	(MIPS_EMBED_CP2_REGNUM): Offset to CP2 registers.
	(MIPS_EMBED_DSPACC_REGNUM): Offset to DSP accumulator registers.
	(MIPS_EMBED_DSPCTL_REGNUM): Offset to DSP control registers.
	(MIPS_LAST_EMBED_REGNUM): Update accordingly.
	(MIPS_EMBED_NUM_REGS): New value to make sure that an even
	number of registers is used.
	* regcache.c (regcache_invalidate): Allow for an arbitrary
	setting of the cache state and replace with a wrapper to call
	the original function renamed to...
	(regcache_set_valid_p): ... this.
	* regcache.h (regcache_set_valid_p): New prototype.
	* Makefile.in (mips_dsp_linux_c): New variable.
	(mips64_dsp_linux_c): Likewise.
	(mips-linux-nat.o): Depend on $(mips_dsp_linux_c) and
	$(mips64_dsp_linux_c).
	* features/Makefile (WHICH): Add "mips-dsp-linux" and
	"mips64-dsp-linux".
	(mips-dsp-linux-expedite): New variable.
	(mips64-dsp-linux-expedite): Likewise.

gdb/doc/:
2008-03-19  Maciej W. Rozycki  <macro@mips.com>

	* gdb.texinfo (MIPS Features): Document org.gnu.gdb.mips.dsp.

  Maciej

14607.diff
Index: binutils-quilt/src/gdb/mips-linux-nat.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-linux-nat.c	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-nat.c	2008-03-18 16:57:45.000000000 +0000
@@ -19,6 +19,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "gdb_assert.h"
+#include "gdb_stdint.h"
 #include "inferior.h"
 #include "mips-tdep.h"
 #include "target.h"
@@ -34,7 +36,9 @@
 #include <sys/ptrace.h>
 
 #include "features/mips-linux.c"
+#include "features/mips-dsp-linux.c"
 #include "features/mips64-linux.c"
+#include "features/mips64-dsp-linux.c"
 
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
@@ -47,8 +51,8 @@
 /* Saved function pointers to fetch and store a single register using
    PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
 
-void (*super_fetch_registers) (struct regcache *, int);
-void (*super_store_registers) (struct regcache *, int);
+static void (*super_fetch_registers) (struct regcache *, int);
+static void (*super_store_registers) (struct regcache *, int);
 
 /* Map gdb internal register number to ptrace ``address''.
    These ``addresses'' are normally defined in <asm/ptrace.h>. 
@@ -84,6 +88,13 @@
     regaddr = FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
+  else if (mips_regnum (gdbarch)->dspacc != 0
+	   && regno >= mips_regnum (gdbarch)->dspacc
+	   && regno < mips_regnum (gdbarch)->dspacc + 6)
+    regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
+  else if (mips_regnum (gdbarch)->dspctl != 0
+	   && regno == mips_regnum (gdbarch)->dspctl)
+    regaddr = DSP_CONTROL;
   else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
     regaddr = 0;
   else
@@ -119,6 +130,13 @@
     regaddr = MIPS64_FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
+  else if (mips_regnum (gdbarch)->dspacc != 0
+	   && regno >= mips_regnum (gdbarch)->dspacc
+	   && regno < mips_regnum (gdbarch)->dspacc + 6)
+    regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
+  else if (mips_regnum (gdbarch)->dspctl != 0
+	   && regno == mips_regnum (gdbarch)->dspctl)
+    regaddr = DSP_CONTROL;
   else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
     regaddr = 0;
   else
@@ -192,7 +210,8 @@
 mips64_linux_regsets_fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int is_fp;
+  int is_fp, is_dsp;
+  int regi;
   int tid;
 
   if (regno >= mips_regnum (gdbarch)->fp0
@@ -205,11 +224,22 @@
   else
     is_fp = 0;
 
+  /* DSP registers are optional and not a part of any set.  */
+  if (mips_regnum (gdbarch)->dspacc != 0
+      && regno >= mips_regnum (gdbarch)->dspacc
+      && regno < mips_regnum (gdbarch)->dspacc + 6)
+    is_dsp = 1;
+  else if (mips_regnum (gdbarch)->dspctl != 0
+	   && regno == mips_regnum (gdbarch)->dspctl)
+    is_dsp = 1;
+  else
+    is_dsp = 0;
+
   tid = ptid_get_lwp (inferior_ptid);
   if (tid == 0)
     tid = ptid_get_pid (inferior_ptid);
 
-  if (regno == -1 || !is_fp)
+  if (regno == -1 || (!is_fp && !is_dsp))
     {
       mips64_elf_gregset_t regs;
 
@@ -245,16 +275,30 @@
       mips64_supply_fpregset (regcache,
 			      (const mips64_elf_fpregset_t *) &fp_regs);
     }
+
+  if (is_dsp)
+    super_fetch_registers (regcache, regno);
+  else if (regno == -1)
+    {
+      if (mips_regnum (gdbarch)->dspacc != 0)
+	for (regi = mips_regnum (gdbarch)->dspacc;
+	     regi < mips_regnum (gdbarch)->dspacc + 6;
+	     regi++)
+	  super_fetch_registers (regcache, regi);
+      if (mips_regnum (gdbarch)->dspctl != 0)
+	super_fetch_registers (regcache, mips_regnum (gdbarch)->dspctl);
+    }
 }
 
 /* Store REGNO (or all registers if REGNO == -1) to the target
    using PTRACE_SETREGS et al.  */
 
 static void
-mips64_linux_regsets_store_registers (const struct regcache *regcache, int regno)
+mips64_linux_regsets_store_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int is_fp;
+  int is_fp, is_dsp;
+  int regi;
   int tid;
 
   if (regno >= mips_regnum (gdbarch)->fp0
@@ -267,11 +311,22 @@
   else
     is_fp = 0;
 
+  /* DSP registers are optional and not a part of any set.  */
+  if (mips_regnum (gdbarch)->dspacc != 0
+      && regno >= mips_regnum (gdbarch)->dspacc
+      && regno < mips_regnum (gdbarch)->dspacc + 6)
+    is_dsp = 1;
+  else if (mips_regnum (gdbarch)->dspctl != 0
+	   && regno == mips_regnum (gdbarch)->dspctl)
+    is_dsp = 1;
+  else
+    is_dsp = 0;
+
   tid = ptid_get_lwp (inferior_ptid);
   if (tid == 0)
     tid = ptid_get_pid (inferior_ptid);
 
-  if (regno == -1 || !is_fp)
+  if (regno == -1 || (!is_fp && !is_dsp))
     {
       mips64_elf_gregset_t regs;
 
@@ -298,6 +353,19 @@
 		  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
 	perror_with_name (_("Couldn't set FP registers"));
     }
+
+  if (is_dsp)
+    super_store_registers (regcache, regno);
+  else if (regno == -1)
+    {
+      if (mips_regnum (gdbarch)->dspacc != 0)
+	for (regi = mips_regnum (gdbarch)->dspacc;
+	     regi < mips_regnum (gdbarch)->dspacc + 6;
+	     regi++)
+	  super_store_registers (regcache, regi);
+      if (mips_regnum (gdbarch)->dspctl != 0)
+	super_store_registers (regcache, mips_regnum (gdbarch)->dspctl);
+    }
 }
 
 /* Fetch REGNO (or all registers if REGNO == -1) from the target
@@ -347,12 +415,29 @@
 static const struct target_desc *
 mips_linux_read_description (struct target_ops *ops)
 {
+  struct gdbarch *gdbarch = current_gdbarch;
+  CORE_ADDR addr;
+  int has_dsp;
+  int tid;
+
+  addr = mips_linux_register_u_offset (gdbarch,
+				       mips_regnum (gdbarch)->dspctl, 0);
+  gdb_assert (addr != (CORE_ADDR) -1);
+
+  tid = ptid_get_lwp (inferior_ptid);
+  if (tid == 0)
+    tid = ptid_get_pid (inferior_ptid);
+
+  errno = 0;
+  ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) (uintptr_t) addr, 0);
+  has_dsp = (errno == 0);
+
   /* Report that target registers are a size we know for sure
      that we can get from ptrace.  */
-  if (_MIPS_SIM == _ABIO32)
-    return tdesc_mips_linux;
+  if (mips_abi_regsize (gdbarch) == 8)
+    return has_dsp ? tdesc_mips64_dsp_linux : tdesc_mips64_linux;
   else
-    return tdesc_mips64_linux;
+    return has_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
 }
 
 void _initialize_mips_linux_nat (void);
@@ -374,5 +459,7 @@
 
   /* Initialize the standard target descriptions.  */
   initialize_tdesc_mips_linux ();
+  initialize_tdesc_mips_dsp_linux ();
   initialize_tdesc_mips64_linux ();
+  initialize_tdesc_mips64_dsp_linux ();
 }
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.c	2008-03-18 16:57:45.000000000 +0000
@@ -436,7 +436,7 @@
    are listed in the following tables.  */
 
 enum
-{ NUM_MIPS_PROCESSOR_REGS = (90 - 32) };
+{ NUM_MIPS_PROCESSOR_REGS = (MIPS_LAST_EMBED_REGNUM + 1 - 32) };
 
 /* Generic MIPS.  */
 
@@ -446,9 +446,7 @@
   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
-  "fsr", "fir", "" /*"fp" */ , "",
-  "", "", "", "", "", "", "", "",
-  "", "", "", "", "", "", "", "",
+  "fsr", "fir",
 };
 
 /* Names of IDT R3041 registers.  */
@@ -474,7 +472,7 @@
   "", "", "", "", "", "", "", "",
   "", "", "", "",
   "", "", "", "", "", "", "", "",
-  "", "", "config", "cache", "debug", "depc", "epc", ""
+  "", "", "config", "cache", "debug", "depc", "epc",
 };
 
 /* Names of IRIX registers.  */
@@ -486,6 +484,17 @@
   "pc", "cause", "bad", "hi", "lo", "fsr", "fir"
 };
 
+/* Names of Linux registers.  */
+static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
+  "sr", "lo", "hi", "bad", "cause", "pc",
+  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+  "fsr", "fir", "hi1", "lo1", "hi2", "lo2", "hi3", "lo3",
+  "dspctl",
+};
+
 
 /* Return the name of the register corresponding to REGNO.  */
 static const char *
@@ -531,7 +540,9 @@
   else if (32 <= rawnum && rawnum < gdbarch_num_regs (gdbarch))
     {
       gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
-      return tdep->mips_processor_reg_names[rawnum - 32];
+      if (tdep->mips_processor_reg_names[rawnum - 32])
+	return tdep->mips_processor_reg_names[rawnum - 32];
+      return "";
     }
   else
     internal_error (__FILE__, __LINE__,
@@ -5085,6 +5096,8 @@
     regnum = mips_regnum (gdbarch)->hi;
   else if (num == 71)
     regnum = mips_regnum (gdbarch)->lo;
+  else if (num >= 72 && num < 78)
+    regnum = num + mips_regnum (gdbarch)->dspacc - 72;
   else
     /* This will hopefully (eventually) provoke a warning.  Should
        we be calling complaint() here?  */
@@ -5108,6 +5121,8 @@
     regnum = mips_regnum (gdbarch)->hi;
   else if (num == 65)
     regnum = mips_regnum (gdbarch)->lo;
+  else if (num >= 66 && num < 72)
+    regnum = num + mips_regnum (gdbarch)->dspacc - 66;
   else
     /* This will hopefully (eventually) provoke a warning.  Should we
        be calling complaint() here?  */
@@ -5241,10 +5256,66 @@
   struct gdbarch_tdep *tdep;
   int elf_flags;
   enum mips_abi mips_abi, found_abi, wanted_abi;
-  int i, num_regs;
+  int i, num_regs, dsp_space;
   enum mips_fpu_type fpu_type;
   struct tdesc_arch_data *tdesc_data = NULL;
   int elf_fpu_type = 0;
+  const char **reg_names;
+  struct mips_regnum mips_regnum, *regnum;
+
+  /* Fill in the OS dependant register numbers and names.  */
+  if (info.osabi == GDB_OSABI_IRIX)
+    {
+      mips_regnum.fp0 = 32;
+      mips_regnum.pc = 64;
+      mips_regnum.cause = 65;
+      mips_regnum.badvaddr = 66;
+      mips_regnum.hi = 67;
+      mips_regnum.lo = 68;
+      mips_regnum.fp_control_status = 69;
+      mips_regnum.fp_implementation_revision = 70;
+      mips_regnum.dspacc = 0;
+      mips_regnum.dspctl = 0;
+      dsp_space = 0;
+      num_regs = 71;
+      reg_names = mips_irix_reg_names;
+    }
+  else if (info.osabi == GDB_OSABI_LINUX)
+    {
+      mips_regnum.fp0 = 38;
+      mips_regnum.pc = 37;
+      mips_regnum.cause = 36;
+      mips_regnum.badvaddr = 35;
+      mips_regnum.hi = 34;
+      mips_regnum.lo = 33;
+      mips_regnum.fp_control_status = 70;
+      mips_regnum.fp_implementation_revision = 71;
+      mips_regnum.dspacc = 72;
+      mips_regnum.dspctl = 78;
+      dsp_space = 0;
+      num_regs = 79;
+      reg_names = mips_linux_reg_names;
+    }
+  else
+    {
+      mips_regnum.lo = MIPS_EMBED_LO_REGNUM;
+      mips_regnum.hi = MIPS_EMBED_HI_REGNUM;
+      mips_regnum.badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
+      mips_regnum.cause = MIPS_EMBED_CAUSE_REGNUM;
+      mips_regnum.pc = MIPS_EMBED_PC_REGNUM;
+      mips_regnum.fp0 = MIPS_EMBED_FP0_REGNUM;
+      mips_regnum.fp_control_status = 70;
+      mips_regnum.fp_implementation_revision = 71;
+      mips_regnum.dspacc = MIPS_EMBED_DSPACC_REGNUM;
+      mips_regnum.dspctl = MIPS_EMBED_DSPCTL_REGNUM;
+      dsp_space = 1;
+      num_regs = MIPS_LAST_EMBED_REGNUM + 1;
+      if (info.bfd_arch_info != NULL
+          && info.bfd_arch_info->mach == bfd_mach_mips3900)
+        reg_names = mips_tx39_reg_names;
+      else
+        reg_names = mips_generic_reg_names;
+    }
 
   /* Check any target description for validity.  */
   if (tdesc_has_registers (info.target_desc))
@@ -5279,11 +5350,11 @@
 
 
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_LO_REGNUM, "lo");
+					  mips_regnum.lo, "lo");
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_HI_REGNUM, "hi");
+					  mips_regnum.hi, "hi");
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_PC_REGNUM, "pc");
+					  mips_regnum.pc, "pc");
 
       if (!valid_p)
 	{
@@ -5301,12 +5372,11 @@
 
       valid_p = 1;
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_BADVADDR_REGNUM,
-					  "badvaddr");
+					  mips_regnum.badvaddr, "badvaddr");
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
 					  MIPS_PS_REGNUM, "status");
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_CAUSE_REGNUM, "cause");
+					  mips_regnum.cause, "cause");
 
       if (!valid_p)
 	{
@@ -5327,13 +5397,15 @@
       valid_p = 1;
       for (i = 0; i < 32; i++)
 	valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					    i + MIPS_EMBED_FP0_REGNUM,
-					    mips_fprs[i]);
+					    i + mips_regnum.fp0, mips_fprs[i]);
 
       valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_FP0_REGNUM + 32, "fcsr");
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  MIPS_EMBED_FP0_REGNUM + 33, "fir");
+					  mips_regnum.fp_control_status,
+					  "fcsr");
+      valid_p
+	&= tdesc_numbered_register (feature, tdesc_data,
+				    mips_regnum.fp_implementation_revision,
+				    "fir");
 
       if (!valid_p)
 	{
@@ -5341,8 +5413,48 @@
 	  return NULL;
 	}
 
+      /* The DSP registers are optional.  Handle the lack of them
+         gracefully.  */
+      feature = tdesc_find_feature (info.target_desc,
+				    "org.gnu.gdb.mips.dsp");
+      if (feature == NULL)
+	{
+	  mips_regnum.dspacc = 0;
+	  mips_regnum.dspctl = 0;
+	}
+
+      if (mips_regnum.dspacc != 0)
+	{
+	  valid_p = 1;
+	  i = dsp_space;
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "hi1");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "lo1");
+	  i += dsp_space;
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "hi2");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "lo2");
+	  i += dsp_space;
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "hi3");
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspacc + i++, "lo3");
+
+	  valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					      mips_regnum.dspctl, "dspctl");
+
+	  if (!valid_p)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+	}
+
       /* It would be nice to detect an attempt to use a 64-bit ABI
 	 when only 32-bit registers are provided.  */
+      reg_names = NULL;
     }
 
   /* First of all, extract the elf_flags, if available.  */
@@ -5581,66 +5693,19 @@
   set_gdbarch_elf_make_msymbol_special (gdbarch,
 					mips_elf_make_msymbol_special);
 
-  /* Fill in the OS dependant register numbers and names.  */
-  {
-    const char **reg_names;
-    struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
-							 struct mips_regnum);
-    if (tdesc_has_registers (info.target_desc))
-      {
-	regnum->lo = MIPS_EMBED_LO_REGNUM;
-	regnum->hi = MIPS_EMBED_HI_REGNUM;
-	regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
-	regnum->cause = MIPS_EMBED_CAUSE_REGNUM;
-	regnum->pc = MIPS_EMBED_PC_REGNUM;
-	regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
-	regnum->fp_control_status = 70;
-	regnum->fp_implementation_revision = 71;
-	num_regs = MIPS_LAST_EMBED_REGNUM + 1;
-	reg_names = NULL;
-      }
-    else if (info.osabi == GDB_OSABI_IRIX)
-      {
-	regnum->fp0 = 32;
-	regnum->pc = 64;
-	regnum->cause = 65;
-	regnum->badvaddr = 66;
-	regnum->hi = 67;
-	regnum->lo = 68;
-	regnum->fp_control_status = 69;
-	regnum->fp_implementation_revision = 70;
-	num_regs = 71;
-	reg_names = mips_irix_reg_names;
-      }
-    else
-      {
-	regnum->lo = MIPS_EMBED_LO_REGNUM;
-	regnum->hi = MIPS_EMBED_HI_REGNUM;
-	regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
-	regnum->cause = MIPS_EMBED_CAUSE_REGNUM;
-	regnum->pc = MIPS_EMBED_PC_REGNUM;
-	regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
-	regnum->fp_control_status = 70;
-	regnum->fp_implementation_revision = 71;
-	num_regs = 90;
-	if (info.bfd_arch_info != NULL
-	    && info.bfd_arch_info->mach == bfd_mach_mips3900)
-	  reg_names = mips_tx39_reg_names;
-	else
-	  reg_names = mips_generic_reg_names;
-      }
-    /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been
-       replaced by read_pc?  */
-    set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
-    set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
-    set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
-    set_gdbarch_num_regs (gdbarch, num_regs);
-    set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
-    set_gdbarch_register_name (gdbarch, mips_register_name);
-    set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer);
-    tdep->mips_processor_reg_names = reg_names;
-    tdep->regnum = regnum;
-  }
+  regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum);
+  *regnum = mips_regnum;
+  /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been
+     replaced by read_pc?  */
+  set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
+  set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
+  set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
+  set_gdbarch_num_regs (gdbarch, num_regs);
+  set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+  set_gdbarch_register_name (gdbarch, mips_register_name);
+  set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer);
+  tdep->mips_processor_reg_names = reg_names;
+  tdep->regnum = regnum;
 
   switch (mips_abi)
     {
Index: binutils-quilt/src/gdb/mips-tdep.h
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.h	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.h	2008-03-18 16:57:45.000000000 +0000
@@ -53,6 +53,8 @@
   int cause;		/* Describes last exception.  */
   int hi;		/* Multiply/divide temp.  */
   int lo;		/* ...  */
+  int dspacc;		/* SmartMIPS/DSP accumulators.  */
+  int dspctl;		/* DSP control.  */
 };
 extern const struct mips_regnum *mips_regnum (struct gdbarch *gdbarch);
 
@@ -75,9 +77,26 @@
   MIPS_EMBED_PC_REGNUM = 37,
   MIPS_EMBED_FP0_REGNUM = 38,
   MIPS_UNUSED_REGNUM = 73,	/* Never used, FIXME */
-  MIPS_FIRST_EMBED_REGNUM = 74,	/* First CP0 register for embedded use.  */
-  MIPS_PRID_REGNUM = 89,	/* Processor ID.  */
-  MIPS_LAST_EMBED_REGNUM = 89	/* Last one.  */
+  MIPS_FIRST_EMBED_REGNUM = 74,	/* First CP register for embedded use.  */
+  MIPS_EMBED_CP0_REGNUM = MIPS_FIRST_EMBED_REGNUM,
+				/* CP0 data registers: 8 banks of 32.  */
+  MIPS_PRID_REGNUM = (MIPS_EMBED_CP0_REGNUM + 15),
+				/* Processor ID.  */
+  MIPS_EMBED_CP2_REGNUM = (MIPS_EMBED_CP0_REGNUM + 8 * 32),
+				/* CP2 data registers: 8 banks of 32.  */
+  MIPS_EMBED_CP2CTL_REGNUM = (MIPS_EMBED_CP2_REGNUM + 8 * 32),
+				/* CP2 control registers: 32.  */
+  MIPS_EMBED_DSPACC_REGNUM = (MIPS_EMBED_CP2CTL_REGNUM + 32),
+				/* DSP/SmartMIPS registers:
+				   ACX, Hi1, Lo1, ACX1,
+				   Hi2, Lo2, ACX2, Hi3, Lo3, ACX3.  */
+  MIPS_EMBED_DSPCTL_REGNUM = (MIPS_EMBED_DSPACC_REGNUM + 10),
+				/* DSP DSPCTL0..1 registers.  */
+  MIPS_EMBED_NUM_REGS = (MIPS_EMBED_DSPCTL_REGNUM + 2),
+				/* Total number of actual registers.  */
+  MIPS_LAST_EMBED_REGNUM
+    = ((MIPS_EMBED_NUM_REGS + MIPS_EMBED_NUM_REGS % 2) - 1)
+				/* Last one, including padding to even.  */
 };
 
 /* Defined in mips-tdep.c and used in remote-mips.c */
Index: binutils-quilt/src/gdb/mips-linux-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-linux-tdep.c	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-tdep.c	2008-03-18 16:57:45.000000000 +0000
@@ -112,14 +112,6 @@
   supply_32bit_reg (regcache, MIPS_PS_REGNUM, regp + EF_CP0_STATUS);
   supply_32bit_reg (regcache, mips_regnum (gdbarch)->cause,
 		    regp + EF_CP0_CAUSE);
-
-  /* Fill inaccessible registers with zero.  */
-  regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
-  regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
-  for (regi = MIPS_FIRST_EMBED_REGNUM;
-       regi <= MIPS_LAST_EMBED_REGNUM;
-       regi++)
-    regcache_raw_supply (regcache, regi, zerobuf);
 }
 
 /* Pack our registers (or one register) into an elf_gregset_t.  */
@@ -325,14 +317,6 @@
 		    (const gdb_byte *) (regp + MIPS64_EF_CP0_STATUS));
   supply_64bit_reg (regcache, mips_regnum (gdbarch)->cause,
 		    (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE));
-
-  /* Fill inaccessible registers with zero.  */
-  regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
-  regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
-  for (regi = MIPS_FIRST_EMBED_REGNUM;
-       regi <= MIPS_LAST_EMBED_REGNUM;
-       regi++)
-    regcache_raw_supply (regcache, regi, zerobuf);
 }
 
 /* Pack our registers (or one register) into a 64-bit elf_gregset_t.  */
Index: binutils-quilt/src/gdb/mips-linux-tdep.h
===================================================================
--- binutils-quilt.orig/src/gdb/mips-linux-tdep.h	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-tdep.h	2008-03-18 16:57:45.000000000 +0000
@@ -36,6 +36,8 @@
 #define MMLO		68
 #define FPC_CSR		69
 #define FPC_EIR		70
+#define DSP_BASE	71
+#define DSP_CONTROL	77
 
 #define EF_REG0			6
 #define EF_REG31		37
Index: binutils-quilt/src/gdb/features/mips-linux.xml
===================================================================
--- binutils-quilt.orig/src/gdb/features/mips-linux.xml	2008-03-18 16:48:10.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-linux.xml	2008-03-18 16:57:45.000000000 +0000
@@ -13,6 +13,6 @@
   <xi:include href="mips-fpu.xml"/>
 
   <feature name="org.gnu.gdb.mips.linux">
-    <reg name="restart" bitsize="32" group="system"/>
+    <reg name="restart" bitsize="32" group="system" regnum="79"/>
   </feature>
 </target>
Index: binutils-quilt/src/gdb/features/mips64-dsp.xml
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-dsp.xml	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.dsp">
+  <reg name="hi1" bitsize="64" regnum="72"/>
+  <reg name="lo1" bitsize="64" regnum="73"/>
+  <reg name="hi2" bitsize="64" regnum="74"/>
+  <reg name="lo2" bitsize="64" regnum="75"/>
+  <reg name="hi3" bitsize="64" regnum="76"/>
+  <reg name="lo3" bitsize="64" regnum="77"/>
+
+  <reg name="dspctl" bitsize="32" regnum="78"/>
+</feature>
Index: binutils-quilt/src/gdb/features/mips64-linux.xml
===================================================================
--- binutils-quilt.orig/src/gdb/features/mips64-linux.xml	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-linux.xml	2008-03-18 16:57:45.000000000 +0000
@@ -13,6 +13,6 @@
   <xi:include href="mips64-fpu.xml"/>
 
   <feature name="org.gnu.gdb.mips.linux">
-    <reg name="restart" bitsize="64" group="system"/>
+    <reg name="restart" bitsize="64" group="system" regnum="79"/>
   </feature>
 </target>
Index: binutils-quilt/src/gdb/features/mips-dsp.xml
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-dsp.xml	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.dsp">
+  <reg name="hi1" bitsize="32" regnum="72"/>
+  <reg name="lo1" bitsize="32" regnum="73"/>
+  <reg name="hi2" bitsize="32" regnum="74"/>
+  <reg name="lo2" bitsize="32" regnum="75"/>
+  <reg name="hi3" bitsize="32" regnum="76"/>
+  <reg name="lo3" bitsize="32" regnum="77"/>
+
+  <reg name="dspctl" bitsize="32" regnum="78"/>
+</feature>
Index: binutils-quilt/src/gdb/regcache.c
===================================================================
--- binutils-quilt.orig/src/gdb/regcache.c	2008-03-18 16:48:10.000000000 +0000
+++ binutils-quilt/src/gdb/regcache.c	2008-03-18 16:57:45.000000000 +0000
@@ -398,16 +398,24 @@
   return regcache->register_valid_p[regnum];
 }
 
+/* Record that REGNUM's value is cached if STATE is >0, uncached but
+   fetchable if STATE is 0, and uncached and unfetchable if STATE is <0.  */
+
 void
-regcache_invalidate (struct regcache *regcache, int regnum)
+regcache_set_valid_p (struct regcache *regcache, int regnum, int state)
 {
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >= 0);
   gdb_assert (!regcache->readonly_p);
   gdb_assert (regnum < regcache->descr->nr_raw_registers);
-  regcache->register_valid_p[regnum] = 0;
+  regcache->register_valid_p[regnum] = state;
 }
 
+void
+regcache_invalidate (struct regcache *regcache, int regnum)
+{
+  regcache_set_valid_p (regcache, regnum, 0);
+}
 
 /* Global structure containing the current regcache.  */
 /* FIXME: cagney/2002-05-11: The two global arrays registers[] and
Index: binutils-quilt/src/gdb/regcache.h
===================================================================
--- binutils-quilt.orig/src/gdb/regcache.h	2008-03-18 16:48:10.000000000 +0000
+++ binutils-quilt/src/gdb/regcache.h	2008-03-18 16:57:45.000000000 +0000
@@ -60,6 +60,8 @@
 
 int regcache_valid_p (const struct regcache *regcache, int regnum);
 
+void regcache_set_valid_p (struct regcache *regcache, int regnum, int state);
+
 void regcache_invalidate (struct regcache *regcache, int regnum);
 
 /* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS).  */
Index: binutils-quilt/src/gdb/features/mips64-linux.c
===================================================================
--- binutils-quilt.orig/src/gdb/features/mips64-linux.c	2008-03-18 16:48:10.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-linux.c	2008-03-18 16:57:45.000000000 +0000
@@ -93,7 +93,7 @@
   tdesc_create_reg (feature, "fir", 71, 1, "float", 64, "int");
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
-  tdesc_create_reg (feature, "restart", 72, 1, "system", 64, "int");
+  tdesc_create_reg (feature, "restart", 79, 1, "system", 64, "int");
 
   tdesc_mips64_linux = result;
 }
Index: binutils-quilt/src/gdb/features/mips-linux.c
===================================================================
--- binutils-quilt.orig/src/gdb/features/mips-linux.c	2008-03-18 16:48:10.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-linux.c	2008-03-18 16:57:45.000000000 +0000
@@ -93,7 +93,7 @@
   tdesc_create_reg (feature, "fir", 71, 1, "float", 32, "int");
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
-  tdesc_create_reg (feature, "restart", 72, 1, "system", 32, "int");
+  tdesc_create_reg (feature, "restart", 79, 1, "system", 32, "int");
 
   tdesc_mips_linux = result;
 }
Index: binutils-quilt/src/gdb/Makefile.in
===================================================================
--- binutils-quilt.orig/src/gdb/Makefile.in	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/Makefile.in	2008-03-18 16:57:45.000000000 +0000
@@ -960,7 +960,9 @@
 features_headers = $(defs_h) $(gdbtypes_h) $(target_descriptions_h)
 arm_with_iwmmxt_c = $(srcdir)/features/arm-with-iwmmxt.c $(features_headers)
 mips_linux_c = $(srcdir)/features/mips-linux.c $(features_headers)
+mips_dsp_linux_c = $(srcdir)/features/mips-dsp-linux.c $(features_headers)
 mips64_linux_c = $(srcdir)/features/mips64-linux.c $(features_headers)
+mips64_dsp_linux_c = $(srcdir)/features/mips64-dsp-linux.c $(features_headers)
 powerpc_32_c = $(srcdir)/features/rs6000/powerpc-32.c $(features_headers)
 powerpc_403_c = $(srcdir)/features/rs6000/powerpc-403.c $(features_headers)
 powerpc_403gc_c = $(srcdir)/features/rs6000/powerpc-403gc.c $(features_headers)
@@ -2472,7 +2474,8 @@
 mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h) $(target_h) \
 	$(regcache_h) $(linux_nat_h) $(gdb_proc_service_h) $(gregset_h) \
 	$(mips_linux_tdep_h) $(inferior_h) $(target_descriptions_h) \
-	$(mips_linux_c) $(mips64_linux_c)
+	$(mips_linux_c) $(mips_dsp_linux_c) \
+	$(mips64_dsp_linux_c) $(mips64_dsp_linux_c)
 mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
 	$(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \
 	$(gdb_assert_h) $(frame_h) $(regcache_h) $(trad_frame_h) \
Index: binutils-quilt/src/gdb/features/Makefile
===================================================================
--- binutils-quilt.orig/src/gdb/features/Makefile	2008-03-18 16:48:09.000000000 +0000
+++ binutils-quilt/src/gdb/features/Makefile	2008-03-18 16:57:45.000000000 +0000
@@ -31,13 +31,16 @@
 # in the GDB repository.  To generate C files:
 #   make GDB=/path/to/gdb XMLTOC="xml files" cfiles
 
-WHICH = arm-with-iwmmxt mips-linux mips64-linux \
+WHICH = arm-with-iwmmxt \
+	mips-linux mips-dsp-linux mips64-linux mips64-dsp-linux \
 	rs6000/powerpc-32 rs6000/powerpc-e500 rs6000/powerpc-64
 
 # Record which registers should be sent to GDB by default after stop.
 arm-with-iwmmxt-expedite = r11,sp,pc
 mips-linux-expedite = r29,pc
+mips-dsp-linux-expedite = r29,pc
 mips64-linux-expedite = r29,pc
+mips64-dsp-linux-expedite = r29,pc
 rs6000/powerpc-32-expedite = r1,pc
 rs6000/powerpc-e500-expedite = r1,pc
 rs6000/powerpc-64-expedite = r1,pc
Index: binutils-quilt/src/gdb/features/mips-dsp-linux.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-dsp-linux.c	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,108 @@
+/* THIS FILE IS GENERATED.  Original: mips-dsp-linux.xml */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_mips_dsp_linux;
+static void
+initialize_tdesc_mips_dsp_linux (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+  struct type *field_type, *type;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("mips"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "lo", 33, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "hi", 34, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "pc", 37, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cp0");
+  tdesc_create_reg (feature, "status", 32, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "badvaddr", 35, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "cause", 36, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.fpu");
+  tdesc_create_reg (feature, "f0", 38, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f1", 39, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f2", 40, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f3", 41, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f4", 42, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f5", 43, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f6", 44, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f7", 45, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f8", 46, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f9", 47, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f10", 48, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f11", 49, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f12", 50, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f13", 51, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f14", 52, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f15", 53, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f16", 54, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f17", 55, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f18", 56, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f19", 57, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f20", 58, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f21", 59, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f22", 60, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f23", 61, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f24", 62, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f25", 63, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f26", 64, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f27", 65, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f28", 66, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f29", 67, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f30", 68, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "f31", 69, 1, NULL, 32, "ieee_single");
+  tdesc_create_reg (feature, "fcsr", 70, 1, "float", 32, "int");
+  tdesc_create_reg (feature, "fir", 71, 1, "float", 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp");
+  tdesc_create_reg (feature, "hi1", 72, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "lo1", 73, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "hi2", 74, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "lo2", 75, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "hi3", 76, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "lo3", 77, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
+  tdesc_create_reg (feature, "restart", 79, 1, "system", 32, "int");
+
+  tdesc_mips_dsp_linux = result;
+}
Index: binutils-quilt/src/gdb/features/mips-dsp-linux.xml
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-dsp-linux.xml	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>mips</architecture>
+  <xi:include href="mips-cpu.xml"/>
+  <xi:include href="mips-cp0.xml"/>
+  <xi:include href="mips-fpu.xml"/>
+  <xi:include href="mips-dsp.xml"/>
+
+  <feature name="org.gnu.gdb.mips.linux">
+    <reg name="restart" bitsize="32" group="system" regnum="79"/>
+  </feature>
+</target>
Index: binutils-quilt/src/gdb/features/mips64-dsp-linux.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-dsp-linux.c	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,108 @@
+/* THIS FILE IS GENERATED.  Original: mips64-dsp-linux.xml */
+
+#include "defs.h"
+#include "gdbtypes.h"
+#include "target-descriptions.h"
+
+struct target_desc *tdesc_mips64_dsp_linux;
+static void
+initialize_tdesc_mips64_dsp_linux (void)
+{
+  struct target_desc *result = allocate_target_description ();
+  struct tdesc_feature *feature;
+  struct type *field_type, *type;
+
+  set_tdesc_architecture (result, bfd_scan_arch ("mips"));
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cpu");
+  tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "lo", 33, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "hi", 34, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "pc", 37, 1, NULL, 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.cp0");
+  tdesc_create_reg (feature, "status", 32, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "badvaddr", 35, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "cause", 36, 1, NULL, 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.fpu");
+  tdesc_create_reg (feature, "f0", 38, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f1", 39, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f2", 40, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f3", 41, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f4", 42, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f5", 43, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f6", 44, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f7", 45, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f8", 46, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f9", 47, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f10", 48, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f11", 49, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f12", 50, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f13", 51, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f14", 52, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f15", 53, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f16", 54, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f17", 55, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f18", 56, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f19", 57, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f20", 58, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f21", 59, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f22", 60, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f23", 61, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f24", 62, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f25", 63, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f26", 64, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f27", 65, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f28", 66, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f29", 67, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f30", 68, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "f31", 69, 1, NULL, 64, "ieee_double");
+  tdesc_create_reg (feature, "fcsr", 70, 1, "float", 64, "int");
+  tdesc_create_reg (feature, "fir", 71, 1, "float", 64, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp");
+  tdesc_create_reg (feature, "hi1", 72, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "lo1", 73, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "hi2", 74, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "lo2", 75, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "hi3", 76, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "lo3", 77, 1, NULL, 64, "int");
+  tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int");
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
+  tdesc_create_reg (feature, "restart", 79, 1, "system", 64, "int");
+
+  tdesc_mips64_dsp_linux = result;
+}
Index: binutils-quilt/src/gdb/features/mips64-dsp-linux.xml
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-dsp-linux.xml	2008-03-18 16:57:45.000000000 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>mips</architecture>
+  <xi:include href="mips64-cpu.xml"/>
+  <xi:include href="mips64-cp0.xml"/>
+  <xi:include href="mips64-fpu.xml"/>
+  <xi:include href="mips64-dsp.xml"/>
+
+  <feature name="org.gnu.gdb.mips.linux">
+    <reg name="restart" bitsize="64" group="system" regnum="79"/>
+  </feature>
+</target>
Index: binutils-quilt/src/gdb/doc/gdb.texinfo
===================================================================
--- binutils-quilt.orig/src/gdb/doc/gdb.texinfo	2008-03-18 16:43:42.000000000 +0000
+++ binutils-quilt/src/gdb/doc/gdb.texinfo	2008-03-18 16:57:45.000000000 +0000
@@ -26803,6 +26803,10 @@
 contain registers @samp{f0} through @samp{f31}, @samp{fcsr}, and
 @samp{fir}.  They may be 32-bit or 64-bit depending on the target.
 
+The @samp{org.gnu.gdb.mips.dsp} feature is optional.  If present, it
+should contain registers @samp{lo1} through @samp{lo3}, @samp{hi1}
+through @samp{hi3}, and @samp{dspctl}.
+
 The @samp{org.gnu.gdb.mips.linux} feature is optional.  It should
 contain a single register, @samp{restart}, which is used by the
 Linux kernel to control restartable syscalls.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]