Allow PPC users to select which PPC/RS6000 variant they're debugging

at run-time.  At the moment, the only thing this affects is the
set of registers visible.
* config/rs6000/tm-rs6000.h (REGISTER_NAME): Define this as a call
to the function rs6000_register_name.
(rs6000_register_name): Include extern decl.
(NUM_REGS): Bump to 183.  What's the right way to do this?
(FIRST_UISA_SP_REGNUM, LAST_UISA_SP_REGNUM): Renamed from
FIRST_SP_REGNUM, LAST_SP_REGNUM.
(REGISTER_BYTES): Recompute this.
* rs6000-tdep.c: Renamed all uses of FIRST_SP_REGNUM and
LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
some concomitant formatting changes.
#include "gdbcmd.h", so we can define commands here.
(struct variant): New structure.
(COMMON_UISA_REG_NAMES, PPC_UISA_SPR_NAMES, PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES, num_registers): New macros.
(register_names_rs6000, register_names_uisa, register_names_403,
register_names_403GC, register_names_505, register_names_860,
register_names_601, register_names_602, register_names_603,
register_names_604, register_names_750, variants): New variables.
(rs6000_register_name, install_variant, find_variant_by_name,
install_variant_by_name, list_variants, show_current_variant,
set_processor, show_processor): New functions.
(_initialize_rs6000_tdep): Define new commands `set processor' and
`show processor', and call install_variant_by_name to set the
default variant.
* rs6000-nat.c: Renamed all uses of FIRST_SP_REGNUM and
LAST_SP_REGNUM to FIRST_UISA_SP_REGNUM and LAST_UISA_SP_REGNUM, with
some concomitant formatting changes.
* configure.in: Accept the `--with-cpu' flag, to specify a default
processor variant.
* acconfig.h: Provide a blurb for TARGET_CPU_DEFAULT, which is set
by configure's `--with-cpu' flag.
* config.in, configure: Regenerated.
This commit is contained in:
Jim Blandy 1999-02-01 21:17:19 +00:00
parent e745689c95
commit 2ac058fda9
6 changed files with 769 additions and 314 deletions

View File

@ -70,3 +70,7 @@
/* Define if <proc_service.h> on solaris uses int instead of
size_t, and assorted other type changes. */
#undef PROC_SERVICE_IS_OLD
/* If you want to specify a default CPU variant, define this to be its
name, as a C string. */
#undef TARGET_CPU_DEFAULT

View File

@ -127,6 +127,10 @@
size_t, and assorted other type changes. */
#undef PROC_SERVICE_IS_OLD
/* If you want to specify a default CPU variant, define this to be its
name, as a C string. */
#undef TARGET_CPU_DEFAULT
/* Define if you have the __argz_count function. */
#undef HAVE___ARGZ_COUNT

