Re: RFA: PowerPC sim & GDB: use fixed register numbering

Jim Blandy
2004-08-04T05:47:48Z

Andrew Cagney <cagney@gnu.org> writes:
> Have a look at the other sim-*.h files, you'll notice that most define
> an enum namespace and not a series of magic constants. Can we expand
> the table so that the constants aren't needed?

Is this going in the right direction?

Index: include/gdb/sim-ppc.h
===================================================================
RCS file: include/gdb/sim-ppc.h
diff -N include/gdb/sim-ppc.h
*** include/gdb/sim-ppc.h 1 Jan 1970 00:00:00 -0000
--- include/gdb/sim-ppc.h 3 Aug 2004 19:03:16 -0000
***************
*** 0 ****
--- 1,254 ----
+ /* sim-ppc.h --- interface between PowerPC simulator and GDB.
+
+ Copyright 2004 Free Software Foundation, Inc.
+
+ Contributed by Red Hat.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+ #if !defined (SIM_PPC_H)
+ #define SIM_PPC_H
+
+
+ /* The register access functions, sim_fetch_register and
+ sim_store_register, use the following numbering for PowerPC
+ registers. */
+
+ enum sim_ppc_regnum
+ {
+ /* General-purpose registers, r0 -- r31. */
+ sim_ppc_r0_regnum,
+ sim_ppc_r1_regnum,
+ sim_ppc_r2_regnum,
+ sim_ppc_r3_regnum,
+ sim_ppc_r4_regnum,
+ sim_ppc_r5_regnum,
+ sim_ppc_r6_regnum,
+ sim_ppc_r7_regnum,
+ sim_ppc_r8_regnum,
+ sim_ppc_r9_regnum,
+ sim_ppc_r10_regnum,
+ sim_ppc_r11_regnum,
+ sim_ppc_r12_regnum,
+ sim_ppc_r13_regnum,
+ sim_ppc_r14_regnum,
+ sim_ppc_r15_regnum,
+ sim_ppc_r16_regnum,
+ sim_ppc_r17_regnum,
+ sim_ppc_r18_regnum,
+ sim_ppc_r19_regnum,
+ sim_ppc_r20_regnum,
+ sim_ppc_r21_regnum,
+ sim_ppc_r22_regnum,
+ sim_ppc_r23_regnum,
+ sim_ppc_r24_regnum,
+ sim_ppc_r25_regnum,
+ sim_ppc_r26_regnum,
+ sim_ppc_r27_regnum,
+ sim_ppc_r28_regnum,
+ sim_ppc_r29_regnum,
+ sim_ppc_r30_regnum,
+ sim_ppc_r31_regnum,
+
+ /* Floating-point registers, f0 -- f31. */
+ sim_ppc_f0_regnum,
+ sim_ppc_f1_regnum,
+ sim_ppc_f2_regnum,
+ sim_ppc_f3_regnum,
+ sim_ppc_f4_regnum,
+ sim_ppc_f5_regnum,
+ sim_ppc_f6_regnum,
+ sim_ppc_f7_regnum,
+ sim_ppc_f8_regnum,
+ sim_ppc_f9_regnum,
+ sim_ppc_f10_regnum,
+ sim_ppc_f11_regnum,
+ sim_ppc_f12_regnum,
+ sim_ppc_f13_regnum,
+ sim_ppc_f14_regnum,
+ sim_ppc_f15_regnum,
+ sim_ppc_f16_regnum,
+ sim_ppc_f17_regnum,
+ sim_ppc_f18_regnum,
+ sim_ppc_f19_regnum,
+ sim_ppc_f20_regnum,
+ sim_ppc_f21_regnum,
+ sim_ppc_f22_regnum,
+ sim_ppc_f23_regnum,
+ sim_ppc_f24_regnum,
+ sim_ppc_f25_regnum,
+ sim_ppc_f26_regnum,
+ sim_ppc_f27_regnum,
+ sim_ppc_f28_regnum,
+ sim_ppc_f29_regnum,
+ sim_ppc_f30_regnum,
+ sim_ppc_f31_regnum,
+
+ /* Altivec vector registers, vr0 -- vr31. */
+ sim_ppc_vr0_regnum,
+ sim_ppc_vr1_regnum,
+ sim_ppc_vr2_regnum,
+ sim_ppc_vr3_regnum,
+ sim_ppc_vr4_regnum,
+ sim_ppc_vr5_regnum,
+ sim_ppc_vr6_regnum,
+ sim_ppc_vr7_regnum,
+ sim_ppc_vr8_regnum,
+ sim_ppc_vr9_regnum,
+ sim_ppc_vr10_regnum,
+ sim_ppc_vr11_regnum,
+ sim_ppc_vr12_regnum,
+ sim_ppc_vr13_regnum,
+ sim_ppc_vr14_regnum,
+ sim_ppc_vr15_regnum,
+ sim_ppc_vr16_regnum,
+ sim_ppc_vr17_regnum,
+ sim_ppc_vr18_regnum,
+ sim_ppc_vr19_regnum,
+ sim_ppc_vr20_regnum,
+ sim_ppc_vr21_regnum,
+ sim_ppc_vr22_regnum,
+ sim_ppc_vr23_regnum,
+ sim_ppc_vr24_regnum,
+ sim_ppc_vr25_regnum,
+ sim_ppc_vr26_regnum,
+ sim_ppc_vr27_regnum,
+ sim_ppc_vr28_regnum,
+ sim_ppc_vr29_regnum,
+ sim_ppc_vr30_regnum,
+ sim_ppc_vr31_regnum,
+
+ /* SPE APU GPR upper halves. These are the upper 32 bits of the
+ gprs; there is one upper-half register for each gpr, so it is
+ appropriate to use sim_ppc_num_gprs for iterating through
+ these. */
+ sim_ppc_rh0_regnum,
+ sim_ppc_rh1_regnum,
+ sim_ppc_rh2_regnum,
+ sim_ppc_rh3_regnum,
+ sim_ppc_rh4_regnum,
+ sim_ppc_rh5_regnum,
+ sim_ppc_rh6_regnum,
+ sim_ppc_rh7_regnum,
+ sim_ppc_rh8_regnum,
+ sim_ppc_rh9_regnum,
+ sim_ppc_rh10_regnum,
+ sim_ppc_rh11_regnum,
+ sim_ppc_rh12_regnum,
+ sim_ppc_rh13_regnum,
+ sim_ppc_rh14_regnum,
+ sim_ppc_rh15_regnum,
+ sim_ppc_rh16_regnum,
+ sim_ppc_rh17_regnum,
+ sim_ppc_rh18_regnum,
+ sim_ppc_rh19_regnum,
+ sim_ppc_rh20_regnum,
+ sim_ppc_rh21_regnum,
+ sim_ppc_rh22_regnum,
+ sim_ppc_rh23_regnum,
+ sim_ppc_rh24_regnum,
+ sim_ppc_rh25_regnum,
+ sim_ppc_rh26_regnum,
+ sim_ppc_rh27_regnum,
+ sim_ppc_rh28_regnum,
+ sim_ppc_rh29_regnum,
+ sim_ppc_rh30_regnum,
+ sim_ppc_rh31_regnum,
+
+ /* SPE APU GPR full registers. Each of these registers is the
+ 64-bit concatenation of a 32-bit GPR (providing the lower bits)
+ and a 32-bit upper-half register (providing the higher bits).
+ As for the upper-half registers, it is appropriate to use
+ sim_ppc_num_gprs with these. */
+ sim_ppc_ev0_regnum,
+ sim_ppc_ev1_regnum,
+ sim_ppc_ev2_regnum,
+ sim_ppc_ev3_regnum,
+ sim_ppc_ev4_regnum,
+ sim_ppc_ev5_regnum,
+ sim_ppc_ev6_regnum,
+ sim_ppc_ev7_regnum,
+ sim_ppc_ev8_regnum,
+ sim_ppc_ev9_regnum,
+ sim_ppc_ev10_regnum,
+ sim_ppc_ev11_regnum,
+ sim_ppc_ev12_regnum,
+ sim_ppc_ev13_regnum,
+ sim_ppc_ev14_regnum,
+ sim_ppc_ev15_regnum,
+ sim_ppc_ev16_regnum,
+ sim_ppc_ev17_regnum,
+ sim_ppc_ev18_regnum,
+ sim_ppc_ev19_regnum,
+ sim_ppc_ev20_regnum,
+ sim_ppc_ev21_regnum,
+ sim_ppc_ev22_regnum,
+ sim_ppc_ev23_regnum,
+ sim_ppc_ev24_regnum,
+ sim_ppc_ev25_regnum,
+ sim_ppc_ev26_regnum,
+ sim_ppc_ev27_regnum,
+ sim_ppc_ev28_regnum,
+ sim_ppc_ev29_regnum,
+ sim_ppc_ev30_regnum,
+ sim_ppc_ev31_regnum,
+
+ /* Segment registers, sr0 -- sr15. */
+ sim_ppc_sr0_regnum,
+ sim_ppc_sr1_regnum,
+ sim_ppc_sr2_regnum,
+ sim_ppc_sr3_regnum,
+ sim_ppc_sr4_regnum,
+ sim_ppc_sr5_regnum,
+ sim_ppc_sr6_regnum,
+ sim_ppc_sr7_regnum,
+ sim_ppc_sr8_regnum,
+ sim_ppc_sr9_regnum,
+ sim_ppc_sr10_regnum,
+ sim_ppc_sr11_regnum,
+ sim_ppc_sr12_regnum,
+ sim_ppc_sr13_regnum,
+ sim_ppc_sr14_regnum,
+ sim_ppc_sr15_regnum,
+
+ /* Miscellaneous --- but non-SPR --- registers. */
+ sim_ppc_pc_regnum,
+ sim_ppc_ps_regnum,
+ sim_ppc_cr_regnum,
+ sim_ppc_fpscr_regnum,
+ sim_ppc_acc_regnum,
+ sim_ppc_vscr_regnum,
+
+ /* Special-purpose registers. Each SPR is given a number equal to
+ its number in the ISA --- the number that appears in the mtspr
+ / mfspr instructions --- plus this constant. */
+ sim_ppc_spr0_regnum
+ };
+
+
+ /* Sizes of various register sets. */
+ enum
+ {
+ sim_ppc_num_gprs = 32,
+ sim_ppc_num_fprs = 32,
+ sim_ppc_num_vrs = 32,
+ sim_ppc_num_srs = 16,
+ sim_ppc_num_sprs = 1024,
+ };
+
+ #endif /* SIM_PPC_H */
Index: sim/ppc/Makefile.in
===================================================================
RCS file: /cvs/src/src/sim/ppc/Makefile.in,v
retrieving revision 1.13
diff -c -p -r1.13 Makefile.in
*** sim/ppc/Makefile.in 26 Jul 2004 21:37:46 -0000 1.13
--- sim/ppc/Makefile.in 3 Aug 2004 19:03:16 -0000
*************** sim/ppc/Makefile.in run $(TARGETLIB) $(GDB_OBJ)
*** 172,180 ****
# Headers outside sim/ppc.
ANSIDECL_H = $(srcroot)/include/ansidecl.h
BFD_H = ../../bfd/bfd.h
- DEFS_H = $(srcroot)/gdb/defs.h
GDB_CALLBACK_H = $(srcroot)/include/gdb/callback.h
GDB_REMOTE_SIM_H = $(srcroot)/include/gdb/remote-sim.h
COMMON_SIM_BASE_H = $(srcroot)/sim/common/sim-base.h
COMMON_SIM_BASICS_H = $(srcroot)/sim/common/sim-basics.h
COMMON_SIM_FPU_H = $(srcroot)/sim/common/sim-fpu.h
--- 172,180 ----
# Headers outside sim/ppc.
ANSIDECL_H = $(srcroot)/include/ansidecl.h
BFD_H = ../../bfd/bfd.h
GDB_CALLBACK_H = $(srcroot)/include/gdb/callback.h
GDB_REMOTE_SIM_H = $(srcroot)/include/gdb/remote-sim.h
+ GDB_SIM_PPC_H = $(srcroot)/include/gdb/sim-ppc.h
COMMON_SIM_BASE_H = $(srcroot)/sim/common/sim-base.h
COMMON_SIM_BASICS_H = $(srcroot)/sim/common/sim-basics.h
COMMON_SIM_FPU_H = $(srcroot)/sim/common/sim-fpu.h
*************** model.o: model.c $(CPU_H) $(MON_H)
*** 597,603 ****

