Re: MIPS: Handle the DSP registers

Daniel Jacobowitz
2008-03-21T18:44:20Z

On Wed, Mar 19, 2008 at 05:06:01PM +0000, Maciej W. Rozycki wrote:
> 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.

That's how our initialization is supposed to work, though. A minimal
description is used until we know exactly what we're talking to. If
you need that minimal description to include the new DSP registers,
one way to do it is to rely on the XML description by default if none
is provided - that's what I did for PowerPC.

Anyway, this is a small issue. Except it's tangled up with...

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

...this. The register numbers don't have to be different. You've
added a new internal register numbering for Linux; that isn't
necessary. Where are Linux and bare metal different? Is it in an
existing stub, and if so, what registers does that stub report?

GDB internal register numbers are used for two purposes. They are the
default for the remote P/p and T packet numbering, and the g/G packet
ordering. If a target description describes the registers,
tdesc_remote_register_number is used instead. And they are passed to
GDB functions and determine the register cache layout. This is
internal; just be consistent.

If you use fixed numbering, you don't need to juggle gdbarches and
tdeps everywhere you want a register number. It makes things IMO
much easier to read and maintain.

The regcache.c/regcache.h bits are now unused; they were for your
inf-ptrace.c change.

Are the DSP registers always 32-bit? It looks that way from the
current kernel. I moved away from peekuser/pokeuser register access
because of n32 debugging issues (ptrace uses "long"), but that's not
a problem for registers which are never 64-bit. You've added them
to 64-bit configuration XML files as 64-bit registers, which doesn't
match the kernel.

> @@ -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);

We're trying to eliminate uses of the global current_gdbarch, and the
current gdbarch at this point doesn't much matter; that's why we're
about to replace it with a new gdbarch. This is just DSP_CONTROL.

> /* 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;

And the comment still applies. The gdbarch doesn't matter; if GDB is
built as an o32 program, then on pre-regset kernels it will not be
able to fetch 64-bit registers and all sorts of things will go wrong.
Why did you need this?

> + MIPS_EMBED_DSPCTL_REGNUM = (MIPS_EMBED_DSPACC_REGNUM + 10),
> + /* DSP DSPCTL0..1 registers. */

Are there two of these? We only handle one. Since the internal
register numbers have no compatibility issues we can add another when
we want it.

Also, what are the the ACX registers? You reserve space for them, but
nothing ever fills them in. And there's no XML bits for them.

Anyway, in the interests of progress, that leaves me with the attached
patch. This adds the DSP registers to native Linux GDB without
touching anything else. If you also want them for an embedded stub
which does not supply XML, or for gdbserver, we can do that
separately. I can't test this patch, so take it with a grain of salt;
I only compiled it.