616
gdb/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -561,6 +561,42 @@ AC_SUBST(LIBIDE)
AC_SUBST(IDE_DEPS)
# end-sanitize-ide
AC_ARG_WITH(cpu,
[ --with-cpu=CPU set the default CPU variant to debug],
[case "${target}" in
powerpc-* | powerpcle-* )
## It would be nice to keep this table in sync with the one in
## gcc/configure.
case "${with_cpu}" in
ppc-uisa | rs6000 | 403 | 403GC | 505 | 860 | 601 | 602 | 603 \
| 604 | 750 )
## Those are all handled in variants in rs6000-tdep.c, so they're fine.
;;
common | power | power2 | rios | rios1 | rios2 | rsc | rsc1 )
## These are all RS6000 variants, as far as GDB is concerned.
with_cpu=rs6000
;;
603e | ec603e )
with_cpu=603
;;
604e )
with_cpu=604
;;
* )
AC_MSG_WARN(GDB: unknown --with-cpu value: \`${with_cpu}'; using \`ppc-uisa'.)
with_cpu=ppc-uisa
;;
esac
;;
* )
AC_MSG_WARN(GDB may ignore the --with-cpu flag for ${target} targets)
;;
esac
AC_DEFINE_UNQUOTED(TARGET_CPU_DEFAULT, "${with_cpu}")
],)
ENABLE_GDBTK=
AC_ARG_ENABLE(gdbtk,

View File

@ -110,8 +110,8 @@ fetch_inferior_registers (regno)
FPR0+ii, 0);
/* read special registers. */
for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
*(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)] =
for (ii=0; ii <= LAST_UISA_SP_REGNUM-FIRST_UISA_SP_REGNUM; ++ii)
*(int*)&registers[REGISTER_BYTE (FIRST_UISA_SP_REGNUM+ii)] =
ptrace (PT_READ_GPR, inferior_pid, (PTRACE_ARG3_TYPE) special_regs[ii],
0, 0);
@ -130,13 +130,16 @@ fetch_inferior_registers (regno)
(PTRACE_ARG3_TYPE) &registers [REGISTER_BYTE (regno)],
(regno-FP0_REGNUM+FPR0), 0);
}
else if (regno <= LAST_SP_REGNUM) { /* a special register */
else if (regno <= LAST_UISA_SP_REGNUM) { /* a special register */
*(int*)&registers[REGISTER_BYTE (regno)] =
ptrace (PT_READ_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs[regno-FIRST_SP_REGNUM], 0, 0);
(PTRACE_ARG3_TYPE) special_regs[regno-FIRST_UISA_SP_REGNUM],
0, 0);
}
else
fprintf_unfiltered (gdb_stderr, "gdb error: register no %d not implemented.\n", regno);
fprintf_unfiltered (gdb_stderr,
"gdb error: register no %d not implemented.\n",
regno);
register_valid [regno] = 1;
}
@ -190,11 +193,12 @@ store_inferior_registers (regno)
}
/* write special registers. */
for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
for (ii=0; ii <= LAST_UISA_SP_REGNUM-FIRST_UISA_SP_REGNUM; ++ii)
{
ptrace (PT_WRITE_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs[ii],
*(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)], 0);
*(int*)&registers[REGISTER_BYTE (FIRST_UISA_SP_REGNUM+ii)],
0);
if (errno)
{
perror ("ptrace write_gpr");
@ -218,15 +222,17 @@ store_inferior_registers (regno)
regno - FP0_REGNUM + FPR0, 0);
}
else if (regno <= LAST_SP_REGNUM) /* a special register */
else if (regno <= LAST_UISA_SP_REGNUM) /* a special register */
{
ptrace (PT_WRITE_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs [regno-FIRST_SP_REGNUM],
(PTRACE_ARG3_TYPE) special_regs [regno-FIRST_UISA_SP_REGNUM],
*(int*)&registers[REGISTER_BYTE (regno)], 0);
}
else
fprintf_unfiltered (gdb_stderr, "Gdb error: register no %d not implemented.\n", regno);
fprintf_unfiltered (gdb_stderr,
"Gdb error: register no %d not implemented.\n",
regno);
if (errno)
{
@ -248,8 +254,9 @@ exec_one_dummy_insn ()
int status, pid;
CORE_ADDR prev_pc;
/* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
this address will never be executed again by the real code. */
/* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We
assume that this address will never be executed again by the real
code. */
target_insert_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
@ -294,8 +301,9 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
/* then comes special registes. They are supposed to be in the same
order in gdb template and bfd `.reg' section. */
core_reg_sect += (32 * 4);
memcpy (&registers [REGISTER_BYTE (FIRST_SP_REGNUM)], core_reg_sect,
(LAST_SP_REGNUM - FIRST_SP_REGNUM + 1) * 4);
memcpy (&registers [REGISTER_BYTE (FIRST_UISA_SP_REGNUM)],
core_reg_sect,
(LAST_UISA_SP_REGNUM - FIRST_UISA_SP_REGNUM + 1) * 4);
}
/* fetch floating point registers from register section 2 in core bfd. */
@ -303,7 +311,9 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
memcpy (&registers [REGISTER_BYTE (FP0_REGNUM)], core_reg_sect, 32 * 8);
else
fprintf_unfiltered (gdb_stderr, "Gdb error: unknown parameter to fetch_core_registers().\n");
fprintf_unfiltered
(gdb_stderr,
"Gdb error: unknown parameter to fetch_core_registers().\n");
}
/* handle symbol translation on vmapping */

View File

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "symtab.h"
#include "target.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "symfile.h"
#include "objfiles.h"
#include "xcoffsolib.h"
@ -595,7 +596,7 @@ push_dummy_frame ()
/* so far, 32*2 + 32 words = 384 bytes have been written.
7 extra registers in our register set: pc, ps, cnd, lr, cnt, xer, mq */
for (ii=1; ii <= (LAST_SP_REGNUM-FIRST_SP_REGNUM+1); ++ii) {
for (ii=1; ii <= (LAST_UISA_SP_REGNUM-FIRST_UISA_SP_REGNUM+1); ++ii) {
write_memory (sp-384-(ii*4),
&registers[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
}
@ -647,7 +648,7 @@ pop_dummy_frame ()
}
/* restore the rest of the registers. */
for (ii=1; ii <=(LAST_SP_REGNUM-FIRST_SP_REGNUM+1); ++ii)
for (ii=1; ii <=(LAST_UISA_SP_REGNUM-FIRST_UISA_SP_REGNUM+1); ++ii)
read_memory (sp-384-(ii*4),
&registers[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
@ -1409,6 +1410,351 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
#endif
/* Handling the various PowerPC/RS6000 variants. */
/* The arrays here called register_names_MUMBLE hold names that
the rs6000_register_name function returns.
For each family of PPC variants, I've tried to isolate out the
common registers and put them up front, so that as long as you get
the general family right, GDB will correctly identify the registers
common to that family. The common register sets are:
For the 60x family: hid0 hid1 iabr dabr pir
For the 505 and 860 family: eie eid nri
For the 403 and 403GC: icdbdr esr dear evpr cdbcr tsr tcr pit tbhi
tblo srr2 srr3 dbsr dbcr iac1 iac2 dac1 dac2 dccr iccr pbl1
pbu1 pbl2 pbu2
Most of these register groups aren't anything formal. I arrived at
them by looking at the registers that occurred in more than one
processor. */
/* UISA register names common across all architectures, including POWER. */
#define COMMON_UISA_REG_NAMES \
/* 0 */ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
/* 8 */ "r8", "r9", "r10","r11","r12","r13","r14","r15", \
/* 16 */ "r16","r17","r18","r19","r20","r21","r22","r23", \
/* 24 */ "r24","r25","r26","r27","r28","r29","r30","r31", \
/* 32 */ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
/* 40 */ "f8", "f9", "f10","f11","f12","f13","f14","f15", \
/* 48 */ "f16","f17","f18","f19","f20","f21","f22","f23", \
/* 56 */ "f24","f25","f26","f27","f28","f29","f30","f31", \
/* 64 */ "pc", "ps"
/* UISA-level SPR names for PowerPC. */
#define PPC_UISA_SPR_NAMES \
/* 66 */ "cr", "lr", "ctr", "xer", ""
/* Segment register names, for PowerPC. */
#define PPC_SEGMENT_REG_NAMES \
/* 71 */ "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7", \
/* 79 */ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15"
/* OEA SPR names for 32-bit PowerPC implementations.
The blank space is for "asr", which is only present on 64-bit
implementations. */
#define PPC_32_OEA_SPR_NAMES \
/* 87 */ "pvr", \
/* 88 */ "ibat0u", "ibat0l", "ibat1u", "ibat1l", \
/* 92 */ "ibat2u", "ibat2l", "ibat3u", "ibat3l", \
/* 96 */ "dbat0u", "dbat0l", "dbat1u", "dbat1l", \
/* 100 */ "dbat2u", "dbat2l", "dbat3u", "dbat3l", \
/* 104 */ "sdr1", "", "dar", "dsisr", "sprg0", "sprg1", "sprg2", "sprg3",\
/* 112 */ "srr0", "srr1", "tbl", "tbu", "dec", "dabr", "ear"
/* For the RS6000, we only cover user-level SPR's. */
char *register_names_rs6000[] =
{
COMMON_UISA_REG_NAMES,
/* 66 */ "cnd", "lr", "cnt", "xer", "mq"
};
/* a UISA-only view of the PowerPC. */
char *register_names_uisa[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES
};
char *register_names_403[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "icdbdr", "esr", "dear", "evpr", "cdbcr", "tsr", "tcr", "pit",
/* 127 */ "tbhi", "tblo", "srr2", "srr3", "dbsr", "dbcr", "iac1", "iac2",
/* 135 */ "dac1", "dac2", "dccr", "iccr", "pbl1", "pbu1", "pbl2", "pbu2"
};
char *register_names_403GC[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "icdbdr", "esr", "dear", "evpr", "cdbcr", "tsr", "tcr", "pit",
/* 127 */ "tbhi", "tblo", "srr2", "srr3", "dbsr", "dbcr", "iac1", "iac2",
/* 135 */ "dac1", "dac2", "dccr", "iccr", "pbl1", "pbu1", "pbl2", "pbu2",
/* 143 */ "zpr", "pid", "sgr", "dcwr", "tbhu", "tblu"
};
char *register_names_505[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "eie", "eid", "nri"
};
char *register_names_860[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "eie", "eid", "nri", "cmpa", "cmpb", "cmpc", "cmpd", "icr",
/* 127 */ "der", "counta", "countb", "cmpe", "cmpf", "cmpg", "cmph",
/* 134 */ "lctrl1", "lctrl2", "ictrl", "bar", "ic_cst", "ic_adr", "ic_dat",
/* 141 */ "dc_cst", "dc_adr", "dc_dat", "dpdr", "dpir", "immr", "mi_ctr",
/* 148 */ "mi_ap", "mi_epn", "mi_twc", "mi_rpn", "md_ctr", "m_casid",
/* 154 */ "md_ap", "md_epn", "md_twb", "md_twc", "md_rpn", "m_tw",
/* 160 */ "mi_dbcam", "mi_dbram0", "mi_dbram1", "md_dbcam", "md_dbram0",
/* 165 */ "md_dbram1"
};
/* Note that the 601 has different register numbers for reading and
writing RTCU and RTCL. However, how one reads and writes a
register is the stub's problem. */
char *register_names_601[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "hid0", "hid1", "iabr", "dabr", "pir", "mq", "rtcu",
/* 126 */ "rtcl"
};
char *register_names_602[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "hid0", "hid1", "iabr", "", "", "tcr", "ibr", "esassr", "sebr",
/* 128 */ "ser", "sp", "lt"
};
char *register_names_603[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "hid0", "hid1", "iabr", "", "", "dmiss", "dcmp", "hash1",
/* 127 */ "hash2", "imiss", "icmp", "rpa"
};
char *register_names_604[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "hid0", "hid1", "iabr", "dabr", "pir", "mmcr0", "pmc1", "pmc2",
/* 127 */ "sia", "sda"
};
char *register_names_750[] =
{
COMMON_UISA_REG_NAMES,
PPC_UISA_SPR_NAMES,
PPC_SEGMENT_REG_NAMES,
PPC_32_OEA_SPR_NAMES,
/* 119 */ "hid0", "hid1", "iabr", "dabr", "", "ummcr0", "upmc1", "upmc2",
/* 127 */ "usia", "ummcr1", "upmc3", "upmc4", "mmcr0", "pmc1", "pmc2",
/* 134 */ "sia", "mmcr1", "pmc3", "pmc4", "l2cr", "ictc", "thrm1", "thrm2",
/* 142 */ "thrm3"
};
/* Information about a particular processor variant. */
struct variant
{
/* Name of this variant. */
char *name;
/* English description of the variant. */
char *description;
/* Table of register names; registers[R] is the name of the register
number R. */
int num_registers;
char **registers;
};
#define num_registers(list) (sizeof (list) / sizeof((list)[0]))
/* Information in this table comes from the following web sites:
IBM: http://www.chips.ibm.com:80/products/embedded/
Motorola: http://www.mot.com/SPS/PowerPC/
I'm sure I've got some of the variant descriptions not quite right.
Please report any inaccuracies you find to GDB's maintainer.
If you add entries to this table, please be sure to allow the new
value as an argument to the --with-cpu flag, in configure.in. */
static struct variant
variants[] =
{
{ "ppc-uisa", "PowerPC UISA - a PPC processor as viewed by user-level code",
num_registers (register_names_uisa), register_names_uisa },
{ "rs6000", "IBM RS6000 (\"POWER\") architecture, user-level view",
num_registers (register_names_rs6000), register_names_rs6000 },
{ "403", "IBM PowerPC 403",
num_registers (register_names_403), register_names_403 },
{ "403GC", "IBM PowerPC 403GC",
num_registers (register_names_403GC), register_names_403GC },
{ "505", "Motorola PowerPC 505",
num_registers (register_names_505), register_names_505 },
{ "860", "Motorola PowerPC 860 or 850",
num_registers (register_names_860), register_names_860 },
{ "601", "Motorola PowerPC 601",
num_registers (register_names_601), register_names_601 },
{ "602", "Motorola PowerPC 602",
num_registers (register_names_602), register_names_602 },
{ "603", "Motorola/IBM PowerPC 603 or 603e",
num_registers (register_names_603), register_names_603 },
{ "604", "Motorola PowerPC 604 or 604e",
num_registers (register_names_604), register_names_604 },
{ "750", "Motorola/IBM PowerPC 750 or 750",
num_registers (register_names_750), register_names_750 },
{ 0, 0, 0, 0 }
};
static struct variant *current_variant;
char *
rs6000_register_name (int i)
{
if (i < 0 || i >= NUM_REGS)
error ("GDB bug: rs6000-tdep.c (rs6000_register_name): strange register number");
return ((i < current_variant->num_registers)
? current_variant->registers[i]
: "");
}
static void
install_variant (struct variant *v)
{
current_variant = v;
}
/* Look up the variant named NAME in the `variants' table. Return a
pointer to the struct variant, or null if we couldn't find it. */
static struct variant *
find_variant_by_name (char *name)
{
int i;
for (i = 0; variants[i].name; i++)
if (! strcmp (name, variants[i].name))
return &variants[i];
return 0;
}
/* Install the PPC/RS6000 variant named NAME in the `variants' table.
Return zero if we installed it successfully, or a non-zero value if
we couldn't do it.
This might be useful to code outside this file, which doesn't want
to depend on the exact indices of the entries in the `variants'
table. Just make it non-static if you want that. */
static int
install_variant_by_name (char *name)
{
struct variant *v = find_variant_by_name (name);
if (v)
{
install_variant (v);
return 0;
}
else
return 1;
}
static void
list_variants ()
{
int i;
printf_filtered ("GDB knows about the following PowerPC and RS6000 variants:\n");
for (i = 0; variants[i].name; i++)
printf_filtered (" %-8s %s\n",
variants[i].name, variants[i].description);
}
static void
show_current_variant ()
{
printf_filtered ("PowerPC / RS6000 processor variant is set to `%s'.\n",
current_variant->name);
}
static void
set_processor (char *arg, int from_tty)
{
int i;
if (! arg || arg[0] == '\0')
{
list_variants ();
return;
}
if (install_variant_by_name (arg))
{
error_begin ();
fprintf_filtered (gdb_stderr,
"`%s' is not a recognized PowerPC / RS6000 variant name.\n\n", arg);
list_variants ();
return_to_top_level (RETURN_ERROR);
}
show_current_variant ();
}
static void
show_processor (char *arg, int from_tty)
{
show_current_variant ();
}
/* Initialization code. */
void
_initialize_rs6000_tdep ()
{
@ -1418,4 +1764,37 @@ _initialize_rs6000_tdep ()
#else
tm_print_insn = print_insn_rs6000;
#endif
/* I don't think we should use the set/show command arrangement
here, because the way that's implemented makes it hard to do the
error checking we want in a reasonable way. So we just add them
as two separate commands. */
add_cmd ("processor", class_support, set_processor,
"`set processor NAME' sets the PowerPC/RS6000 variant to NAME.\n\
If you set this, GDB will know about the special-purpose registers that are\n\
available on the given variant.\n\
Type `set processor' alone for a list of recognized variant names.",
&setlist);
add_cmd ("processor", class_support, show_processor,
"Show the variant of the PowerPC or RS6000 processor in use.\n\
Use `set processor' to change this.",
&showlist);
/* Set the current PPC processor variant. */
{
int status = 1;
#ifdef TARGET_CPU_DEFAULT
status = install_variant_by_name (TARGET_CPU_DEFAULT);
#endif
if (status)
{
#ifdef GDB_TARGET_POWERPC
install_variant_by_name ("ppc-uisa");
#else
install_variant_by_name ("rs6000");
#endif
}
}
}