* MIPS: Handle the DSP registers
@ 2007-12-10 16:33 Maciej W. Rozycki
2007-12-18 13:42 ` Daniel Jacobowitz
0 siblings, 1 reply; 13+ messages in thread
From: Maciej W. Rozycki @ 2007-12-10 16:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Chris Dearman, Maciej W. Rozycki
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/"
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: MIPS: Handle the DSP registers 2007-12-10 16:33 MIPS: Handle the DSP registers Maciej W. Rozycki @ 2007-12-18 13:42 ` Daniel Jacobowitz 2007-12-18 13:56 ` Nigel Stephens 2008-03-19 17:07 ` Maciej W. Rozycki 0 siblings, 2 replies; 13+ messages in thread From: Daniel Jacobowitz @ 2007-12-18 13:42 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Mon, Dec 10, 2007 at 03:51:55PM +0000, Maciej W. Rozycki wrote: > 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). 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. > +/* 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. > @@ -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. > + 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. > 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. > 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"/> And a corrolary of that is that we'll have two mips-linux descriptions, with and without the DSP registers. > 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. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2007-12-18 13:42 ` Daniel Jacobowitz @ 2007-12-18 13:56 ` Nigel Stephens 2007-12-18 15:15 ` Daniel Jacobowitz 2008-03-19 17:07 ` Maciej W. Rozycki 1 sibling, 1 reply; 13+ messages in thread From: Nigel Stephens @ 2007-12-18 13:56 UTC (permalink / raw) To: drow; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki Daniel Jacobowitz wrote: > > >> 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"/> >> > > And a corrolary of that is that we'll have two mips-linux > descriptions, with and without the DSP registers. > Sounds like this mechanism could rapidly get unwieldy if there were many disjoint, optional register sets supported by an architecture -- would you need a different description for each possible permutation? For example with a bare-iron target you might want to omit the floating-point register descriptions for CPUs which don't have a h/w FPU, so then we've got Base, Base+FPU, Base+DSP, Base+FPU+DSP. Then double again for 32-bit vs 64-bit, and so on. Or have I missed something. Nigel ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2007-12-18 13:56 ` Nigel Stephens @ 2007-12-18 15:15 ` Daniel Jacobowitz 2007-12-18 16:06 ` Nigel Stephens 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2007-12-18 15:15 UTC (permalink / raw) To: Nigel Stephens; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Tue, Dec 18, 2007 at 01:41:44PM +0000, Nigel Stephens wrote: > Sounds like this mechanism could rapidly get unwieldy if there were many > disjoint, optional register sets supported by an architecture -- would > you need a different description for each possible permutation? For > example with a bare-iron target you might want to omit the > floating-point register descriptions for CPUs which don't have a h/w > FPU, so then we've got Base, Base+FPU, Base+DSP, Base+FPU+DSP. Then > double again for 32-bit vs 64-bit, and so on. Or have I missed something. You have, but it's a very small thing. The hand-written descriptions in the GDB source code serve three purposes. They are used for gdbserver (which could be made smarter); they are used for GDB (but only to eliminate the build dependency on expat); and they are used as canonical examples for stub writers. There's at least two ways we could support a large set of combinations in GDB. One is to require expat, provide XML files at the feature level, and generate the top level target description using strcat (one of CodeSourcery's stubs does it this way). The other is to adjust the precompiling process, which currently generates a callable C function per target description, to generate functions at the feature level and call those from within GDB. That's a bit nicer. Since so far we only support MIPS with an attached FPU (due to change somewhere in MTI's GDB patch collection, I think?) there's only four descriptions, so no one's bothered to do that flexibility yet. But the framework is there when we need it :-) gdbserver is not very bright; its register set is selected entirely at compile time and the C parts know a bit about the layout of the XML parts. Eventually, it's going to grow multiple description support just like GDB, I think. I just haven't needed it yet. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2007-12-18 15:15 ` Daniel Jacobowitz @ 2007-12-18 16:06 ` Nigel Stephens 0 siblings, 0 replies; 13+ messages in thread From: Nigel Stephens @ 2007-12-18 16:06 UTC (permalink / raw) To: drow; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki Daniel Jacobowitz wrote: > On Tue, Dec 18, 2007 at 01:41:44PM +0000, Nigel Stephens wrote: > >> Sounds like this mechanism could rapidly get unwieldy if there were many >> disjoint, optional register sets supported by an architecture -- would >> you need a different description for each possible permutation? For >> example with a bare-iron target you might want to omit the >> floating-point register descriptions for CPUs which don't have a h/w >> FPU, so then we've got Base, Base+FPU, Base+DSP, Base+FPU+DSP. Then >> double again for 32-bit vs 64-bit, and so on. Or have I missed something. >> > > You have, but it's a very small thing. > > The hand-written descriptions in the GDB source code serve three > purposes. They are used for gdbserver (which could be made smarter); > they are used for GDB (but only to eliminate the build dependency on > expat); and they are used as canonical examples for stub writers. > > There's at least two ways we could support a large set of combinations > in GDB. One is to require expat, provide XML files at the feature > level, and generate the top level target description using strcat > (one of CodeSourcery's stubs does it this way). The other is to > adjust the precompiling process, which currently generates a callable > C function per target description, to generate functions at the > feature level and call those from within GDB. That's a bit nicer. > Yes, FWIW my vote would be for function per feature. > Since so far we only support MIPS with an attached FPU (due to change > somewhere in MTI's GDB patch collection, I think?) there's only four > descriptions, so no one's bothered to do that flexibility yet. But > the framework is there when we need it :-) > > gdbserver is not very bright; its register set is selected entirely at > compile time and the C parts know a bit about the layout of the XML > parts. Eventually, it's going to grow multiple description support > just like GDB, I think. I just haven't needed it yet. > > OK, thanks. Nigel ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2007-12-18 13:42 ` Daniel Jacobowitz 2007-12-18 13:56 ` Nigel Stephens @ 2008-03-19 17:07 ` Maciej W. Rozycki 2008-03-21 18:44 ` Daniel Jacobowitz 1 sibling, 1 reply; 13+ messages in thread From: Maciej W. Rozycki @ 2008-03-19 17:07 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki 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. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-19 17:07 ` Maciej W. Rozycki @ 2008-03-21 18:44 ` Daniel Jacobowitz 2008-03-26 16:59 ` Maciej W. Rozycki 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2008-03-21 18:44 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki 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. --> + +<!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"/> + + <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. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<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. --> + +<!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"/> + + <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. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<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> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-21 18:44 ` Daniel Jacobowitz @ 2008-03-26 16:59 ` Maciej W. Rozycki 2008-03-26 17:59 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Maciej W. Rozycki @ 2008-03-26 16:59 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Fri, 21 Mar 2008, Daniel Jacobowitz 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. Well, I am actually unsure whether I really *need* it (which probably means I do not), but it does not look like a good engineering practice to have this initial meta-state. I suppose no description should be available before a target has been connected to or a native debuggee process started so that it is seen when some code somewhere tries to access this effectively inexistent state. > 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? DSP registers were added pretty late in the game when CP0 registers had already been defined for bare iron, so there is no way to have the same numbers for Linux and bare iron (unless we want to have a hole in the Linux register space). They were added at the end of the already defined ranges, respectively which is I think reasonable. And these numbers have to match ptrace() and the existing remote debug stubs (e.g. YAMON), don't they? > 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. Obviously the numbers returned by tdesc_remote_register_number() are purely internal, but the "legacy" ones are seen externally as mentioned above; or am I getting confused here? > 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. No argument, but is it still doable? > The regcache.c/regcache.h bits are now unused; they were for your > inf-ptrace.c change. The MDI change still relies on these -- I'll migrate them there, thanks for spotting. Hmm, actually I have just spotted I have already committed a build-fix change to remote-mips.c that I submitted a while ago that makes the file rely on the function; still it is not built without the MDI change, so I propose not to take them out and wait for MDI to get in. > 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. The kernel is wrong -- with MIPS64 processors additional HIx/LOx registers are 64-bit as the traditional HI/LO ones (which, if you notice instruction encoding, could as well be called HI0/LO0 now) -- all the four provide the same semantics. The control register is 32-bit-wide in all cases. > > @@ -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. Good point -- DSP_CONTROL is indeed fine here. > > /* 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? It just looked wrong to me to depend on a preprocessor macro where we strive to make GDB multi-platform. Your point is of course valid, but after a little thought I believe my change is right anyway. Given a 64-bit kernel and an (n)64 or n32 GDB binary you may want to debug an o32 executable; I have not investigated how ptrace() is meant to work in such a scenario and I do not insist on getting rid of the macro dependency with this patch, but this is something to be kept in mind in my opinion. > > + 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. Well-spotted, thanks -- this is an obsolete reference to DSPCTL1 which has never happened. All the relevant associated bits of code have been already removed. > 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. These are the "ACcumulator eXtension" registers as defined by the SmartMIPS ASE. One is added per each HI/LO pair; though to the best of my knowledge nobody has manufactured a MIPS core with the DSP and SmartMIPS ASEs both included at the same time, hence only a single ACX register (for the traditional HI/LO pair) has ever been in implemented in existing hardware. > 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. Thanks for your effort. As you may have noticed the bare-iron bits merely provide definitions so that register offsets are correctly allocated, given some of them are trivially used here. The actual part providing support for CP0/DSP registers stays in my queue pending a rewrite to use target descriptions (CP0 subsetting making it a reasonably complicated task, as mentioned a while ago); support for "legacy" stubs is indeed essential too. I have noticed I missed register format descriptions (what are they for anyway? -- that don't seem to be documented in the obvious places) and fixed a couple of issues that I discovered in testing too. Here is a new version. As native regression testing takes quite a while, I will do this once we agree on a reasonable candidate for commission. 2008-03-26 Maciej W. Rozycki <macro@mips.com> Daniel Jacobowitz <drow@false.org> Chris Dearman <chris@mips.com> * features/mips-dsp.xml: New file for DSP ASE registers. * features/mips64-dsp.xml: Likewise. * features/mips-dsp-linux.xml: New file for a DSP-enabled target. * features/mips64-dsp-linux.xml: Likewise. * features/mips-dsp-linux.c: New generated file. * features/mips64-dsp-linux.c: Likewise. * regformats/mips-dsp-linux.dat: Likewise. * regformats/mips64-dsp-linux.dat: 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_RESTART_REGNUM): Set from MIPS_NUM_REGS. * mips-tdep.c (NUM_MIPS_PROCESSOR_REGS): Set from MIPS_LAST_CP0SEL0_REGNUM. (mips_generic_reg_names): Remove trailing null strings. (mips_tx39_reg_names): Likewise. (mips_r3041_reg_names): Add missing size specifier. (mips_register_name): Check for a null pointer in mips_processor_reg_names and return an empty string. Handle missing XML-described registers. (mips_register_type): Handle the DSP control register. (mips_pseudo_register_type): Likewise. (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. Use MIPS_NUM_REGS as appropriate. * mips-tdep.h (struct mips_regnum): Add dspacc/dspctl offsets. (MIPS_EMBED_CP0_REGNUM): Offset to CP0 registers. (MIPS_LAST_CP0SEL0_REGNUM): Offset to the last CP0 select 0 register. (MIPS_EMBED_CP2_REGNUM): Offset to CP2 registers. (MIPS_EMBED_CP2CTL_REGNUM): Offset to CP2 control registers. (MIPS_LAST_EMBED_REGNUM): Update accordingly. (MIPS_DSPACC_REGNUM): Offset to DSP accumulator registers. (MIPS_DSPCTL_REGNUM): Offset to the DSP control register. (MIPS_NUM_REGS): New value for total register count. * 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.texinfo (MIPS Features): Document org.gnu.gdb.mips.dsp. Comments? Maciej 14607.diff Index: binutils-quilt/src/gdb/mips-linux-nat.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-linux-nat.c 2008-03-26 16:46:08.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-nat.c 2008-03-26 16:47:35.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,21 @@ 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 + 10) + { + if ((regno - mips_regnum (gdbarch)->dspacc) % 3 == 0) + regaddr = (CORE_ADDR) -1; /* ACX registers unhandled. */ + else + regaddr = DSP_BASE + + (regno - mips_regnum (gdbarch)->dspacc) + - (regno - mips_regnum (gdbarch)->dspacc) / 3 + - 1; + } + 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 +138,21 @@ 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 + 10) + { + if ((regno - mips_regnum (gdbarch)->dspacc) % 3 == 0) + regaddr = (CORE_ADDR) -1; /* ACX registers unhandled. */ + else + regaddr = DSP_BASE + + (regno - mips_regnum (gdbarch)->dspacc) + - (regno - mips_regnum (gdbarch)->dspacc) / 3 + - 1; + } + 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 +226,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 +240,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 + 10) + 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 +291,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 + 10; + 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 +327,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 + 10) + 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 +369,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 + 10; + 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 +431,23 @@ 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 +469,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-26 16:47:35.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.c 2008-03-26 16:47:35.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_CP0SEL0_REGNUM + 1 - 32) }; /* Generic MIPS. */ @@ -446,14 +446,12 @@ "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. */ -static const char *mips_r3041_reg_names[] = { +static const char *mips_r3041_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", @@ -474,7 +472,7 @@ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "config", "cache", "debug", "depc", "epc", "" + "", "", "config", "cache", "debug", "depc", "epc", }; /* Names of IRIX registers. */ @@ -528,11 +526,15 @@ } 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); @@ -741,9 +743,12 @@ { /* The cooked or ABI registers. These are sized according to the ABI (with a few complications). */ - if (regnum >= (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp_control_status) - && regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM) + if ((regnum >= (gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp_control_status) + && regnum < gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM) + || (mips_regnum (gdbarch)->dspctl != 0 + && regnum == (gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->dspctl))) /* The pseudo/cooked view of the embedded registers is always 32-bit. The raw view is handled below. */ return builtin_type_int32; @@ -787,7 +792,10 @@ do not try to convert between FPU layouts. */ return rawtype; - if (rawnum >= MIPS_EMBED_FP0_REGNUM + 32 && rawnum <= MIPS_LAST_EMBED_REGNUM) + if ((rawnum >= MIPS_EMBED_FP0_REGNUM + 32 + && rawnum <= MIPS_LAST_EMBED_REGNUM) + || (mips_regnum (gdbarch)->dspctl != 0 + && rawnum == mips_regnum (gdbarch)->dspctl)) { /* The pseudo/cooked view of embedded registers is always 32-bit, even if the target transfers 64-bit values for them. @@ -5089,6 +5097,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? */ @@ -5112,6 +5122,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? */ @@ -5249,6 +5261,7 @@ 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)) @@ -5345,6 +5358,37 @@ 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. */ } @@ -5600,7 +5644,9 @@ regnum->fp0 = MIPS_EMBED_FP0_REGNUM; regnum->fp_control_status = 70; regnum->fp_implementation_revision = 71; - num_regs = MIPS_LAST_EMBED_REGNUM + 1; + regnum->dspacc = have_dsp ? MIPS_DSPACC_REGNUM : 0; + regnum->dspctl = have_dsp ? MIPS_DSPCTL_REGNUM : 0; + num_regs = MIPS_NUM_REGS; reg_names = NULL; } else if (info.osabi == GDB_OSABI_IRIX) @@ -5613,6 +5659,8 @@ 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; } @@ -5626,6 +5674,8 @@ 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: binutils-quilt/src/gdb/mips-tdep.h =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.h 2008-03-26 16:46:08.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.h 2008-03-26 16:47:35.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_LAST_CP0SEL0_REGNUM = MIPS_EMBED_CP0_REGNUM + 31, + /* Last CP0 select 0 register. */ + 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_LAST_EMBED_REGNUM = MIPS_EMBED_CP2CTL_REGNUM + 31, + /* Last CP register for embedded use. */ + MIPS_DSPACC_REGNUM = MIPS_LAST_EMBED_REGNUM + 1, + /* DSP/SmartMIPS registers: + ACX, Hi1, Lo1, ACX1, + Hi2, Lo2, ACX2, Hi3, Lo3, ACX3. */ + MIPS_DSPCTL_REGNUM = MIPS_DSPACC_REGNUM + 10, + /* DSP DSPCTL register. */ + MIPS_NUM_REGS }; /* 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-26 16:46:08.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.c 2008-03-26 16:47:35.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-26 16:46:08.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.h 2008-03-26 16:47:35.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 @@ -94,7 +96,7 @@ 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: 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-26 16:47:35.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"/> + <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> 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-26 16:47:35.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"/> + <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: binutils-quilt/src/gdb/Makefile.in =================================================================== --- binutils-quilt.orig/src/gdb/Makefile.in 2008-03-26 16:47:35.000000000 +0000 +++ binutils-quilt/src/gdb/Makefile.in 2008-03-26 16:47:35.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) @@ -2473,7 +2475,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-26 16:46:08.000000000 +0000 +++ binutils-quilt/src/gdb/features/Makefile 2008-03-26 16:47:35.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-26 16:47:35.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.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: 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-26 16:47:35.000000000 +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. --> + +<!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"/> + + <feature name="org.gnu.gdb.mips.linux"> + <reg name="restart" bitsize="32" group="system"/> + </feature> + + <xi:include href="mips-dsp.xml"/> +</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-26 16:47:35.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.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: 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-26 16:47:35.000000000 +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. --> + +<!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"/> + + <feature name="org.gnu.gdb.mips.linux"> + <reg name="restart" bitsize="64" group="system"/> + </feature> + + <xi:include href="mips64-dsp.xml"/> +</target> Index: binutils-quilt/src/gdb/doc/gdb.texinfo =================================================================== --- binutils-quilt.orig/src/gdb/doc/gdb.texinfo 2008-03-26 16:46:07.000000000 +0000 +++ binutils-quilt/src/gdb/doc/gdb.texinfo 2008-03-26 16:47:35.000000000 +0000 @@ -26881,6 +26881,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: binutils-quilt/src/gdb/regformats/mips-dsp-linux.dat =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/regformats/mips-dsp-linux.dat 2008-03-26 16:47:35.000000000 +0000 @@ -0,0 +1,84 @@ +# DO NOT EDIT: generated from mips-dsp-linux.xml +name:mips_dsp_linux +xmltarget:mips-dsp-linux.xml +expedite:r29,pc +32:r0 +32:r1 +32:r2 +32:r3 +32:r4 +32:r5 +32:r6 +32:r7 +32:r8 +32:r9 +32:r10 +32:r11 +32:r12 +32:r13 +32:r14 +32:r15 +32:r16 +32:r17 +32:r18 +32:r19 +32:r20 +32:r21 +32:r22 +32:r23 +32:r24 +32:r25 +32:r26 +32:r27 +32:r28 +32:r29 +32:r30 +32:r31 +32:status +32:lo +32:hi +32:badvaddr +32:cause +32:pc +32:f0 +32:f1 +32:f2 +32:f3 +32:f4 +32:f5 +32:f6 +32:f7 +32:f8 +32:f9 +32:f10 +32:f11 +32:f12 +32:f13 +32:f14 +32:f15 +32:f16 +32:f17 +32:f18 +32:f19 +32:f20 +32:f21 +32:f22 +32:f23 +32:f24 +32:f25 +32:f26 +32:f27 +32:f28 +32:f29 +32:f30 +32:f31 +32:fcsr +32:fir +32:restart +32:hi1 +32:lo1 +32:hi2 +32:lo2 +32:hi3 +32:lo3 +32:dspctl Index: binutils-quilt/src/gdb/regformats/mips64-dsp-linux.dat =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/regformats/mips64-dsp-linux.dat 2008-03-26 16:47:35.000000000 +0000 @@ -0,0 +1,84 @@ +# DO NOT EDIT: generated from mips64-dsp-linux.xml +name:mips64_dsp_linux +xmltarget:mips64-dsp-linux.xml +expedite:r29,pc +64:r0 +64:r1 +64:r2 +64:r3 +64:r4 +64:r5 +64:r6 +64:r7 +64:r8 +64:r9 +64:r10 +64:r11 +64:r12 +64:r13 +64:r14 +64:r15 +64:r16 +64:r17 +64:r18 +64:r19 +64:r20 +64:r21 +64:r22 +64:r23 +64:r24 +64:r25 +64:r26 +64:r27 +64:r28 +64:r29 +64:r30 +64:r31 +64:status +64:lo +64:hi +64:badvaddr +64:cause +64:pc +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +64:fcsr +64:fir +64:restart +64:hi1 +64:lo1 +64:hi2 +64:lo2 +64:hi3 +64:lo3 +32:dspctl ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-26 16:59 ` Maciej W. Rozycki @ 2008-03-26 17:59 ` Daniel Jacobowitz 2008-03-27 17:13 ` Maciej W. Rozycki 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2008-03-26 17:59 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Wed, Mar 26, 2008 at 04:58:28PM +0000, Maciej W. Rozycki wrote: > Well, I am actually unsure whether I really *need* it (which probably > means I do not), but it does not look like a good engineering practice to > have this initial meta-state. I suppose no description should be > available before a target has been connected to or a native debuggee > process started so that it is seen when some code somewhere tries to > access this effectively inexistent state. There will be no description unless the architecture supplies a default one. The initialization sequence does not look like it would if I'd been writing a debugger from scratch, I admit. It was very tangled up but this is the best compromise I could come up with. > > ...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? > > DSP registers were added pretty late in the game when CP0 registers had > already been defined for bare iron, so there is no way to have the same > numbers for Linux and bare iron (unless we want to have a hole in the > Linux register space). They were added at the end of the already defined > ranges, respectively which is I think reasonable. And these numbers have > to match ptrace() and the existing remote debug stubs (e.g. YAMON), don't > they? > > > 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. > > Obviously the numbers returned by tdesc_remote_register_number() are > purely internal, but the "legacy" ones are seen externally as mentioned > above; or am I getting confused here? You've got this backwards. The numbers _taken_ by tdesc_remote_register_number are internal. The numbers returned by it are the external interface with a remote stub. If the remote stub implements the new registers and p/P, or returns the new registers in T responses (both reasonably unlikely) then the numbers matter. If it only implements the new registers and g/G, the numbers do not matter but the ordering of non-zero-sized registers determines the layout of the g/G packet. Ptrace isn't affected by these numbers at all; translation is done by mips_linux_register_addr for instance. If there are no existing remote stubs (ignoring gdbserver, here, newer versions of gdbserver will use XML) that transmit the new registers, then there's no need to give them any particular numbers. If there are existing stubs you want to preserve, then we can add a translation method if you can tell us what the actual register layout you want is. > > The regcache.c/regcache.h bits are now unused; they were for your > > inf-ptrace.c change. > > The MDI change still relies on these -- I'll migrate them there, thanks > for spotting. > > Hmm, actually I have just spotted I have already committed a build-fix > change to remote-mips.c that I submitted a while ago that makes the file > rely on the function; still it is not built without the MDI change, so I > propose not to take them out and wait for MDI to get in. Does the MDI patch rely on passing "1" to the new function? If not, please just use regcache_invalidate. Speaking about good engineering design, a function which marks cached data as valid without putting in any data is pretty suspicious. > The kernel is wrong -- with MIPS64 processors additional HIx/LOx > registers are 64-bit as the traditional HI/LO ones (which, if you notice > instruction encoding, could as well be called HI0/LO0 now) -- all the four > provide the same semantics. The control register is 32-bit-wide in all > cases. Then an N32 GDB is not going to be able to read these registers unless we create a regset for them, FYI. ptrace takes and returns longs on n32, not long longs. I experimented with using long long, but it was a terrible mess. > It just looked wrong to me to depend on a preprocessor macro where we > strive to make GDB multi-platform. Your point is of course valid, but > after a little thought I believe my change is right anyway. Given a > 64-bit kernel and an (n)64 or n32 GDB binary you may want to debug an o32 > executable; I have not investigated how ptrace() is meant to work in such > a scenario and I do not insist on getting rid of the macro dependency with > this patch, but this is something to be kept in mind in my opinion. That exact requirement is why it's written the way it is. If GDB is 64-bit, then we can always read 64-bit registers from the target; the pseudo ABI registers will be the right size for o32. > These are the "ACcumulator eXtension" registers as defined by the > SmartMIPS ASE. One is added per each HI/LO pair; though to the best of my > knowledge nobody has manufactured a MIPS core with the DSP and SmartMIPS > ASEs both included at the same time, hence only a single ACX register (for > the traditional HI/LO pair) has ever been in implemented in existing > hardware. I see, thanks. > I have noticed I missed register format descriptions (what are they for > anyway? -- that don't seem to be documented in the obvious places) and They're for gdbserver; they define its register cache. If I wrote the missing XML files for all existing gdbserver targets, I could replace them with pregenerated C files using xsltproc (just like I did for the ones currently in features/*.c); I haven't gotten round to it. > fixed a couple of issues that I discovered in testing too. Here is a new > version. As native regression testing takes quite a while, I will do this > once we agree on a reasonable candidate for commission. Sounds fine. If you'll forgive me, I'll wait to look at the patch until we resolve the issues above. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-26 17:59 ` Daniel Jacobowitz @ 2008-03-27 17:13 ` Maciej W. Rozycki 2008-03-27 17:46 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Maciej W. Rozycki @ 2008-03-27 17:13 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Wed, 26 Mar 2008, Daniel Jacobowitz wrote: > You've got this backwards. The numbers _taken_ by > tdesc_remote_register_number are internal. The numbers returned by it > are the external interface with a remote stub. Ah, I see, indeed -- I got confused at one point. So the numbers in XML files are externally visible and these from the enum containing MIPS_ZERO_REGNUM, etc. are internal. Which means you are right they can be assigned randomly (so your choice is certainly not worse than mine but it's densier, which is an advantage here); though some other bits which predate target descriptions in my patch set depend on these numbers for remote targets, so again -- I will put that dependency to where the dependee is (1). > Ptrace isn't affected by these numbers at all; translation is done > by mips_linux_register_addr for instance. Indeed -- I was too fast writing this. > If there are no existing remote stubs (ignoring gdbserver, here, newer > versions of gdbserver will use XML) that transmit the new > registers, then there's no need to give them any particular numbers. > If there are existing stubs you want to preserve, then we can add > a translation method if you can tell us what the actual register > layout you want is. As far as I know it both YAMON and the SDE library debugging stub both provide access to cp0 registers. I may not have time to check whether they use the problematic packets, but with the code shuffle above (1) this becomes a non-issue for this lone change. > Does the MDI patch rely on passing "1" to the new function? If not, > please just use regcache_invalidate. Speaking about good engineering Well, it passes "-1", so it is reasonable and not exactly the same as regcache_invalidate(). > design, a function which marks cached data as valid without putting > in any data is pretty suspicious. Indeed -- another patch in the set adds: regcache_set_valid_p (regcache, cookednum, regcache_valid_p (regcache, rawnum)); at the botton of mips_pseudo_register_read() too, which is a place, I believe, the scenario you are referring to may actually happen; it used to for sure. Similarly there used to be another possibility for this to trigger in code we have to access registers through a frame. > Then an N32 GDB is not going to be able to read these registers unless > we create a regset for them, FYI. ptrace takes and returns longs on > n32, not long longs. I experimented with using long long, but it was > a terrible mess. Hmm, I have had a peek at the kernel and it looks like PTRACE_POKEUSR and PTRACE_PEEKUSR requests are completely broken for n32; it's just that we have a way around it for GP/FP registers... > > It just looked wrong to me to depend on a preprocessor macro where we > > strive to make GDB multi-platform. Your point is of course valid, but > > after a little thought I believe my change is right anyway. Given a > > 64-bit kernel and an (n)64 or n32 GDB binary you may want to debug an o32 > > executable; I have not investigated how ptrace() is meant to work in such > > a scenario and I do not insist on getting rid of the macro dependency with > > this patch, but this is something to be kept in mind in my opinion. > > That exact requirement is why it's written the way it is. If GDB is > 64-bit, then we can always read 64-bit registers from the target; the > pseudo ABI registers will be the right size for o32. Fair enough, though still hackish in my opinion. ;-) > > fixed a couple of issues that I discovered in testing too. Here is a new > > version. As native regression testing takes quite a while, I will do this > > once we agree on a reasonable candidate for commission. > > Sounds fine. If you'll forgive me, I'll wait to look at the patch > until we resolve the issues above. Well, certainly fixing ptrace() to work with DSP registers one way or another for n32 can wait until we have a relevant piece of silicon and I'll sort out the numbering issue as referred to above (1). Please let me know whether there is anything else you have had in mind and I'll send a new version of the patch shortly. Maciej ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-27 17:13 ` Maciej W. Rozycki @ 2008-03-27 17:46 ` Daniel Jacobowitz 2008-03-28 17:16 ` Maciej W. Rozycki 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2008-03-27 17:46 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Thu, Mar 27, 2008 at 05:13:03PM +0000, Maciej W. Rozycki wrote: > As far as I know it both YAMON and the SDE library debugging stub both > provide access to cp0 registers. I may not have time to check whether > they use the problematic packets, but with the code shuffle above (1) this > becomes a non-issue for this lone change. Great. So we can figure out what register layout they need and provide it explicitly. > > Does the MDI patch rely on passing "1" to the new function? If not, > > please just use regcache_invalidate. Speaking about good engineering > > Well, it passes "-1", so it is reasonable and not exactly the same as > regcache_invalidate(). Hmm, that is more reasonable. That meaning is documented in a comment, but not used anywhere else in present GDB, though, and none of the callers of regcache_valid_p expect it - so I'd be dubious of it actually working! If we want it to work there's going to be an ugly audit involved. May I ask you to save this function for later, and return to it along with the MDI patch? I will look at that as soon as I can find a moment, it's next after this one. > > Then an N32 GDB is not going to be able to read these registers unless > > we create a regset for them, FYI. ptrace takes and returns longs on > > n32, not long longs. I experimented with using long long, but it was > > a terrible mess. > > Hmm, I have had a peek at the kernel and it looks like PTRACE_POKEUSR and > PTRACE_PEEKUSR requests are completely broken for n32; it's just that we > have a way around it for GP/FP registers... Yes, pretty much. Other platforms know how to fetch larger than word-sized registers using these functions but they do it by using register offsets in a hypothetical "struct user" as arguments, instead of indexes. The fact that we pass 30 and 31 to get $30 and $31 really messes things up when you want the other half of $30. > Well, certainly fixing ptrace() to work with DSP registers one way or > another for n32 can wait until we have a relevant piece of silicon and > I'll sort out the numbering issue as referred to above (1). Please let me > know whether there is anything else you have had in mind and I'll send a > new version of the patch shortly. Nope, I'm otherwise happy. Thanks for your patience. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-27 17:46 ` Daniel Jacobowitz @ 2008-03-28 17:16 ` Maciej W. Rozycki 2008-03-31 10:50 ` Maciej W. Rozycki 0 siblings, 1 reply; 13+ messages in thread From: Maciej W. Rozycki @ 2008-03-28 17:16 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Thu, 27 Mar 2008, Daniel Jacobowitz wrote: > > Well, it passes "-1", so it is reasonable and not exactly the same as > > regcache_invalidate(). > > Hmm, that is more reasonable. That meaning is documented in a > comment, but not used anywhere else in present GDB, though, and none > of the callers of regcache_valid_p expect it - so I'd be dubious of it > actually working! If we want it to work there's going to be an > ugly audit involved. > > May I ask you to save this function for later, and return to it along > with the MDI patch? I will look at that as soon as I can find a > moment, it's next after this one. Well, I did this with the previous version of the patch already. WRT the MDI patch -- changes to this one imply a couple of updates to there for it to build at the very least. I will post the current version separately, but I will not be able to do any further updates. > > Hmm, I have had a peek at the kernel and it looks like PTRACE_POKEUSR and > > PTRACE_PEEKUSR requests are completely broken for n32; it's just that we > > have a way around it for GP/FP registers... > > Yes, pretty much. Other platforms know how to fetch larger than > word-sized registers using these functions but they do it by using > register offsets in a hypothetical "struct user" as arguments, instead > of indexes. The fact that we pass 30 and 31 to get $30 and $31 really > messes things up when you want the other half of $30. I suppose n32 support in the kernel and then GDB could be updated to use such an approach too -- it looks like inf-ptrace.c supports it already as is and given n32 is broken in this respect, nobody could have relied on the current ABI. > > Well, certainly fixing ptrace() to work with DSP registers one way or > > another for n32 can wait until we have a relevant piece of silicon and > > I'll sort out the numbering issue as referred to above (1). Please let me > > know whether there is anything else you have had in mind and I'll send a > > new version of the patch shortly. > > Nope, I'm otherwise happy. Thanks for your patience. Well, it's my time, not patience that's limited I am afraid... Here's an updated version hopefully taking all the issues covered into account. I have tested it with the mipsisa32-sde-elf target using the mips-sim-sde32/-EB/-march=mips32r2 and mips-sim-sde32/-EL/-march=mips32r2 boards with no regressions. I have tested it natively with the mips-linux-gnu host using a MIPS64 processor (no DSP support) with no regressions. I did some basic testing the mips-linux-gnu host using a DSP-enabled MIPS32r2 processor (a 24KEf) to see whether the DSP registers are accessible and verified with a probe attached to same that values read and written under Linux actually correspond to the right hardware registers. I'll see if I manage to find enough time to run the test suite on the 24KEf, but it is slow enough I may not. 2008-03-28 Maciej W. Rozycki <macro@mips.com> Daniel Jacobowitz <drow@false.org> Chris Dearman <chris@mips.com> [mti-dsp-dbg] * features/mips-dsp.xml: New file for DSP ASE registers. * features/mips64-dsp.xml: Likewise. * features/mips-dsp-linux.xml: New file for a DSP-enabled target. * features/mips64-dsp-linux.xml: Likewise. * features/mips-dsp-linux.c: New generated file. * features/mips64-dsp-linux.c: Likewise. * regformats/mips-dsp-linux.dat: Likewise. * regformats/mips64-dsp-linux.dat: 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_RESTART_REGNUM): Set from MIPS_NUM_REGS. * mips-tdep.c (NUM_MIPS_PROCESSOR_REGS): Set from MIPS_LAST_CP0SEL0_REGNUM. (mips_generic_reg_names): Remove trailing null strings. (mips_tx39_reg_names): Likewise. (mips_r3041_reg_names): Add missing size specifier. (mips_register_name): Check for a null pointer in mips_processor_reg_names and return an empty string. Handle missing XML-described registers. (mips_register_type): Handle the DSP control register. (mips_pseudo_register_type): Likewise. (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. Use MIPS_NUM_REGS and NUM_MIPS_PROCESSOR_REGS as appropriate. * mips-tdep.h (struct mips_regnum): Add dspacc/dspctl offsets. (MIPS_DSPACC_REGNUM): Offset to DSP accumulator registers. (MIPS_DSPCTL_REGNUM): Offset to the DSP control register. (MIPS_NUM_REGS): New value for total register count. * 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.texinfo (MIPS Features): Document org.gnu.gdb.mips.dsp. OK to apply? Maciej 14607.diff Index: binutils-quilt/src/gdb/mips-linux-nat.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-linux-nat.c 2008-03-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-nat.c 2008-03-28 12:53:25.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,21 @@ 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 + 10) + { + if ((regno - mips_regnum (gdbarch)->dspacc) % 3 == 0) + regaddr = (CORE_ADDR) -1; /* ACX registers unhandled. */ + else + regaddr = DSP_BASE + + (regno - mips_regnum (gdbarch)->dspacc) + - (regno - mips_regnum (gdbarch)->dspacc) / 3 + - 1; + } + 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 +138,21 @@ 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 + 10) + { + if ((regno - mips_regnum (gdbarch)->dspacc) % 3 == 0) + regaddr = (CORE_ADDR) -1; /* ACX registers unhandled. */ + else + regaddr = DSP_BASE + + (regno - mips_regnum (gdbarch)->dspacc) + - (regno - mips_regnum (gdbarch)->dspacc) / 3 + - 1; + } + 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 +226,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 +240,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 + 10) + 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 +291,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 + 10; + 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 +327,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 + 10) + 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 +369,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 + 10; + 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 +431,23 @@ 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 +469,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-28 12:53:25.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.c 2008-03-28 12:53:25.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,14 +446,12 @@ "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. */ -static const char *mips_r3041_reg_names[] = { +static const char *mips_r3041_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", @@ -474,7 +472,7 @@ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "config", "cache", "debug", "depc", "epc", "" + "", "", "config", "cache", "debug", "depc", "epc", }; /* Names of IRIX registers. */ @@ -528,11 +526,15 @@ } 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); @@ -741,9 +743,12 @@ { /* The cooked or ABI registers. These are sized according to the ABI (with a few complications). */ - if (regnum >= (gdbarch_num_regs (gdbarch) - + mips_regnum (gdbarch)->fp_control_status) - && regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM) + if ((regnum >= (gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->fp_control_status) + && regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM) + || (mips_regnum (gdbarch)->dspctl != 0 + && regnum == (gdbarch_num_regs (gdbarch) + + mips_regnum (gdbarch)->dspctl))) /* The pseudo/cooked view of the embedded registers is always 32-bit. The raw view is handled below. */ return builtin_type_int32; @@ -787,7 +792,10 @@ do not try to convert between FPU layouts. */ return rawtype; - if (rawnum >= MIPS_EMBED_FP0_REGNUM + 32 && rawnum <= MIPS_LAST_EMBED_REGNUM) + if ((rawnum >= MIPS_EMBED_FP0_REGNUM + 32 + && rawnum <= MIPS_LAST_EMBED_REGNUM) + || (mips_regnum (gdbarch)->dspctl != 0 + && rawnum == mips_regnum (gdbarch)->dspctl)) { /* The pseudo/cooked view of embedded registers is always 32-bit, even if the target transfers 64-bit values for them. @@ -5089,6 +5097,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? */ @@ -5112,6 +5122,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? */ @@ -5249,6 +5261,7 @@ 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)) @@ -5345,6 +5358,37 @@ 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. */ } @@ -5600,7 +5644,9 @@ regnum->fp0 = MIPS_EMBED_FP0_REGNUM; regnum->fp_control_status = 70; regnum->fp_implementation_revision = 71; - num_regs = MIPS_LAST_EMBED_REGNUM + 1; + regnum->dspacc = have_dsp ? MIPS_DSPACC_REGNUM : 0; + regnum->dspctl = have_dsp ? MIPS_DSPCTL_REGNUM : 0; + num_regs = MIPS_NUM_REGS; reg_names = NULL; } else if (info.osabi == GDB_OSABI_IRIX) @@ -5613,6 +5659,8 @@ 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; } @@ -5626,7 +5674,9 @@ regnum->fp0 = MIPS_EMBED_FP0_REGNUM; regnum->fp_control_status = 70; regnum->fp_implementation_revision = 71; - num_regs = 90; + regnum->dspacc = 0; + regnum->dspctl = 0; + num_regs = NUM_MIPS_PROCESSOR_REGS + 32; if (info.bfd_arch_info != NULL && info.bfd_arch_info->mach == bfd_mach_mips3900) reg_names = mips_tx39_reg_names; Index: binutils-quilt/src/gdb/mips-tdep.h =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.h 2008-03-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.h 2008-03-28 12:53:25.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); @@ -77,7 +79,12 @@ 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 = 100, /* DSP DSPCTL register. */ + MIPS_NUM_REGS }; /* 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-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.c 2008-03-28 12:53:25.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-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.h 2008-03-28 12:53:25.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 @@ -94,7 +96,7 @@ 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: 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-28 12:53:25.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"/> + <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> 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-28 12:53:25.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"/> + <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: binutils-quilt/src/gdb/Makefile.in =================================================================== --- binutils-quilt.orig/src/gdb/Makefile.in 2008-03-28 12:53:25.000000000 +0000 +++ binutils-quilt/src/gdb/Makefile.in 2008-03-28 12:53:25.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) @@ -2473,7 +2475,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-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/features/Makefile 2008-03-28 12:53:25.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-28 12:53:25.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.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: 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-28 12:53:25.000000000 +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. --> + +<!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"/> + + <feature name="org.gnu.gdb.mips.linux"> + <reg name="restart" bitsize="32" group="system"/> + </feature> + + <xi:include href="mips-dsp.xml"/> +</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-28 12:53:25.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.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: 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-28 12:53:25.000000000 +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. --> + +<!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"/> + + <feature name="org.gnu.gdb.mips.linux"> + <reg name="restart" bitsize="64" group="system"/> + </feature> + + <xi:include href="mips64-dsp.xml"/> +</target> Index: binutils-quilt/src/gdb/doc/gdb.texinfo =================================================================== --- binutils-quilt.orig/src/gdb/doc/gdb.texinfo 2008-03-28 12:53:04.000000000 +0000 +++ binutils-quilt/src/gdb/doc/gdb.texinfo 2008-03-28 12:53:26.000000000 +0000 @@ -26881,6 +26881,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: binutils-quilt/src/gdb/regformats/mips-dsp-linux.dat =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/regformats/mips-dsp-linux.dat 2008-03-28 12:53:26.000000000 +0000 @@ -0,0 +1,84 @@ +# DO NOT EDIT: generated from mips-dsp-linux.xml +name:mips_dsp_linux +xmltarget:mips-dsp-linux.xml +expedite:r29,pc +32:r0 +32:r1 +32:r2 +32:r3 +32:r4 +32:r5 +32:r6 +32:r7 +32:r8 +32:r9 +32:r10 +32:r11 +32:r12 +32:r13 +32:r14 +32:r15 +32:r16 +32:r17 +32:r18 +32:r19 +32:r20 +32:r21 +32:r22 +32:r23 +32:r24 +32:r25 +32:r26 +32:r27 +32:r28 +32:r29 +32:r30 +32:r31 +32:status +32:lo +32:hi +32:badvaddr +32:cause +32:pc +32:f0 +32:f1 +32:f2 +32:f3 +32:f4 +32:f5 +32:f6 +32:f7 +32:f8 +32:f9 +32:f10 +32:f11 +32:f12 +32:f13 +32:f14 +32:f15 +32:f16 +32:f17 +32:f18 +32:f19 +32:f20 +32:f21 +32:f22 +32:f23 +32:f24 +32:f25 +32:f26 +32:f27 +32:f28 +32:f29 +32:f30 +32:f31 +32:fcsr +32:fir +32:restart +32:hi1 +32:lo1 +32:hi2 +32:lo2 +32:hi3 +32:lo3 +32:dspctl Index: binutils-quilt/src/gdb/regformats/mips64-dsp-linux.dat =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/regformats/mips64-dsp-linux.dat 2008-03-28 12:53:26.000000000 +0000 @@ -0,0 +1,84 @@ +# DO NOT EDIT: generated from mips64-dsp-linux.xml +name:mips64_dsp_linux +xmltarget:mips64-dsp-linux.xml +expedite:r29,pc +64:r0 +64:r1 +64:r2 +64:r3 +64:r4 +64:r5 +64:r6 +64:r7 +64:r8 +64:r9 +64:r10 +64:r11 +64:r12 +64:r13 +64:r14 +64:r15 +64:r16 +64:r17 +64:r18 +64:r19 +64:r20 +64:r21 +64:r22 +64:r23 +64:r24 +64:r25 +64:r26 +64:r27 +64:r28 +64:r29 +64:r30 +64:r31 +64:status +64:lo +64:hi +64:badvaddr +64:cause +64:pc +64:f0 +64:f1 +64:f2 +64:f3 +64:f4 +64:f5 +64:f6 +64:f7 +64:f8 +64:f9 +64:f10 +64:f11 +64:f12 +64:f13 +64:f14 +64:f15 +64:f16 +64:f17 +64:f18 +64:f19 +64:f20 +64:f21 +64:f22 +64:f23 +64:f24 +64:f25 +64:f26 +64:f27 +64:f28 +64:f29 +64:f30 +64:f31 +64:fcsr +64:fir +64:restart +64:hi1 +64:lo1 +64:hi2 +64:lo2 +64:hi3 +64:lo3 +32:dspctl ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: MIPS: Handle the DSP registers 2008-03-28 17:16 ` Maciej W. Rozycki @ 2008-03-31 10:50 ` Maciej W. Rozycki 0 siblings, 0 replies; 13+ messages in thread From: Maciej W. Rozycki @ 2008-03-31 10:50 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Chris Dearman, Maciej W. Rozycki On Fri, 28 Mar 2008, Maciej W. Rozycki wrote: > registers. I'll see if I manage to find enough time to run the test suite > on the 24KEf, but it is slow enough I may not. Well, it has finished now and except from a few additional timeouts on some particularly slow cases, no problems. Maciej ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-03-31 10:50 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-12-10 16:33 MIPS: Handle the DSP registers Maciej W. Rozycki 2007-12-18 13:42 ` Daniel Jacobowitz 2007-12-18 13:56 ` Nigel Stephens 2007-12-18 15:15 ` Daniel Jacobowitz 2007-12-18 16:06 ` Nigel Stephens 2008-03-19 17:07 ` Maciej W. Rozycki 2008-03-21 18:44 ` Daniel Jacobowitz 2008-03-26 16:59 ` Maciej W. Rozycki 2008-03-26 17:59 ` Daniel Jacobowitz 2008-03-27 17:13 ` Maciej W. Rozycki 2008-03-27 17:46 ` Daniel Jacobowitz 2008-03-28 17:16 ` Maciej W. Rozycki 2008-03-31 10:50 ` Maciej W. Rozycki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox