* Makefile.in (mips-tdep.o): Update.

* mips-tdep.c (struct register_alias, mips_o32_aliases)
	(mips_n32_n64_aliases, mips_register_aliases): New.
	(mips_register_name): Call tdesc_register_name.
	(mips_tdesc_register_reggroup_p): New.
	(mips_pseudo_register_type, value_of_mips_user_reg): New.
	(mips_gdbarch_init): Add target-described register support.
	Register aliases for register names.
	* target-descriptions.c (tdesc_register_name): Make global.
	(tdesc_register_in_reggroup_p): New function, broken out from
	tdesc_register_reggroup_p.
	(tdesc_register_reggroup_p): Use it.
	* target-descriptions.h (tdesc_register_name)
	(tdesc_register_in_reggroup_p): New prototypes.
	* NEWS: Correct formatting.  Mention MIPS register support.
	* features/mips-cp0.xml, features/mips-fpu.xml,
	features/mips64-cp0.xml, gdb/features/mips64-fpu.xml, mips-cpu.xml,
	features/mips64-cpu.xml: New files.

	* gdb.xml/tdesc-regs.exp: Add MIPS support.  Allow multiple
	required features to be included.

	* gdb.texinfo (MIPS Features): New subsection.
This commit is contained in:
Daniel Jacobowitz 2007-06-13 18:27:00 +00:00
parent 17a912b682
commit f8b73d13b7
16 changed files with 627 additions and 27 deletions

View File

@ -1,3 +1,24 @@
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (mips-tdep.o): Update.
* mips-tdep.c (struct register_alias, mips_o32_aliases)
(mips_n32_n64_aliases, mips_register_aliases): New.
(mips_register_name): Call tdesc_register_name.
(mips_tdesc_register_reggroup_p): New.
(mips_pseudo_register_type, value_of_mips_user_reg): New.
(mips_gdbarch_init): Add target-described register support.
Register aliases for register names.
* target-descriptions.c (tdesc_register_name): Make global.
(tdesc_register_in_reggroup_p): New function, broken out from
tdesc_register_reggroup_p.
(tdesc_register_reggroup_p): Use it.
* target-descriptions.h (tdesc_register_name)
(tdesc_register_in_reggroup_p): New prototypes.
* NEWS: Correct formatting. Mention MIPS register support.
* features/mips-cp0.xml, features/mips-fpu.xml,
features/mips64-cp0.xml, gdb/features/mips64-fpu.xml, mips-cpu.xml,
features/mips64-cpu.xml: New files.
2007-06-13 Markus Deuling <deuling@de.ibm.com>
* gdbarch.sh (TARGET_ADDR_BIT): Replace by gdbarch_addr_bit.

View File

@ -2361,7 +2361,7 @@ mips-tdep.o: mips-tdep.c $(defs_h) $(gdb_string_h) $(gdb_assert_h) \
$(elf_bfd_h) $(symcat_h) $(sim_regno_h) $(dis_asm_h) \
$(frame_unwind_h) $(frame_base_h) $(trad_frame_h) $(infcall_h) \
$(floatformat_h) $(remote_h) $(target_descriptions_h) \
$(dwarf2_frame_h)
$(dwarf2_frame_h) $(user_regs_h)
memory-map.o: memory-map.c $(defs_h) $(memory_map_h) $(xml_support_h) \
$(gdb_assert_h) $(exceptions_h) $(gdb_string_h)
mn10300-linux-tdep.o: mn10300-linux-tdep.c $(defs_h) $(gdbcore_h) \

View File

@ -20,11 +20,11 @@ target's overall architecture. GDB can read a description from
a local file or over the remote serial protocol.
* Arrays of explicitly SIGNED or UNSIGNED CHARs are now printed as arrays
of numbers.
of numbers.
* Target descriptions can now describe target-specific registers,
for architectures which have implemented the support (currently
only ARM).
only ARM and MIPS).
* GDB and the GDB remote stub, gdbserver, now support the XScale
iWMMXt coprocessor.

View File

@ -1,3 +1,7 @@
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (MIPS Features): New subsection.
2007-06-12 Ulrich Weigand <uweigand@de.ibm.com>
Markus Deuling <deuling@de.ibm.com>

View File

@ -25767,6 +25767,23 @@ it should contain at least registers @samp{wR0} through @samp{wR15} and
@samp{wCGR0} through @samp{wCGR3}. The @samp{wCID}, @samp{wCon},
@samp{wCSSF}, and @samp{wCASF} registers are optional.
@subsection MIPS Features
@cindex target descriptions, MIPS features
The @samp{org.gnu.gdb.mips.cpu} feature is required for MIPS targets.
It should contain registers @samp{r0} through @samp{r31}, @samp{lo},
@samp{hi}, and @samp{pc}. They may be 32-bit or 64-bit depending
on the target.
The @samp{org.gnu.gdb.mips.cp0} feature is also required. It should
contain at least the @samp{status}, @samp{badvaddr}, and @samp{cause}
registers. They may be 32-bit or 64-bit depending on the target.
The @samp{org.gnu.gdb.mips.fpu} feature is currently required, though
it may be optional in a future version of @value{GDBN}. It should
contain registers @samp{f0} through @samp{f31}, @samp{fcsr}, and
@samp{fir}. They may be 32-bit or 64-bit depending on the target.
@include gpl.texi
@raisesections

13
gdb/features/mips-cp0.xml Normal file
View File

@ -0,0 +1,13 @@
<?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.cp0">
<reg name="status" bitsize="32" regnum="32"/>
<reg name="badvaddr" bitsize="32" regnum="35"/>
<reg name="cause" bitsize="32" regnum="36"/>
</feature>

46
gdb/features/mips-cpu.xml Normal file
View File

@ -0,0 +1,46 @@
<?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.cpu">
<reg name="r0" bitsize="32"/>
<reg name="r1" bitsize="32"/>
<reg name="r2" bitsize="32"/>
<reg name="r3" bitsize="32"/>
<reg name="r4" bitsize="32"/>
<reg name="r5" bitsize="32"/>
<reg name="r6" bitsize="32"/>
<reg name="r7" bitsize="32"/>
<reg name="r8" bitsize="32"/>
<reg name="r9" bitsize="32"/>
<reg name="r10" bitsize="32"/>
<reg name="r11" bitsize="32"/>
<reg name="r12" bitsize="32"/>
<reg name="r13" bitsize="32"/>
<reg name="r14" bitsize="32"/>
<reg name="r15" bitsize="32"/>
<reg name="r16" bitsize="32"/>
<reg name="r17" bitsize="32"/>
<reg name="r18" bitsize="32"/>
<reg name="r19" bitsize="32"/>
<reg name="r20" bitsize="32"/>
<reg name="r21" bitsize="32"/>
<reg name="r22" bitsize="32"/>
<reg name="r23" bitsize="32"/>
<reg name="r24" bitsize="32"/>
<reg name="r25" bitsize="32"/>
<reg name="r26" bitsize="32"/>
<reg name="r27" bitsize="32"/>
<reg name="r28" bitsize="32"/>
<reg name="r29" bitsize="32"/>
<reg name="r30" bitsize="32"/>
<reg name="r31" bitsize="32"/>
<reg name="lo" bitsize="32" regnum="33"/>
<reg name="hi" bitsize="32" regnum="34"/>
<reg name="pc" bitsize="32" regnum="37"/>
</feature>

45
gdb/features/mips-fpu.xml Normal file
View File

@ -0,0 +1,45 @@
<?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.fpu">
<reg name="f0" bitsize="32" type="ieee_single"/>
<reg name="f1" bitsize="32" type="ieee_single"/>
<reg name="f2" bitsize="32" type="ieee_single"/>
<reg name="f3" bitsize="32" type="ieee_single"/>
<reg name="f4" bitsize="32" type="ieee_single"/>
<reg name="f5" bitsize="32" type="ieee_single"/>
<reg name="f6" bitsize="32" type="ieee_single"/>
<reg name="f7" bitsize="32" type="ieee_single"/>
<reg name="f8" bitsize="32" type="ieee_single"/>
<reg name="f9" bitsize="32" type="ieee_single"/>
<reg name="f10" bitsize="32" type="ieee_single"/>
<reg name="f11" bitsize="32" type="ieee_single"/>
<reg name="f12" bitsize="32" type="ieee_single"/>
<reg name="f13" bitsize="32" type="ieee_single"/>
<reg name="f14" bitsize="32" type="ieee_single"/>
<reg name="f15" bitsize="32" type="ieee_single"/>
<reg name="f16" bitsize="32" type="ieee_single"/>
<reg name="f17" bitsize="32" type="ieee_single"/>
<reg name="f18" bitsize="32" type="ieee_single"/>
<reg name="f19" bitsize="32" type="ieee_single"/>
<reg name="f20" bitsize="32" type="ieee_single"/>
<reg name="f21" bitsize="32" type="ieee_single"/>
<reg name="f22" bitsize="32" type="ieee_single"/>
<reg name="f23" bitsize="32" type="ieee_single"/>
<reg name="f24" bitsize="32" type="ieee_single"/>
<reg name="f25" bitsize="32" type="ieee_single"/>
<reg name="f26" bitsize="32" type="ieee_single"/>
<reg name="f27" bitsize="32" type="ieee_single"/>
<reg name="f28" bitsize="32" type="ieee_single"/>
<reg name="f29" bitsize="32" type="ieee_single"/>
<reg name="f30" bitsize="32" type="ieee_single"/>
<reg name="f31" bitsize="32" type="ieee_single"/>
<reg name="fcsr" bitsize="32" group="float"/>
<reg name="fir" bitsize="32" group="float"/>
</feature>

View File

@ -0,0 +1,13 @@
<?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.cp0">
<reg name="status" bitsize="64" regnum="32"/>
<reg name="badvaddr" bitsize="64" regnum="35"/>
<reg name="cause" bitsize="64" regnum="36"/>
</feature>

View File

@ -0,0 +1,46 @@
<?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.cpu">
<reg name="r0" bitsize="64"/>
<reg name="r1" bitsize="64"/>
<reg name="r2" bitsize="64"/>
<reg name="r3" bitsize="64"/>
<reg name="r4" bitsize="64"/>
<reg name="r5" bitsize="64"/>
<reg name="r6" bitsize="64"/>
<reg name="r7" bitsize="64"/>
<reg name="r8" bitsize="64"/>
<reg name="r9" bitsize="64"/>
<reg name="r10" bitsize="64"/>
<reg name="r11" bitsize="64"/>
<reg name="r12" bitsize="64"/>
<reg name="r13" bitsize="64"/>
<reg name="r14" bitsize="64"/>
<reg name="r15" bitsize="64"/>
<reg name="r16" bitsize="64"/>
<reg name="r17" bitsize="64"/>
<reg name="r18" bitsize="64"/>
<reg name="r19" bitsize="64"/>
<reg name="r20" bitsize="64"/>
<reg name="r21" bitsize="64"/>
<reg name="r22" bitsize="64"/>
<reg name="r23" bitsize="64"/>
<reg name="r24" bitsize="64"/>
<reg name="r25" bitsize="64"/>
<reg name="r26" bitsize="64"/>
<reg name="r27" bitsize="64"/>
<reg name="r28" bitsize="64"/>
<reg name="r29" bitsize="64"/>
<reg name="r30" bitsize="64"/>
<reg name="r31" bitsize="64"/>
<reg name="lo" bitsize="64" regnum="33"/>
<reg name="hi" bitsize="64" regnum="34"/>
<reg name="pc" bitsize="64" regnum="37"/>
</feature>

View File

