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]

MIPS: Handle the DSP registers


Hello,

 Here is code to support DSP registers as defined by the DSP ASE to the 
MIPS Architecture.  This piece of code handles Linux and provides for 
adding such support to embedded targets.  The ASE is optional (as are all 
ASEs) and therefore some steps have been taken to handle this correctly.

 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).

 The offsets and layout of DSP registers vary between Linux and bare-iron 
-- this has been taken account of (by shuffling some code around in 
mips_gdbarch_init(), which I believe has actually made it a little bit 
more readable) and it is also the reason some minimal support for these 
registers with the bare-iron has been included here (and which effectively 
amounts to the addition of more MIPS_EMBED_* enum definitions and their 
use in mips-tdep.c).  Full support for bare-iron relies on cp0 register 
discovery which I plan to propose later on (once I have found a reasonable 
way to port the old piece of code so that it fits the XML target 
description model).

 As a small benefit on top of these changes, there is no need to provide 
null strings in the tables holding register names for offsets 
corresponding to inexistent registers anymore -- mips_register_name() now 
returns a null string when the entry requested holds a null pointer.

 Tested using the mipsisa32-sde-elf target, with the mips-sim-sde32/-EB 
and mips-sim-sde32/-EL boards with no regressions.  Tested natively with 
the mips-linux-gnu host/target (with the o32 ABI) using a MIPS64 (no DSP 
ASE) and a MIPS32r2 (DSP-enabled) processor with no regressions in either.  
I have no access to the IRIX host, but I hope I have not broken anything 
-- the support for no-DSP there should keep working as it is.

gdb/:
2007-12-10  Maciej W. Rozycki  <macro@mips.com>
            Chris Dearman  <chris@mips.com>

	* features/mips-dsp.xml: New file.
	* features/mips64-dsp.xml: Likewise.
	* features/mips-linux.xml: Include mips-dsp.xml.
	* features/mips64-linux.xml: Include mips64-dsp.xml.
	* features/mips-linux.c: Regenerate.
	* features/mips64-linux.c: Regenerate.
	* inf-ptrace.c (inf_ptrace_fetch_register): Don't bail out
	having attempted to read an inexistent register; mark it as
	inaccessible in the cache instead.
	(inf_ptrace_store_register): Don't bail out having attempted to
	write an inexistent register.
	* mips-linux-nat.c (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-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 DSP accumulators.
	(mips_dwarf_dwarf2_ecoff_reg_to_regnum): Likewise.
	(mips_gdbarch_init): Likewise.  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.

gdb/testsuite/:
2007-12-10  Maciej W. Rozycki  <macro@mips.com>

	* gdb.xml/tdesc-regs.exp: Add "mips-dsp.xml" to the list of MIPS
	core registers.

 Ok to apply?

  Maciej

14607.diff
Index: binutils-quilt/src/gdb/mips-linux-nat.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-linux-nat.c	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-nat.c	2007-12-07 15:13:02.000000000 +0000
@@ -47,8 +47,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 +84,11 @@
     regaddr = FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
+  else if ((regno >= mips_regnum (gdbarch)->dspacc)
+	   && (regno < mips_regnum (gdbarch)->dspacc + 6))
+    regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
+  else if (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 +124,11 @@
     regaddr = MIPS64_FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
     regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
+  else if ((regno >= mips_regnum (gdbarch)->dspacc)
+	   && (regno < mips_regnum (gdbarch)->dspacc + 6))
+    regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
+  else if (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 +202,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 +216,20 @@
   else
     is_fp = 0;
 
+  /* DSP registers are optional and not a part of any set.  */
+  if ((regno >= mips_regnum (gdbarch)->dspacc)
+      && (regno < mips_regnum (gdbarch)->dspacc + 6))
+    is_dsp = 1;
+  else if (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 +265,28 @@
       mips64_supply_fpregset (regcache,
 			      (const mips64_elf_fpregset_t *) &fp_regs);
     }
+
+  if (is_dsp)
+    super_fetch_registers (regcache, regno);
+  else if (regno == -1)
+    {
+      for (regi = mips_regnum (gdbarch)->dspacc;
+	   regi < mips_regnum (gdbarch)->dspacc + 6;
+	   regi++)
+	super_fetch_registers (regcache, regi);
+      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 +299,20 @@
   else
     is_fp = 0;
 
+  /* DSP registers are optional and not a part of any set.  */
+  if ((regno >= mips_regnum (gdbarch)->dspacc)
+      && (regno < mips_regnum (gdbarch)->dspacc + 6))
+    is_dsp = 1;
+  else if (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 +339,17 @@
 		  (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)
+    {
+      for (regi = mips_regnum (gdbarch)->dspacc;
+	   regi < mips_regnum (gdbarch)->dspacc + 6;
+	   regi++)
+	super_store_registers (regcache, regi);
+      super_store_registers (regcache, mips_regnum (gdbarch)->dspctl);
+    }
 }
 
 /* Fetch REGNO (or all registers if REGNO == -1) from the target
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2007-12-07 15:10:04.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.c	2007-12-07 15:13:02.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__,
@@ -5076,6 +5087,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?  */
@@ -5099,6 +5112,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?  */
@@ -5232,10 +5247,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 = -1;
+      mips_regnum.dspctl = -1;
+      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))
@@ -5270,11 +5341,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)
 	{
@@ -5292,12 +5363,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)
 	{
@@ -5318,13 +5388,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)
 	{
@@ -5332,8 +5404,46 @@
 	  return NULL;
 	}
 
+      if (mips_regnum.dspacc >= 0)
+	{
+	  feature = tdesc_find_feature (info.target_desc,
+					"org.gnu.gdb.mips.dsp");
+	  if (feature == NULL)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+
+	  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.  */
@@ -5572,66 +5682,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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.h	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-tdep.c	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/mips-linux-tdep.h	2007-12-07 15:13:02.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/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
@@ -647,7 +647,12 @@
     {
       errno = 0;
       buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0);
-      if (errno != 0)
+      if (errno == EIO)
+	{
+	  regcache_set_valid_p (regcache, regnum, -1);
+	  return;
+	}
+      else if (errno != 0)
 	error (_("Couldn't read register %s (#%d): %s."),
 	       gdbarch_register_name (gdbarch, regnum),
 	       regnum, safe_strerror (errno));
@@ -705,7 +710,9 @@
     {
       errno = 0;
       ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]);
-      if (errno != 0)
+      if (errno == EIO)
+	return;
+      else if (errno != 0)
 	error (_("Couldn't write register %s (#%d): %s."),
 	       gdbarch_register_name (gdbarch, regnum),
 	       regnum, safe_strerror (errno));
Index: binutils-quilt/src/gdb/features/mips-linux.xml
===================================================================
--- binutils-quilt.orig/src/gdb/features/mips-linux.xml	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-linux.xml	2007-12-07 15:13:02.000000000 +0000
@@ -11,6 +11,7 @@
   <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"/>
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	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-linux.xml	2007-12-07 15:13:02.000000000 +0000
@@ -11,6 +11,7 @@
   <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"/>
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	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/regcache.c	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/regcache.h	2007-12-07 15:13:02.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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips64-linux.c	2007-12-07 15:13:02.000000000 +0000
@@ -92,8 +92,17 @@
   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", 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	2007-12-07 15:08:21.000000000 +0000
+++ binutils-quilt/src/gdb/features/mips-linux.c	2007-12-07 15:13:02.000000000 +0000
@@ -92,8 +92,17 @@
   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", 72, 1, "system", 32, "int");
+  tdesc_create_reg (feature, "restart", 79, 1, "system", 32, "int");
 
   tdesc_mips_linux = result;
 }
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/"


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