events.o: events.c $(BASICS_H) $(EVENTS_H)

! sim_calls.o: sim_calls.c $(PSIM_H) $(OPTIONS_H) $(DEFS_H) $(BFD_H) $(GDB_CALLBACK_H) $(GDB_REMOTE_SIM_H)

spreg.o: spreg.c $(BASICS_H) $(SPREG_H)

--- 597,603 ----

events.o: events.c $(BASICS_H) $(EVENTS_H)

! sim_calls.o: sim_calls.c $(PSIM_H) $(OPTIONS_H) $(REGISTERS_H) $(BFD_H) $(GDB_CALLBACK_H) $(GDB_REMOTE_SIM_H) $(GDB_SIM_PPC_H)

spreg.o: spreg.c $(BASICS_H) $(SPREG_H)

Index: sim/ppc/sim_calls.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/sim_calls.c,v
retrieving revision 1.7
diff -c -p -r1.7 sim_calls.c
*** sim/ppc/sim_calls.c 20 Jun 2003 13:32:34 -0000 1.7
--- sim/ppc/sim_calls.c 3 Aug 2004 19:03:17 -0000
***************
*** 25,30 ****
--- 25,31 ----

#include "psim.h"
#include "options.h"
+ #include "registers.h"

#undef printf_filtered /* blow away the mapping */

***************
*** 40,49 ****
#endif
#endif

- #include "defs.h"
#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"

/* Define the rate at which the simulator should poll the host
for a quit. */
--- 41,50 ----
#endif
#endif

#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"
+ #include "gdb/sim-ppc.h"

/* Define the rate at which the simulator should poll the host
for a quit. */
*************** static psim *simulator;
*** 59,87 ****
static device *root_device;
static host_callback *callbacks;

- /* We use GDB's gdbarch_register_name function to map GDB register
- numbers onto names, which we can then look up in the register
- table. Since the `set architecture' command can select a new
- processor variant at run-time, the meanings of the register numbers
- can change, so we need to make sure the sim uses the same
- name/number mapping that GDB uses.
-
- (We don't use the REGISTER_NAME macro, which is a wrapper for
- gdbarch_register_name. We #include GDB's "defs.h", which tries to
- #include GDB's "config.h", but gets ours instead, and REGISTER_NAME
- ends up not getting defined. Simpler to just use
- gdbarch_register_name directly.)
-
- We used to just use the REGISTER_NAMES macro from GDB's
- target-dependent header files, which expanded into an initializer
- for an array of strings. That was kind of nice, because it meant
- that libsim.a had only a compile-time dependency on GDB; using
- gdbarch_register_name directly means that there are now link-time
- and run-time dependencies too.
-
- Perhaps the host_callback structure could provide a function for
- retrieving register names; that would be cleaner. */
-
SIM_DESC
sim_open (SIM_OPEN_KIND kind,
host_callback *callback,
--- 60,65 ----
*************** sim_write (SIM_DESC sd, SIM_ADDR mem, un
*** 177,182 ****
--- 155,236 ----
}

+ /* A table mapping register numbers (as received from GDB) to register
+ names. This table does not handle special-purpose registers: the
+ SPR whose number is N is assigned the register number
+ sim_ppc_spr0_regnum + N. */
+ static const char *gdb_register_name_table[] = {
+
+ /* General-purpose registers: 0 .. 31. */
+ "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",
+
+ /* Floating-point registers: 32 .. 63. */
+ "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",
+
+ /* Altivec registers: 64 .. 95. */
+ "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7",
+ "vr8", "vr9", "vr10", "vr11", "vr12", "vr13", "vr14", "vr15",
+ "vr16", "vr17", "vr18", "vr19", "vr20", "vr21", "vr22", "vr23",
+ "vr24", "vr25", "vr26", "vr27", "vr28", "vr29", "vr30", "vr31",
+
+ /* SPE APU GPR upper halves: 96 .. 127. */
+ "rh0", "rh1", "rh2", "rh3", "rh4", "rh5", "rh6", "rh7",
+ "rh8", "rh9", "rh10", "rh11", "rh12", "rh13", "rh14", "rh15",
+ "rh16", "rh17", "rh18", "rh19", "rh20", "rh21", "rh22", "rh23",
+ "rh24", "rh25", "rh26", "rh27", "rh28", "rh29", "rh30", "rh31",
+
+ /* SPE APU full 64-bit vector registers: 128 .. 159. */
+ "ev0", "ev1", "ev2", "ev3", "ev4", "ev5", "ev6", "ev7",
+ "ev8", "ev9", "ev10", "ev11", "ev12", "ev13", "ev14", "ev15",
+ "ev16", "ev17", "ev18", "ev19", "ev20", "ev21", "ev22", "ev23",
+ "ev24", "ev25", "ev26", "ev27", "ev28", "ev29", "ev30", "ev31",
+
+ /* Segment registers: 160 .. 175. */
+ "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
+
+ /* Miscellaneous (not special-purpose!) registers: 176 .. 181. */
+ "pc", "ps", "cr", "fpscr", "acc", "vscr"
+ };
+
+ enum {
+ gdb_register_name_table_size = (sizeof (gdb_register_name_table)
+ / sizeof (gdb_register_name_table[0])),
+ };
+
+
+ /* Return the name of the register whose number is REGNUM, or zero if
+ REGNUM is an invalid register number. */
+ static const char *
+ gdb_register_name (int regnum)
+ {
+ /* Is it a special-purpose register? */
+ if (sim_ppc_spr0_regnum <= regnum
+ && regnum < sim_ppc_spr0_regnum + sim_ppc_num_sprs)
+ {
+ int spr = regnum - sim_ppc_spr0_regnum;
+ if (spr_is_valid (spr))
+ return spr_name (spr);
+ else
+ return 0;
+ }
+
+ /* Is it a valid non-SPR register number? */
+ else if (0 <= regnum && regnum < gdb_register_name_table_size)
+ return gdb_register_name_table[regnum];
+
+ /* Not a valid register number at all. */
+ else
+ return 0;
+ }
+
+
int
sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
{
*************** sim_fetch_register (SIM_DESC sd, int reg
*** 186,200 ****
return 0;
}

! /* GDB will sometimes ask for the contents of a register named "";
! we ignore such requests, and leave garbage in *BUF. In GDB
! terms, the empty string means "the register with this number is
! not present in the currently selected architecture variant."
! That's following the kludge we're using for the MIPS processors.
! But there are loops that just walk through the entire list of
! names and try to get everything. */
! regname = gdbarch_register_name (current_gdbarch, regno);
! if (! regname || regname[0] == '\0')
return -1;

TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
--- 240,250 ----
return 0;
}

! regname = gdb_register_name (regno);
!
! /* Occasionally, GDB will pass invalid register numbers to us; it
! wants us to ignore them. */
! if (! regname)
return -1;

TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n",
*************** sim_store_register (SIM_DESC sd, int reg
*** 212,220 ****
if (simulator == NULL)
return 0;

! /* See comments in sim_fetch_register, above. */
! regname = gdbarch_register_name (current_gdbarch, regno);
! if (! regname || regname[0] == '\0')
return -1;

TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",
--- 262,272 ----
if (simulator == NULL)
return 0;

! regname = gdb_register_name (regno);
!
! /* Occasionally, GDB will pass invalid register numbers to us; it
! wants us to ignore them. */
! if (! regname)
return -1;

TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n",