@ -0,0 +1,45 @@
<?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.fpu">
<reg name="f0" bitsize="64" type="ieee_double"/>
<reg name="f1" bitsize="64" type="ieee_double"/>
<reg name="f2" bitsize="64" type="ieee_double"/>
<reg name="f3" bitsize="64" type="ieee_double"/>
<reg name="f4" bitsize="64" type="ieee_double"/>
<reg name="f5" bitsize="64" type="ieee_double"/>
<reg name="f6" bitsize="64" type="ieee_double"/>
<reg name="f7" bitsize="64" type="ieee_double"/>
<reg name="f8" bitsize="64" type="ieee_double"/>
<reg name="f9" bitsize="64" type="ieee_double"/>
<reg name="f10" bitsize="64" type="ieee_double"/>
<reg name="f11" bitsize="64" type="ieee_double"/>
<reg name="f12" bitsize="64" type="ieee_double"/>
<reg name="f13" bitsize="64" type="ieee_double"/>
<reg name="f14" bitsize="64" type="ieee_double"/>
<reg name="f15" bitsize="64" type="ieee_double"/>
<reg name="f16" bitsize="64" type="ieee_double"/>
<reg name="f17" bitsize="64" type="ieee_double"/>
<reg name="f18" bitsize="64" type="ieee_double"/>
<reg name="f19" bitsize="64" type="ieee_double"/>
<reg name="f20" bitsize="64" type="ieee_double"/>
<reg name="f21" bitsize="64" type="ieee_double"/>
<reg name="f22" bitsize="64" type="ieee_double"/>
<reg name="f23" bitsize="64" type="ieee_double"/>
<reg name="f24" bitsize="64" type="ieee_double"/>
<reg name="f25" bitsize="64" type="ieee_double"/>
<reg name="f26" bitsize="64" type="ieee_double"/>
<reg name="f27" bitsize="64" type="ieee_double"/>
<reg name="f28" bitsize="64" type="ieee_double"/>
<reg name="f29" bitsize="64" type="ieee_double"/>
<reg name="f30" bitsize="64" type="ieee_double"/>
<reg name="f31" bitsize="64" type="ieee_double"/>
<reg name="fcsr" bitsize="64" group="float"/>
<reg name="fir" bitsize="64" group="float"/>
</feature>

View File

@ -58,6 +58,7 @@
#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2-frame.h"
#include "user-regs.h"
static const struct objfile_data *mips_pdr_data;
@ -94,6 +95,55 @@ static const char *mips_abi_strings[] = {
NULL
};
/* The standard register names, and all the valid aliases for them. */
struct register_alias
{
const char *name;
int regnum;
};
/* Aliases for o32 and most other ABIs. */
const struct register_alias mips_o32_aliases[] = {
{ "ta0", 12 },
{ "ta1", 13 },
{ "ta2", 14 },
{ "ta3", 15 }
};
/* Aliases for n32 and n64. */
const struct register_alias mips_n32_n64_aliases[] = {
{ "ta0", 8 },
{ "ta1", 9 },
{ "ta2", 10 },
{ "ta3", 11 }
};
/* Aliases for ABI-independent registers. */
const struct register_alias mips_register_aliases[] = {
/* The architecture manuals specify these ABI-independent names for
the GPRs. */
#define R(n) { "r" #n, n }
R(0), R(1), R(2), R(3), R(4), R(5), R(6), R(7),
R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
#undef R
/* k0 and k1 are sometimes called these instead (for "kernel
temp"). */
{ "kt0", 26 },
{ "kt1", 27 },
/* This is the traditional GDB name for the CP0 status register. */
{ "sr", MIPS_PS_REGNUM },
/* This is the traditional GDB name for the CP0 BadVAddr register. */
{ "bad", MIPS_EMBED_BADVADDR_REGNUM },
/* This is the traditional GDB name for the FCSR. */
{ "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
};
/* Some MIPS boards don't support floating point while others only
support single-precision floating-point operations. */
@ -509,6 +559,8 @@ mips_register_name (int regno)
else
return mips_gpr_names[rawnum];
}
else if (tdesc_has_registers (gdbarch_target_desc (current_gdbarch)))
return tdesc_register_name (rawnum);
else if (32 <= rawnum && rawnum < gdbarch_num_regs (current_gdbarch))
{
gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
@ -557,6 +609,35 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
return 0;
}
/* Return the groups that a MIPS register can be categorised into.
This version is only used if we have a target description which
describes real registers (and their groups). */
static int
mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
struct reggroup *reggroup)
{
int rawnum = regnum % gdbarch_num_regs (gdbarch);
int pseudo = regnum / gdbarch_num_regs (gdbarch);
int ret;
/* Only save, restore, and display the pseudo registers. Need to
make certain that any code extracting register values from a
saved register cache also uses pseudo registers.
Note: saving and restoring the pseudo registers is slightly
strange; if we have 64 bits, we should save and restore all
64 bits. But this is hard and has little benefit. */
if (!pseudo)
return 0;
ret = tdesc_register_in_reggroup_p (gdbarch, rawnum, reggroup);
if (ret != -1)
return ret;
return mips_register_reggroup_p (gdbarch, regnum, reggroup);
}
/* Map the symbol table registers which live in the range [1 *
gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
registers. Take care of alignment and size problems. */
@ -721,6 +802,59 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
}
}
/* Return the GDB type for the pseudo register REGNUM, which is the
ABI-level view. This function is only called if there is a target
description which includes registers, so we know precisely the
types of hardware registers. */
static struct type *
mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
const int num_regs = gdbarch_num_regs (gdbarch);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int rawnum = regnum % num_regs;
struct type *rawtype;
gdb_assert (regnum >= num_regs && regnum < 2 * num_regs);
/* Absent registers are still absent. */
rawtype = gdbarch_register_type (gdbarch, rawnum);
if (TYPE_LENGTH (rawtype) == 0)
return rawtype;
if (rawnum >= MIPS_EMBED_FP0_REGNUM && rawnum < MIPS_EMBED_FP0_REGNUM + 32)
/* Present the floating point registers however the hardware did;
do not try to convert between FPU layouts. */
return rawtype;
if (rawnum >= MIPS_EMBED_FP0_REGNUM + 32 && rawnum <= MIPS_LAST_EMBED_REGNUM)
{
/* The pseudo/cooked view of embedded registers is always
32-bit, even if the target transfers 64-bit values for them.
New targets relying on XML descriptions should only transfer
the necessary 32 bits, but older versions of GDB expected 64,
so allow the target to provide 64 bits without interfering
with the displayed type. */
return builtin_type_int32;
}
/* Use pointer types for registers if we can. For n32 we can not,
since we do not have a 64-bit pointer type. */
if (mips_abi_regsize (gdbarch) == TYPE_LENGTH (builtin_type_void_data_ptr))
{
if (rawnum == MIPS_SP_REGNUM || rawnum == MIPS_EMBED_BADVADDR_REGNUM)
return builtin_type_void_data_ptr;
else if (rawnum == MIPS_EMBED_PC_REGNUM)
return builtin_type_void_func_ptr;
}
if (mips_abi_regsize (gdbarch) == 4 && TYPE_LENGTH (rawtype) == 8
&& rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_EMBED_PC_REGNUM)
return builtin_type_int32;
/* For all other registers, pass through the hardware type. */
return rawtype;
}
/* Should the upper word of 64-bit addresses be zeroed? */
enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO;
@ -4724,6 +4858,13 @@ mips_register_g_packet_guesses (struct gdbarch *gdbarch)
/* Otherwise we don't have a useful guess. */
}
static struct value *
value_of_mips_user_reg (struct frame_info *frame, const void *baton)
{
const int *reg_p = baton;
return value_of_register (*reg_p, frame);
}
static struct gdbarch *
mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
@ -4731,8 +4872,108 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
struct gdbarch_tdep *tdep;
int elf_flags;
enum mips_abi mips_abi, found_abi, wanted_abi;
int num_regs;
int i, num_regs;
enum mips_fpu_type fpu_type;
struct tdesc_arch_data *tdesc_data = NULL;
/* Check any target description for validity. */
if (tdesc_has_registers (info.target_desc))
{
static const char *const mips_gprs[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
};
static const char *const mips_fprs[] = {
"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",
};
const struct tdesc_feature *feature;
int valid_p;
feature = tdesc_find_feature (info.target_desc,
"org.gnu.gdb.mips.cpu");
if (feature == NULL)
return NULL;
tdesc_data = tdesc_data_alloc ();
valid_p = 1;
for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)
valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
mips_gprs[i]);
valid_p &= tdesc_numbered_register (feature, tdesc_data,
MIPS_EMBED_LO_REGNUM, "lo");
valid_p &= tdesc_numbered_register (feature, tdesc_data,
MIPS_EMBED_HI_REGNUM, "hi");
valid_p &= tdesc_numbered_register (feature, tdesc_data,
MIPS_EMBED_PC_REGNUM, "pc");
if (!valid_p)
{
tdesc_data_cleanup (tdesc_data);
return NULL;
}
feature = tdesc_find_feature (info.target_desc,
"org.gnu.gdb.mips.cp0");
if (feature == NULL)
{
tdesc_data_cleanup (tdesc_data);
return NULL;
}
valid_p = 1;
valid_p &= tdesc_numbered_register (feature, tdesc_data,
MIPS_EMBED_BADVADDR_REGNUM,
"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");
if (!valid_p)
{
tdesc_data_cleanup (tdesc_data);
return NULL;
}
/* FIXME drow/2007-05-17: The FPU should be optional. The MIPS
backend is not prepared for that, though. */
feature = tdesc_find_feature (info.target_desc,
"org.gnu.gdb.mips.fpu");
if (feature == NULL)
{
tdesc_data_cleanup (tdesc_data);
return NULL;
}
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]);
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");
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. */
}
/* First of all, extract the elf_flags, if available. */
if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
@ -4876,7 +5117,11 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
&& tdesc_property (info.target_desc, PROPERTY_GP32) != NULL
&& mips_abi != MIPS_ABI_EABI32
&& mips_abi != MIPS_ABI_O32)
return NULL;
{
if (tdesc_data != NULL)
tdesc_data_cleanup (tdesc_data);
return NULL;
}
/* try to find a pre-existing architecture */
for (arches = gdbarch_list_lookup_by_info (arches, &info);
@ -4897,6 +5142,9 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Be pedantic about which FPU is selected. */
if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
continue;
if (tdesc_data != NULL)
tdesc_data_cleanup (tdesc_data);
return arches->gdbarch;
}
@ -4944,7 +5192,20 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
const char **reg_names;
struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
struct mips_regnum);
if (info.osabi == GDB_OSABI_IRIX)
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;
@ -5208,6 +5469,37 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
frame_base_append_sniffer (gdbarch, mips_insn16_frame_base_sniffer);
frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);
if (tdesc_data)
{
set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
tdesc_use_registers (gdbarch, tdesc_data);
/* Override the normal target description methods to handle our
dual real and pseudo registers. */
set_gdbarch_register_name (gdbarch, mips_register_name);
set_gdbarch_register_reggroup_p (gdbarch, mips_tdesc_register_reggroup_p);
num_regs = gdbarch_num_regs (gdbarch);
set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
set_gdbarch_pc_regnum (gdbarch, tdep->regnum->pc + num_regs);
set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
}
/* Add ABI-specific aliases for the registers. */
if (mips_abi == MIPS_ABI_N32 || mips_abi == MIPS_ABI_N64)
for (i = 0; i < ARRAY_SIZE (mips_n32_n64_aliases); i++)
user_reg_add (gdbarch, mips_n32_n64_aliases[i].name,
value_of_mips_user_reg, &mips_n32_n64_aliases[i].regnum);
else
for (i = 0; i < ARRAY_SIZE (mips_o32_aliases); i++)
user_reg_add (gdbarch, mips_o32_aliases[i].name,
value_of_mips_user_reg, &mips_o32_aliases[i].regnum);
/* Add some other standard aliases. */
for (i = 0; i < ARRAY_SIZE (mips_register_aliases); i++)
user_reg_add (gdbarch, mips_register_aliases[i].name,
value_of_mips_user_reg, &mips_register_aliases[i].regnum);
return gdbarch;
}

View File

@ -486,7 +486,10 @@ tdesc_find_register (struct gdbarch *gdbarch, int regno)
return NULL;
}
static const char *
/* Return the name of register REGNO, from the target description or
from an architecture-provided pseudo_register_name method. */
const char *
tdesc_register_name (int regno)
{
struct tdesc_reg *reg = tdesc_find_register (current_gdbarch, regno);
@ -582,8 +585,9 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
/* Check whether REGNUM is a member of REGGROUP. Registers from the
target description may be classified as general, float, or vector.
Registers with no group specified go to the default reggroup
function and are handled by type.
Unlike a gdbarch register_reggroup_p method, this function will
return -1 if it does not know; the caller should handle registers
with no specified group.
Arbitrary strings (other than "general", "float", and "vector")
from the description are not used; they cause the register to be
@ -594,21 +598,12 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
The save-restore flag is also implemented here. */
static int
tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
struct reggroup *reggroup)
int
tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
struct reggroup *reggroup)
{
int num_regs = gdbarch_num_regs (gdbarch);
int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
struct tdesc_reg *reg = tdesc_find_register (gdbarch, regno);
if (reg == NULL && regno >= num_regs && regno < num_regs + num_pseudo_regs)
{
struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
gdb_assert (data->pseudo_register_reggroup_p != NULL);
return data->pseudo_register_reggroup_p (gdbarch, regno, reggroup);
}
if (reg != NULL && reg->group != NULL)
{
int general_p = 0, float_p = 0, vector_p = 0;
@ -634,6 +629,32 @@ tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
&& (reggroup == save_reggroup || reggroup == restore_reggroup))
return reg->save_restore;
return -1;
}
/* Check whether REGNUM is a member of REGGROUP. Registers with no
group specified go to the default reggroup function and are handled
by type. */
static int
tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regno,
struct reggroup *reggroup)
{
int num_regs = gdbarch_num_regs (gdbarch);
int num_pseudo_regs = gdbarch_num_pseudo_regs (gdbarch);
int ret;
if (regno >= num_regs && regno < num_regs + num_pseudo_regs)
{
struct tdesc_arch_data *data = gdbarch_data (gdbarch, tdesc_data);
gdb_assert (data->pseudo_register_reggroup_p != NULL);
return data->pseudo_register_reggroup_p (gdbarch, regno, reggroup);
}
ret = tdesc_register_in_reggroup_p (gdbarch, regno, reggroup);
if (ret != -1)
return ret;
return default_register_reggroup_p (gdbarch, regno, reggroup);
}

View File

@ -140,6 +140,18 @@ const char *tdesc_feature_name (const struct tdesc_feature *feature);
struct type *tdesc_named_type (const struct tdesc_feature *feature,
const char *id);
/* Return the name of register REGNO, from the target description or
from an architecture-provided pseudo_register_name method. */
const char *tdesc_register_name (int regno);
/* Check whether REGNUM is a member of REGGROUP using the target
description. Return -1 if the target description does not
specify a group. */
int tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
struct reggroup *reggroup);
/* Methods for constructing a target description. */
struct target_desc *allocate_target_description (void);

View File

@ -1,3 +1,8 @@
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.xml/tdesc-regs.exp: Add MIPS support. Allow multiple
required features to be included.
2007-06-12 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.threads/manythreads.exp: Prevent expect buffer overflow

View File

@ -27,10 +27,13 @@ gdb_start
set core-regs ""
switch -glob -- [istarget] {
"*arm-*-*" {
set core-regs arm-core
set core-regs {arm-core.xml}
}
"xscale-*-*" {
set core-regs arm-core
set core-regs {arm-core.xml}
}
"mips*-*-*" {
set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml}
}
}
@ -56,17 +59,32 @@ gdb_test "set tdesc file $srcdir/$subdir/single-reg.xml" \
# Copy the core registers into the objdir if necessary, so that they
# will be found by <xi:include>.
file delete "core-regs.xml"
file copy "$srcdir/../features/${core-regs}.xml" "core-regs.xml"
foreach src ${core-regs} {
file delete "$src"
file copy "$srcdir/../features/$src" "$src"
}
# Similarly, we need to copy files under test into the objdir.
proc load_description { file errmsg } {
global srcdir
global subdir
global gdb_prompt
global core-regs
file delete "regs.xml"
file copy "$srcdir/$subdir/$file" "regs.xml"
set ifd [open "$srcdir/$subdir/$file" r]
set ofd [open "regs.xml" w]
while {[gets $ifd line] >= 0} {
if {[regexp {<xi:include href="core-regs.xml"/>} $line]} {
foreach src ${core-regs} {
puts $ofd " <xi:include href=\"$src\"/>"
}
} else {
puts $ofd $line
}
}
close $ifd
close $ofd
# Anchor the test output, so that error messages are detected.
set cmd "set tdesc filename regs.xml"
@ -91,5 +109,7 @@ load_description "core-only.xml" ""
# The extra register from the previous description should be gone.
gdb_test "ptype \$extrareg" "type = void"
file delete "core-regs.xml"
foreach src ${core-regs} {
file delete "$src"
}
file delete "regs.xml"