--
Daniel Jacobowitz
CodeSourcery

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.993
diff -u -p -r1.993 Makefile.in
--- Makefile.in 16 Mar 2008 08:50:43 -0000 1.993
+++ Makefile.in 21 Mar 2008 18:42:41 -0000
@@ -958,7 +958,9 @@ tui_winsource_h = $(srcdir)/tui/tui-wins
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)
@@ -2471,7 +2473,8 @@ mips-irix-tdep.o: mips-irix-tdep.c $(def
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: mips-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-nat.c,v
retrieving revision 1.29
diff -u -p -r1.29 mips-linux-nat.c
--- mips-linux-nat.c 1 Jan 2008 22:53:12 -0000 1.29
+++ mips-linux-nat.c 21 Mar 2008 18:42:41 -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 @@ static int have_ptrace_regsets = 1;
/* 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 @@ mips_linux_register_addr (struct gdbarch
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 @@ mips64_linux_register_addr (struct gdbar
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 @@ static void
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 @@ mips64_linux_regsets_fetch_registers (st
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_linux_regsets_fetch_registers (st
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 @@ mips64_linux_regsets_store_registers (co
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 @@ mips64_linux_regsets_store_registers (co
(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,23 @@ mips_linux_register_u_offset (struct gdb
static const struct target_desc *
mips_linux_read_description (struct target_ops *ops)
{
+ int has_dsp;
+ int tid;
+
+ 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) DSP_CONTROL, 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;
+ return has_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux;
else
- return tdesc_mips64_linux;
+ return has_dsp ? tdesc_mips64_dsp_linux : tdesc_mips64_linux;
}

void _initialize_mips_linux_nat (void);
@@ -374,5 +453,7 @@ _initialize_mips_linux_nat (void)

/* Initialize the standard target descriptions. */
initialize_tdesc_mips_linux ();
+ initialize_tdesc_mips_dsp_linux ();
initialize_tdesc_mips64_linux ();
+ initialize_tdesc_mips64_dsp_linux ();
}
Index: mips-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-tdep.c,v
retrieving revision 1.69
diff -u -p -r1.69 mips-linux-tdep.c
--- mips-linux-tdep.c 15 Feb 2008 04:50:58 -0000 1.69
+++ mips-linux-tdep.c 21 Mar 2008 18:42:41 -0000
@@ -112,14 +112,6 @@ mips_supply_gregset (struct regcache *re
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 @@ mips64_supply_gregset (struct regcache *
(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: mips-linux-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-linux-tdep.h,v
retrieving revision 1.7
diff -u -p -r1.7 mips-linux-tdep.h
--- mips-linux-tdep.h 1 Jan 2008 22:53:12 -0000 1.7
+++ mips-linux-tdep.h 21 Mar 2008 18:42:41 -0000
@@ -36,6 +36,8 @@ typedef mips_elf_fpreg_t mips_elf_fpregs
#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
@@ -94,7 +96,7 @@ void mips64_fill_fpregset (const struct
enum {
/* The Linux kernel stores an error code from any interrupted
syscall in a "register" (in $0's save slot). */
- MIPS_RESTART_REGNUM = MIPS_LAST_EMBED_REGNUM + 1
+ MIPS_RESTART_REGNUM = MIPS_NUM_REGS
};

/* Return 1 if MIPS_RESTART_REGNUM is usable. */
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.471
diff -u -p -r1.471 mips-tdep.c
--- mips-tdep.c 15 Mar 2008 00:00:48 -0000 1.471
+++ mips-tdep.c 21 Mar 2008 18:42:42 -0000
@@ -408,7 +408,7 @@ static struct cmd_list_element *showmips
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. */

@@ -418,9 +418,7 @@ static const char *mips_generic_reg_name
"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. */
@@ -446,7 +444,7 @@ static const char *mips_tx39_reg_names[N
"", "", "", "", "", "", "", "",
"", "", "", "",
"", "", "", "", "", "", "", "",
- "", "", "config", "cache", "debug", "depc", "epc", ""
+ "", "", "config", "cache", "debug", "depc", "epc",
};

/* Names of IRIX registers. */
@@ -500,11 +498,15 @@ mips_register_name (struct gdbarch *gdba
}
else if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
return tdesc_register_name (gdbarch, rawnum);
- else if (32 <= rawnum && rawnum < gdbarch_num_regs (gdbarch))
+ else if (32 <= rawnum && rawnum - 32 < NUM_MIPS_PROCESSOR_REGS)
{
- 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 if (rawnum < gdbarch_num_regs (gdbarch))
+ /* Other known registers are always handled by an XML description. */
+ return "";
else
internal_error (__FILE__, __LINE__,
_("mips_register_name: bad register number %d"), rawnum);
@@ -5068,6 +5070,8 @@ mips_stab_reg_to_regnum (struct gdbarch
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? */
@@ -5091,6 +5095,8 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (s
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? */
@@ -5228,6 +5234,7 @@ mips_gdbarch_init (struct gdbarch_info i
enum mips_fpu_type fpu_type;
struct tdesc_arch_data *tdesc_data = NULL;
int elf_fpu_type = 0;
+ int have_dsp = 0;

/* Check any target description for validity. */
if (tdesc_has_registers (info.target_desc))
@@ -5324,6 +5331,37 @@ mips_gdbarch_init (struct gdbarch_info i
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)
+ {
+ valid_p = 1;
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 1, "hi1");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 2, "lo1");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 4, "hi2");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 5, "lo2");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 7, "hi3");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPACC_REGNUM + 8, "lo3");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ MIPS_DSPCTL_REGNUM, "dspctl");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ have_dsp = 1;
+ }
+
/* It would be nice to detect an attempt to use a 64-bit ABI
when only 32-bit registers are provided. */
}
@@ -5579,6 +5617,8 @@ mips_gdbarch_init (struct gdbarch_info i
regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
regnum->fp_control_status = 70;
regnum->fp_implementation_revision = 71;
+ regnum->dspacc = have_dsp ? MIPS_DSPACC_REGNUM : 0;
+ regnum->dspctl = have_dsp ? MIPS_DSPCTL_REGNUM : 0;
num_regs = MIPS_LAST_EMBED_REGNUM + 1;
reg_names = NULL;
}
@@ -5592,6 +5632,8 @@ mips_gdbarch_init (struct gdbarch_info i
regnum->lo = 68;
regnum->fp_control_status = 69;
regnum->fp_implementation_revision = 70;
+ regnum->dspacc = 0;
+ regnum->dspctl = 0;
num_regs = 71;
reg_names = mips_irix_reg_names;
}
@@ -5605,6 +5647,8 @@ mips_gdbarch_init (struct gdbarch_info i
regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
regnum->fp_control_status = 70;
regnum->fp_implementation_revision = 71;
+ regnum->dspacc = 0;
+ regnum->dspctl = 0;
num_regs = 90;
if (info.bfd_arch_info != NULL
&& info.bfd_arch_info->mach == bfd_mach_mips3900)
Index: mips-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.h,v
retrieving revision 1.27
diff -u -p -r1.27 mips-tdep.h
--- mips-tdep.h 1 Jan 2008 22:53:12 -0000 1.27
+++ mips-tdep.h 21 Mar 2008 18:42:42 -0000
@@ -53,6 +53,8 @@ struct mips_regnum
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);

@@ -77,7 +79,12 @@ enum
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_LAST_EMBED_REGNUM = 89, /* Last one. */
+ MIPS_DSPACC_REGNUM = 90, /* DSP/SmartMIPS registers:
+ ACX, Hi1, Lo1, ACX1,
+ Hi2, Lo2, ACX2, Hi3, Lo3, ACX3. */
+ MIPS_DSPCTL_REGNUM = MIPS_DSPACC_REGNUM + 10,
+ MIPS_NUM_REGS
};

/* Defined in mips-tdep.c and used in remote-mips.c */
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.476
diff -u -p -r1.476 gdb.texinfo
--- doc/gdb.texinfo 21 Mar 2008 15:02:37 -0000 1.476
+++ doc/gdb.texinfo 21 Mar 2008 18:42:44 -0000
@@ -26883,6 +26883,10 @@ it may be optional in a future version o
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: features/mips-dsp-linux.c
===================================================================
RCS file: features/mips-dsp-linux.c
diff -N features/mips-dsp-linux.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips-dsp-linux.c 21 Mar 2008 18:42:44 -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.linux");
+ tdesc_create_reg (feature, "restart", 72, 1, "system", 32, "int");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp");
+ tdesc_create_reg (feature, "hi1", 73, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "lo1", 74, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "hi2", 75, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "lo2", 76, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "hi3", 77, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "lo3", 78, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "dspctl", 79, 1, NULL, 32, "int");
+
+ tdesc_mips_dsp_linux = result;
+}
Index: features/mips-dsp-linux.xml
===================================================================
RCS file: features/mips-dsp-linux.xml
diff -N features/mips-dsp-linux.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips-dsp-linux.xml 21 Mar 2008 18:42:44 -0000
@@ -0,0 +1,20 @@
+<?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. -->
+
+
+<target>
+ <architecture>mips</architecture>
+ <xi:include href="mips-cpu.xml"/>
+ <xi:include href="mips-cp0.xml"/>
+ <xi:include href="mips-fpu.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="32" group="system"/>
+ </feature>
+
+ <xi:include href="mips-dsp.xml"/>
+</target>
Index: features/mips-dsp.xml
===================================================================
RCS file: features/mips-dsp.xml
diff -N features/mips-dsp.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips-dsp.xml 21 Mar 2008 18:42:44 -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. -->
+
+
+<feature name="org.gnu.gdb.mips.dsp">
+ <reg name="hi1" bitsize="32"/>
+ <reg name="lo1" bitsize="32"/>
+ <reg name="hi2" bitsize="32"/>
+ <reg name="lo2" bitsize="32"/>
+ <reg name="hi3" bitsize="32"/>
+ <reg name="lo3" bitsize="32"/>
+
+ <reg name="dspctl" bitsize="32"/>
+</feature>
Index: features/mips64-dsp-linux.c
===================================================================
RCS file: features/mips64-dsp-linux.c
diff -N features/mips64-dsp-linux.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips64-dsp-linux.c 21 Mar 2008 18:42:44 -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.linux");
+ tdesc_create_reg (feature, "restart", 72, 1, "system", 64, "int");
+
+ feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp");
+ tdesc_create_reg (feature, "hi1", 73, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "lo1", 74, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "hi2", 75, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "lo2", 76, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "hi3", 77, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "lo3", 78, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "dspctl", 79, 1, NULL, 32, "int");
+
+ tdesc_mips64_dsp_linux = result;
+}
Index: features/mips64-dsp-linux.xml
===================================================================
RCS file: features/mips64-dsp-linux.xml
diff -N features/mips64-dsp-linux.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips64-dsp-linux.xml 21 Mar 2008 18:42:44 -0000
@@ -0,0 +1,20 @@
+<?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. -->
+
+
+<target>
+ <architecture>mips</architecture>
+ <xi:include href="mips64-cpu.xml"/>
+ <xi:include href="mips64-cp0.xml"/>
+ <xi:include href="mips64-fpu.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="64" group="system"/>
+ </feature>
+
+ <xi:include href="mips64-dsp.xml"/>
+</target>
Index: features/mips64-dsp.xml
===================================================================
RCS file: features/mips64-dsp.xml
diff -N features/mips64-dsp.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ features/mips64-dsp.xml 21 Mar 2008 18:42:44 -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. -->
+
+
+<feature name="org.gnu.gdb.mips.dsp">
+ <reg name="hi1" bitsize="64"/>
+ <reg name="lo1" bitsize="64"/>
+ <reg name="hi2" bitsize="64"/>
+ <reg name="lo2" bitsize="64"/>
+ <reg name="hi3" bitsize="64"/>
+ <reg name="lo3" bitsize="64"/>
+
+ <reg name="dspctl" bitsize="32"/>
+</feature>