Re: [rfc] Use target descriptions for PowerPC

Daniel Jacobowitz
2007-10-15T19:47:29Z

On Fri, Oct 05, 2007 at 12:37:54PM -0400, Daniel Jacobowitz wrote:
> A couple of weeks ago, I began cleaning up some local patches that
> added support for XML target described registers to the PowerPC port.
> My goal was to add gdbserver support for AltiVec and for the e500
> SPE vector registers. This patch is what eventually came of that
> work.

Here's what I committed, along with the generated files.

--
Daniel Jacobowitz
CodeSourcery

2007-10-15 Daniel Jacobowitz <dan@codesourcery.com>

* NEWS: Document target described register support for PowerPC.
* ppc-tdep.h: Remove ppc_spr constants.
(struct gdbarch_tdep): Remove regs, ppc_sr0_regnum, and
ppc_builtin_type_vec128 members.
(PPC_R0_REGNUM, PPC_F0_REGNUM, PPC_PC_REGNUM, PPC_MSR_REGNUM)
(PPC_CR_REGNUM, PPC_LR_REGNUM, PPC_CTR_REGNUM, PPC_XER_REGNUM)
(PPC_FPSCR_REGNUM, PPC_MQ_REGNUM, PPC_SPE_UPPER_GP0_REGNUM)
(PPC_SPE_ACC_REGNUM, PPC_SPE_FSCR_REGNUM, PPC_VR0_REGNUM)
(PPC_VSCR_REGNUM, PPC_VRSAVE_REGNUM, PPC_NUM_REGS): New constants.
* rs6000-tdep.c: Include preparsed descriptions.
(init_sim_regno_table): Do not iterate over pseudo registers.
Look up segment registers by name. Use sim_spr_register_name
for SPRs.
(rs6000_register_sim_regno): Call init_sim_regno_table here.
(rs6000_builtin_type_vec128): Delete.
(rs6000_register_name): Only handle SPE pseudo registers and upper
halves. Call tdesc_register_name for everything else.
(rs6000_register_type): Delete. Replace with...
(rs6000_pseudo_register_type): ...this new function. Only handle
SPE pseudo registers.
(rs6000_register_reggroup_p): Delete. Replace with...
(rs6000_pseudo_register_reggroup_p): ...this new function. Only
handle SPE pseudo registers.
(rs6000_convert_register_p): Use ppc_fp0_regnum instead of
"struct reg".
(rs6000_register_to_value, rs6000_value_to_register): Remove check
of reg->fpr.
(e500_register_reggroup_p): Delete.
(STR, R, R4, R8, R16, F, P8, R32, R64, R0, A4, S, S4, SN4, S64)
(COMMON_UISA_REGS, PPC_UISA_SPRS, PPC_UISA_NOFP_SPRS)
(PPC_SEGMENT_REGS, PPC_OEA_SPRS, PPC_ALTIVEC_REGS, PPC_SPE_GP_REGS)
(PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): Delete macros.
(registers_powerpc, registers_403, registers_403GC, registers_505)
(registers_860, registers_601, registers_602, registers_603)
(registers_604, registers_750, registers_7400, registers_e500): Delete
variables.
(struct variant): Delete nregs, npregs, num_tot_regs, and regs. Add
tdesc.
(tot_num_registers, num_registers, num_pseudo_registers): Delete.
(variants): Delete outdated comment. Use standard target descriptions
instead of "struct reg" arrays.
(init_variants): Delete.
(rs6000_gdbarch_init): Do not guess word size from the BFD
architecture if we have a target description. Select a variant
before creating a new architecture. Use the variant's target
description if the target did not define a register layout.
Validate target-supplied registers. Reject mismatches. Use
fixed register numbers and new constants instead of magic
numbers. Call set_gdbarch_ps_regnum. Call tdesc_use_registers.
(_initialize_rs6000_tdep): Initialize the preparsed target
descriptions.
* target-descriptions.c (tdesc_predefined_types): Add int128 and
uint128.
(tdesc_find_register_early): New function.
(tdesc_numbered_register): Use it.
(tdesc_register_size): New function.
(tdesc_use_registers): Take a target_desc argument. Do not use
gdbarch_target_desc.
* target-descriptions.h (tdesc_use_registers): Update prototype
and comment.
(tdesc_register_size): New prototype.
* Makefile.in (powerpc_32_c, powerpc_403_c, powerpc_403gc_c)
(powerpc_505_c, powerpc_601_c, powerpc_602_c, powerpc_603_c)
(powerpc_604_c, powerpc_64_c, powerpc_7400_c, powerpc_750_c)
(powerpc_860_c, powerpc_e500_c, rs6000_c): New macros.
(rs6000-tdep.o): Update.
* arm-tdep.c (arm_gdbarch_init): Update call to tdesc_use_registers.
* m68k-tdep.c (m68k_gdbarch_init): Likewise.
* mips-tdep.c (mips_gdbarch_init): Likewise.

2007-10-15 Daniel Jacobowitz <dan@codesourcery.com>

* gdb.texinfo (Predefined Target Types): Add int128
and uint128.
(Standard Target Features): Add PowerPC features.

2007-10-15 Daniel Jacobowitz <dan@codesourcery.com>

* gdb.xml/tdesc-regs.exp: Add PowerPC support.

2007-10-15 Daniel Jacobowitz <dan@codesourcery.com>

* sim-ppc.h (sim_spr_register_name): New prototype.

2007-10-15 Daniel Jacobowitz <dan@codesourcery.com>

* gdb-sim.c (regnum2spr): Rename to...
(sim_spr_register_name): ... this. Make global.

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.944
diff -u -p -r1.944 Makefile.in
--- gdb/Makefile.in 15 Oct 2007 19:19:17 -0000 1.944
+++ gdb/Makefile.in 15 Oct 2007 19:28:55 -0000
@@ -888,6 +888,20 @@ features_headers = $(defs_h) $(gdbtypes_
arm_with_iwmmxt_c = $(srcdir)/features/arm-with-iwmmxt.c $(features_headers)
mips_linux_c = $(srcdir)/features/mips-linux.c $(features_headers)
mips64_linux_c = $(srcdir)/features/mips64-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)
+powerpc_505_c = $(srcdir)/features/rs6000/powerpc-505.c $(features_headers)
+powerpc_601_c = $(srcdir)/features/rs6000/powerpc-601.c $(features_headers)
+powerpc_602_c = $(srcdir)/features/rs6000/powerpc-602.c $(features_headers)
+powerpc_603_c = $(srcdir)/features/rs6000/powerpc-603.c $(features_headers)
+powerpc_604_c = $(srcdir)/features/rs6000/powerpc-604.c $(features_headers)
+powerpc_64_c = $(srcdir)/features/rs6000/powerpc-64.c $(features_headers)
+powerpc_7400_c = $(srcdir)/features/rs6000/powerpc-7400.c $(features_headers)
+powerpc_750_c = $(srcdir)/features/rs6000/powerpc-750.c $(features_headers)
+powerpc_860_c = $(srcdir)/features/rs6000/powerpc-860.c $(features_headers)
+powerpc_e500_c = $(srcdir)/features/rs6000/powerpc-e500.c $(features_headers)
+rs6000_c = $(srcdir)/features/rs6000/rs6000.c $(features_headers)

# Header files that need to have srcdir added. Note that in the cases
# where we use a macro like $(gdbcmd_h), things are carefully arranged
@@ -2543,7 +2557,12 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $
$(reggroups_h) $(libbfd_h) $(coff_internal_h) $(libcoff_h) \
$(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \
$(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \
- $(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h) $(dwarf2_frame_h)
+ $(frame_unwind_h) $(frame_base_h) $(rs6000_tdep_h) $(dwarf2_frame_h) \
+ $(target_descriptions) $(user_regs_h) \
+ $(powerpc_32_c) $(powerpc_403_c) $(powerpc_403gc_c) $(powerpc_505_c) \
+ $(powerpc_601_c) $(powerpc_602_c) $(powerpc_603_c) $(powerpc_604_c) \
+ $(powerpc_64_c) $(powerpc_7400_c) $(powerpc_750_c) $(powerpc_860_c) \
+ $(powerpc_e500_c) $(rs6000_c)
rs6000-aix-tdep.o: rs6000-aix-tdep.c $(defs_h) $(gdb_string_h) $(osabi_h) \
$(regcache_h) $(regset_h) $(rs6000_tdep_h) $(ppc_tdep_h)
s390-nat.o: s390-nat.c $(defs_h) $(regcache_h) $(inferior_h) \
Index: gdb/NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.241
diff -u -p -r1.241 NEWS
--- gdb/NEWS 3 Oct 2007 20:42:08 -0000 1.241
+++ gdb/NEWS 15 Oct 2007 19:28:55 -0000
@@ -10,6 +10,8 @@ is resolved.
including breakpoints on C++ constructors, inside C++ templates,
and in inlined functions.

+* Target descriptions can now describe registers for PowerPC.
+
*** Changes in GDB 6.7

* Resolved 101 resource leaks, null pointer dereferences, etc. in gdb,
Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.245
diff -u -p -r1.245 arm-tdep.c
--- gdb/arm-tdep.c 10 Oct 2007 14:04:53 -0000 1.245
+++ gdb/arm-tdep.c 15 Oct 2007 19:28:55 -0000
@@ -3074,7 +3074,7 @@ arm_gdbarch_init (struct gdbarch_info in
}

if (tdesc_data)
- tdesc_use_registers (gdbarch, tdesc_data);
+ tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);

/* Add standard register aliases. We add aliases even for those
nanes which are used by the current architecture - it's simpler,
Index: gdb/m68k-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m68k-tdep.c,v
retrieving revision 1.124
diff -u -p -r1.124 m68k-tdep.c
--- gdb/m68k-tdep.c 8 Oct 2007 12:54:07 -0000 1.124
+++ gdb/m68k-tdep.c 15 Oct 2007 19:28:55 -0000
@@ -1257,7 +1257,7 @@ m68k_gdbarch_init (struct gdbarch_info i
frame_unwind_append_sniffer (gdbarch, m68k_frame_sniffer);

if (tdesc_data)
- tdesc_use_registers (gdbarch, tdesc_data);
+ tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);

return gdbarch;
}
Index: gdb/mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.452
diff -u -p -r1.452 mips-tdep.c
--- gdb/mips-tdep.c 10 Oct 2007 17:03:36 -0000 1.452
+++ gdb/mips-tdep.c 15 Oct 2007 19:28:56 -0000
@@ -5649,7 +5649,7 @@ mips_gdbarch_init (struct gdbarch_info i
if (tdesc_data)
{
set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
- tdesc_use_registers (gdbarch, tdesc_data);
+ tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);

/* Override the normal target description methods to handle our
dual real and pseudo registers. */
Index: gdb/ppc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/ppc-tdep.h,v
retrieving revision 1.56
diff -u -p -r1.56 ppc-tdep.h
--- gdb/ppc-tdep.h 30 Aug 2007 13:13:59 -0000 1.56
+++ gdb/ppc-tdep.h 15 Oct 2007 19:28:56 -0000
@@ -139,7 +139,6 @@ extern void ppc_collect_fpregset (const
struct gdbarch_tdep
{
int wordsize; /* size in bytes of fixed-point word */
- const struct reg *regs; /* from current variant */
int ppc_gp0_regnum; /* GPR register 0 */
int ppc_toc_regnum; /* TOC register */
int ppc_ps_regnum; /* Processor (or machine) status (%msr) */
@@ -156,9 +155,6 @@ struct gdbarch_tdep
int ppc_fp0_regnum; /* floating-point register 0 */
int ppc_fpscr_regnum; /* fp status and condition register */

- /* Segment registers. */
- int ppc_sr0_regnum; /* segment register 0 */
-
/* Multiplier-Quotient Register (older POWER architectures only). */
int ppc_mq_regnum;

@@ -186,7 +182,6 @@ struct gdbarch_tdep

/* ISA-specific types. */
struct type *ppc_builtin_type_vec64;
- struct type *ppc_builtin_type_vec128;
};

@@ -200,189 +195,31 @@ enum
};

-/* Constants for SPR register numbers. These are *not* GDB register
- numbers: they are the numbers used in the PowerPC ISA itself to
- refer to these registers.
-
- This table includes all the SPRs from all the variants I could find
- documentation for.
-
- There may be registers from different PowerPC variants assigned the
- same number, but that's fine: GDB and the SIM always use the
- numbers in the context of a particular variant, so it's not
- ambiguous.
-
- We need to deviate from the naming pattern when variants have
- special-purpose registers of the same name, but with different
- numbers. Fortunately, this is rare: look below to see how we
- handle the 'tcr' registers on the 403/403GX and 602. */
+/* Register number constants. These are GDB internal register
+ numbers; they are not used for the simulator or remote targets.
+ Extra SPRs (those other than MQ, CTR, LR, XER, SPEFSCR) are given
+ numbers above PPC_NUM_REGS. So are segment registers and other
+ target-defined registers. */
+enum {
+ PPC_R0_REGNUM = 0,
+ PPC_F0_REGNUM = 32,
+ PPC_PC_REGNUM = 64,
+ PPC_MSR_REGNUM = 65,
+ PPC_CR_REGNUM = 66,
+ PPC_LR_REGNUM = 67,
+ PPC_CTR_REGNUM = 68,
+ PPC_XER_REGNUM = 69,
+ PPC_FPSCR_REGNUM = 70,
+ PPC_MQ_REGNUM = 71,
+ PPC_SPE_UPPER_GP0_REGNUM = 72,
+ PPC_SPE_ACC_REGNUM = 104,
+ PPC_SPE_FSCR_REGNUM = 105,
+ PPC_VR0_REGNUM = 106,
+ PPC_VSCR_REGNUM = 138,
+ PPC_VRSAVE_REGNUM = 139,
+ PPC_NUM_REGS
+};

-enum
- {
- ppc_spr_mq = 0,
- ppc_spr_xer = 1,
- ppc_spr_rtcu = 4,
- ppc_spr_rtcl = 5,
- ppc_spr_lr = 8,
- ppc_spr_ctr = 9,
- ppc_spr_cnt = 9,
- ppc_spr_dsisr = 18,
- ppc_spr_dar = 19,
- ppc_spr_dec = 22,
- ppc_spr_sdr1 = 25,
- ppc_spr_srr0 = 26,
- ppc_spr_srr1 = 27,
- ppc_spr_eie = 80,
- ppc_spr_eid = 81,
- ppc_spr_nri = 82,
- ppc_spr_sp = 102,
- ppc_spr_cmpa = 144,
- ppc_spr_cmpb = 145,
- ppc_spr_cmpc = 146,
- ppc_spr_cmpd = 147,
- ppc_spr_icr = 148,
- ppc_spr_der = 149,
- ppc_spr_counta = 150,
- ppc_spr_countb = 151,
- ppc_spr_cmpe = 152,
- ppc_spr_cmpf = 153,
- ppc_spr_cmpg = 154,
- ppc_spr_cmph = 155,
- ppc_spr_lctrl1 = 156,
- ppc_spr_lctrl2 = 157,
- ppc_spr_ictrl = 158,
- ppc_spr_bar = 159,
- ppc_spr_vrsave = 256,
- ppc_spr_sprg0 = 272,
- ppc_spr_sprg1 = 273,
- ppc_spr_sprg2 = 274,
- ppc_spr_sprg3 = 275,
- ppc_spr_asr = 280,
- ppc_spr_ear = 282,
- ppc_spr_tbl = 284,
- ppc_spr_tbu = 285,
- ppc_spr_pvr = 287,
- ppc_spr_spefscr = 512,
- ppc_spr_ibat0u = 528,
- ppc_spr_ibat0l = 529,
- ppc_spr_ibat1u = 530,
- ppc_spr_ibat1l = 531,
- ppc_spr_ibat2u = 532,
- ppc_spr_ibat2l = 533,
- ppc_spr_ibat3u = 534,
- ppc_spr_ibat3l = 535,
- ppc_spr_dbat0u = 536,
- ppc_spr_dbat0l = 537,
- ppc_spr_dbat1u = 538,
- ppc_spr_dbat1l = 539,
- ppc_spr_dbat2u = 540,
- ppc_spr_dbat2l = 541,
- ppc_spr_dbat3u = 542,
- ppc_spr_dbat3l = 543,
- ppc_spr_ic_cst = 560,
- ppc_spr_ic_adr = 561,
- ppc_spr_ic_dat = 562,
- ppc_spr_dc_cst = 568,
- ppc_spr_dc_adr = 569,
- ppc_spr_dc_dat = 570,
- ppc_spr_dpdr = 630,
- ppc_spr_dpir = 631,
- ppc_spr_immr = 638,
- ppc_spr_mi_ctr = 784,
- ppc_spr_mi_ap = 786,
- ppc_spr_mi_epn = 787,
- ppc_spr_mi_twc = 789,
- ppc_spr_mi_rpn = 790,
- ppc_spr_mi_cam = 816,
- ppc_spr_mi_ram0 = 817,
- ppc_spr_mi_ram1 = 818,
- ppc_spr_md_ctr = 792,
- ppc_spr_m_casid = 793,
- ppc_spr_md_ap = 794,
- ppc_spr_md_epn = 795,
- ppc_spr_m_twb = 796,
- ppc_spr_md_twc = 797,
- ppc_spr_md_rpn = 798,
- ppc_spr_m_tw = 799,
- ppc_spr_mi_dbcam = 816,
- ppc_spr_mi_dbram0 = 817,
- ppc_spr_mi_dbram1 = 818,
- ppc_spr_md_dbcam = 824,
- ppc_spr_md_cam = 824,
- ppc_spr_md_dbram0 = 825,
- ppc_spr_md_ram0 = 825,
- ppc_spr_md_dbram1 = 826,
- ppc_spr_md_ram1 = 826,
- ppc_spr_ummcr0 = 936,
- ppc_spr_upmc1 = 937,
- ppc_spr_upmc2 = 938,
- ppc_spr_usia = 939,
- ppc_spr_ummcr1 = 940,
- ppc_spr_upmc3 = 941,
- ppc_spr_upmc4 = 942,
- ppc_spr_zpr = 944,
- ppc_spr_pid = 945,
- ppc_spr_mmcr0 = 952,
- ppc_spr_pmc1 = 953,
- ppc_spr_sgr = 953,
- ppc_spr_pmc2 = 954,
- ppc_spr_dcwr = 954,
- ppc_spr_sia = 955,
- ppc_spr_mmcr1 = 956,
- ppc_spr_pmc3 = 957,
- ppc_spr_pmc4 = 958,
- ppc_spr_sda = 959,
- ppc_spr_tbhu = 972,
- ppc_spr_tblu = 973,
- ppc_spr_dmiss = 976,
- ppc_spr_dcmp = 977,
- ppc_spr_hash1 = 978,
- ppc_spr_hash2 = 979,
- ppc_spr_icdbdr = 979,
- ppc_spr_imiss = 980,
- ppc_spr_esr = 980,
- ppc_spr_icmp = 981,
- ppc_spr_dear = 981,
- ppc_spr_rpa = 982,
- ppc_spr_evpr = 982,
- ppc_spr_cdbcr = 983,
- ppc_spr_tsr = 984,
- ppc_spr_602_tcr = 984,
- ppc_spr_403_tcr = 986,
- ppc_spr_ibr = 986,
- ppc_spr_pit = 987,
- ppc_spr_esasrr = 988,
- ppc_spr_tbhi = 988,
- ppc_spr_tblo = 989,
- ppc_spr_srr2 = 990,
- ppc_spr_sebr = 990,
- ppc_spr_srr3 = 991,
- ppc_spr_ser = 991,
- ppc_spr_hid0 = 1008,
- ppc_spr_dbsr = 1008,
- ppc_spr_hid1 = 1009,
- ppc_spr_iabr = 1010,
- ppc_spr_dbcr = 1010,
- ppc_spr_iac1 = 1012,
- ppc_spr_dabr = 1013,
- ppc_spr_iac2 = 1013,
- ppc_spr_dac1 = 1014,
- ppc_spr_dac2 = 1015,
- ppc_spr_l2cr = 1017,
- ppc_spr_dccr = 1018,
- ppc_spr_ictc = 1019,
- ppc_spr_iccr = 1019,
- ppc_spr_thrm1 = 1020,
- ppc_spr_pbl1 = 1020,
- ppc_spr_thrm2 = 1021,
- ppc_spr_pbu1 = 1021,
- ppc_spr_thrm3 = 1022,
- ppc_spr_pbl2 = 1022,
- ppc_spr_fpecr = 1022,
- ppc_spr_lt = 1022,
- ppc_spr_pir = 1023,
- ppc_spr_pbu2 = 1023
- };

/* Instruction size. */
#define PPC_INSN_SIZE 4
Index: gdb/rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.289
diff -u -p -r1.289 rs6000-tdep.c
--- gdb/rs6000-tdep.c 10 Oct 2007 17:06:30 -0000 1.289
+++ gdb/rs6000-tdep.c 15 Oct 2007 19:28:56 -0000
@@ -39,6 +39,8 @@
#include "gdb/sim-ppc.h"
#include "reggroups.h"
#include "dwarf2-frame.h"
+#include "target-descriptions.h"
+#include "user-regs.h"

#include "libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
@@ -60,6 +62,21 @@

#include "rs6000-tdep.h"

+#include "features/rs6000/powerpc-32.c"
+#include "features/rs6000/powerpc-403.c"
+#include "features/rs6000/powerpc-403gc.c"
+#include "features/rs6000/powerpc-505.c"
+#include "features/rs6000/powerpc-601.c"
+#include "features/rs6000/powerpc-602.c"
+#include "features/rs6000/powerpc-603.c"
+#include "features/rs6000/powerpc-604.c"
+#include "features/rs6000/powerpc-64.c"
+#include "features/rs6000/powerpc-7400.c"
+#include "features/rs6000/powerpc-750.c"
+#include "features/rs6000/powerpc-860.c"
+#include "features/rs6000/powerpc-e500.c"
+#include "features/rs6000/rs6000.c"
+
/* If the kernel has to deliver a signal, it pushes a sigcontext
structure on the stack and then calls the signal handler, passing
the address of the sigcontext in an argument register. Usually
@@ -202,10 +219,13 @@ static void
init_sim_regno_table (struct gdbarch *arch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
- int total_regs = gdbarch_num_regs (arch) + gdbarch_num_pseudo_regs (arch);
- const struct reg *regs = tdep->regs;
+ int total_regs = gdbarch_num_regs (arch);
int *sim_regno = GDBARCH_OBSTACK_CALLOC (arch, total_regs, int);
int i;
+ static const char *const segment_regs[] = {
+ "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15"
+ };

/* Presume that all registers not explicitly mentioned below are
unavailable from the sim. */
@@ -230,11 +250,14 @@ init_sim_regno_table (struct gdbarch *ar
set_sim_regno (sim_regno, tdep->ppc_cr_regnum, sim_ppc_cr_regnum);

/* Segment registers. */
- if (tdep->ppc_sr0_regnum >= 0)
- for (i = 0; i < ppc_num_srs; i++)
- set_sim_regno (sim_regno,
- tdep->ppc_sr0_regnum + i,
- sim_ppc_sr0_regnum + i);
+ for (i = 0; i < ppc_num_srs; i++)
+ {
+ int gdb_regno;
+
+ gdb_regno = user_reg_map_name_to_regnum (arch, segment_regs[i], -1);
+ if (gdb_regno >= 0)
+ set_sim_regno (sim_regno, gdb_regno, sim_ppc_sr0_regnum + i);
+ }

/* Altivec registers. */
if (tdep->ppc_vr0_regnum >= 0)
@@ -253,11 +276,6 @@ init_sim_regno_table (struct gdbarch *ar
/* vsave is a special-purpose register, so the code below handles it. */

/* SPE APU (E500) registers. */
- if (tdep->ppc_ev0_regnum >= 0)
- for (i = 0; i < ppc_num_gprs; i++)
- set_sim_regno (sim_regno,
- tdep->ppc_ev0_regnum + i,
- sim_ppc_ev0_regnum + i);
if (tdep->ppc_ev0_upper_regnum >= 0)
for (i = 0; i < ppc_num_gprs; i++)
set_sim_regno (sim_regno,
@@ -267,12 +285,22 @@ init_sim_regno_table (struct gdbarch *ar
set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum);
/* spefscr is a special-purpose register, so the code below handles it. */

+#ifdef WITH_SIM
/* Now handle all special-purpose registers. Verify that they
haven't mistakenly been assigned numbers by any of the above
- code). */
- for (i = 0; i < total_regs; i++)
- if (regs[i].spr_num >= 0)
- set_sim_regno (sim_regno, i, regs[i].spr_num + sim_ppc_spr0_regnum);
+ code. */
+ for (i = 0; i < sim_ppc_num_sprs; i++)
+ {
+ const char *spr_name = sim_spr_register_name (i);
+ int gdb_regno = -1;
+
+ if (spr_name != NULL)
+ gdb_regno = user_reg_map_name_to_regnum (arch, spr_name, -1);
+
+ if (gdb_regno != -1)
+ set_sim_regno (sim_regno, gdb_regno, sim_ppc_spr0_regnum + i);
+ }
+#endif

/* Drop the initialized array into place. */
tdep->sim_regno = sim_regno;
@@ -287,6 +315,9 @@ rs6000_register_sim_regno (int reg)
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
int sim_regno;

+ if (tdep->sim_regno == NULL)
+ init_sim_regno_table (current_gdbarch);
+
gdb_assert (0 <= reg
&& reg <= gdbarch_num_regs (current_gdbarch)
+ gdbarch_num_pseudo_regs (current_gdbarch));
@@ -2171,46 +2202,6 @@ rs6000_builtin_type_vec64 (struct gdbarc
return tdep->ppc_builtin_type_vec64;
}

-static struct type *
-rs6000_builtin_type_vec128 (struct gdbarch *gdbarch)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- if (!tdep->ppc_builtin_type_vec128)
- {
- /* The type we're building is this: */
-#if 0
- union __gdb_builtin_type_vec128
- {
- int128_t uint128;
- float v4_float[4];
- int32_t v4_int32[4];
- int16_t v8_int16[8];
- int8_t v16_int8[16];
- };
-#endif
-
- struct type *t;
-
- t = init_composite_type ("__ppc_builtin_type_vec128", TYPE_CODE_UNION);
- append_composite_type_field (t, "uint128", builtin_type_int128);
- append_composite_type_field (t, "v4_float",
- init_vector_type (builtin_type_float, 4));
- append_composite_type_field (t, "v4_int32",
- init_vector_type (builtin_type_int32, 4));
- append_composite_type_field (t, "v8_int16",
- init_vector_type (builtin_type_int16, 8));
- append_composite_type_field (t, "v16_int8",
- init_vector_type (builtin_type_int8, 16));
-
- TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
- TYPE_NAME (t) = "ppc_builtin_type_vec128";
- tdep->ppc_builtin_type_vec128 = t;
- }
-
- return tdep->ppc_builtin_type_vec128;
-}
-
/* Return the size of register REG when words are WORDSIZE bytes long. If REG
isn't available with that word size, return 0. */

@@ -2220,109 +2211,71 @@ regsize (const struct reg *reg, int word
return wordsize == 8 ? reg->sz64 : reg->sz32;
}

-/* Return the name of register number N, or null if no such register exists
- in the current architecture. */
+/* Return the name of register number REGNO, or the empty string if it
+ is an anonymous register. */

static const char *
-rs6000_register_name (int n)
+rs6000_register_name (int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
- const struct reg *reg = tdep->regs + n;

- if (!regsize (reg, tdep->wordsize))
- return NULL;
- return reg->name;
+ /* The upper half "registers" have names in the XML description,
+ but we present only the low GPRs and the full 64-bit registers
+ to the user. */
+ if (tdep->ppc_ev0_upper_regnum >= 0
+ && tdep->ppc_ev0_upper_regnum <= regno
+ && regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
+ return "";
+
+ /* Check if the SPE pseudo registers are available. */
+ if (tdep->ppc_ev0_regnum >= 0
+ && tdep->ppc_ev0_regnum <= regno
+ && regno < tdep->ppc_ev0_regnum + ppc_num_gprs)
+ {
+ static const char *const spe_regnames[] = {
+ "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",
+ };
+ return spe_regnames[regno - tdep->ppc_ev0_regnum];
+ }
+
+ return tdesc_register_name (regno);
}

-/* Return the GDB type object for the "standard" data type
- of data in register N. */
+/* Return the GDB type object for the "standard" data type of data in
+ register N. */

static struct type *
-rs6000_register_type (struct gdbarch *gdbarch, int n)
+rs6000_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- const struct reg *reg = tdep->regs + n;

- if (reg->fpr)
- return builtin_type_double;
- else
- {
- int size = regsize (reg, tdep->wordsize);
- switch (size)
- {
- case 0:
- return builtin_type_int0;
- case 4:
- return builtin_type_uint32;
- case 8:
- if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum)
- return rs6000_builtin_type_vec64 (gdbarch);
- else
- return builtin_type_uint64;
- break;
- case 16:
- return rs6000_builtin_type_vec128 (gdbarch);
- break;
- default:
- internal_error (__FILE__, __LINE__, _("Register %d size %d unknown"),
- n, size);
- }
- }
+ /* These are the only pseudo-registers we support. */
+ gdb_assert (tdep->ppc_ev0_regnum >= 0
+ && regnum >= tdep->ppc_ev0_regnum
+ && regnum < tdep->ppc_ev0_regnum + 32);
+
+ return rs6000_builtin_type_vec64 (gdbarch);
}

/* Is REGNUM a member of REGGROUP? */
static int
-rs6000_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
+rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *group)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int float_p;
- int vector_p;
- int general_p;
-
- if (gdbarch_register_name (gdbarch, regnum) == NULL
- || *gdbarch_register_name (gdbarch, regnum) == '\0')
- return 0;
- if (group == all_reggroup)
- return 1;

- float_p = (regnum == tdep->ppc_fpscr_regnum
- || (regnum >= tdep->ppc_fp0_regnum
- && regnum < tdep->ppc_fp0_regnum + 32));
- if (group == float_reggroup)
- return float_p;
-
- vector_p = ((tdep->ppc_vr0_regnum >= 0
- && regnum >= tdep->ppc_vr0_regnum
- && regnum < tdep->ppc_vr0_regnum + 32)
- || (tdep->ppc_ev0_regnum >= 0
- && regnum >= tdep->ppc_ev0_regnum
- && regnum < tdep->ppc_ev0_regnum + 32)
- || regnum == tdep->ppc_vrsave_regnum - 1 /* vscr */
- || regnum == tdep->ppc_vrsave_regnum
- || regnum == tdep->ppc_acc_regnum
- || regnum == tdep->ppc_spefscr_regnum);
- if (group == vector_reggroup)
- return vector_p;
-
- /* Note that PS aka MSR isn't included - it's a system register (and
- besides, due to GCC's CFI foobar you do not want to restore
- it). */
- general_p = ((regnum >= tdep->ppc_gp0_regnum
- && regnum < tdep->ppc_gp0_regnum + 32)
- || regnum == tdep->ppc_toc_regnum
- || regnum == tdep->ppc_cr_regnum
- || regnum == tdep->ppc_lr_regnum
- || regnum == tdep->ppc_ctr_regnum
- || regnum == tdep->ppc_xer_regnum
- || regnum == gdbarch_pc_regnum (gdbarch));
- if (group == general_reggroup)
- return general_p;
+ /* These are the only pseudo-registers we support. */
+ gdb_assert (tdep->ppc_ev0_regnum >= 0
+ && regnum >= tdep->ppc_ev0_regnum
+ && regnum < tdep->ppc_ev0_regnum + 32);

- if (group == save_reggroup || group == restore_reggroup)
- return general_p || vector_p || float_p;
-
- return 0;
+ if (group == all_reggroup || group == vector_reggroup)
+ return 1;
+ else
+ return 0;
}

/* The register format for RS/6000 floating point registers is always
@@ -2331,11 +2284,13 @@ rs6000_register_reggroup_p (struct gdbar
static int
rs6000_convert_register_p (int regnum, struct type *type)
{
- const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum;
-
- return (reg->fpr
- && TYPE_CODE (type) == TYPE_CODE_FLT
- && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double));
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ return (tdep->ppc_fp0_regnum >= 0
+ && regnum >= tdep->ppc_fp0_regnum
+ && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs
+ && TYPE_CODE (type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (type) != TYPE_LENGTH (builtin_type_double));
}

static void
@@ -2344,10 +2299,8 @@ rs6000_register_to_value (struct frame_i
struct type *type,
gdb_byte *to)
{
- const struct reg *reg = gdbarch_tdep (get_frame_arch (frame))->regs + regnum;
gdb_byte from[MAX_REGISTER_SIZE];

- gdb_assert (reg->fpr);
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

get_frame_register (frame, regnum, from);
@@ -2360,10 +2313,8 @@ rs6000_value_to_register (struct frame_i
struct type *type,
const gdb_byte *from)
{
- const struct reg *reg = gdbarch_tdep (get_frame_arch (frame))->regs + regnum;
gdb_byte to[MAX_REGISTER_SIZE];

- gdb_assert (reg->fpr);
gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

convert_typed_floating (from, type, to, builtin_type_double);
@@ -2461,28 +2412,6 @@ e500_pseudo_register_write (struct gdbar
gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}

-/* The E500 needs a custom reggroup function: it has anonymous raw
- registers, and default_register_reggroup_p assumes that anonymous
- registers are not members of any reggroup. */
-static int
-e500_register_reggroup_p (struct gdbarch *gdbarch,
- int regnum,
- struct reggroup *group)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-
- /* The save and restore register groups need to include the
- upper-half registers, even though they're anonymous. */
- if ((group == save_reggroup
- || group == restore_reggroup)
- && (tdep->ppc_ev0_upper_regnum <= regnum
- && regnum < tdep->ppc_ev0_upper_regnum + ppc_num_gprs))
- return 1;
-
- /* In all other regards, the default reggroup definition is fine. */
- return default_register_reggroup_p (gdbarch, regnum, group);
-}
-
/* Convert a DBX STABS register number to a GDB register number. */
static int
rs6000_stab_reg_to_regnum (int num)
@@ -2669,370 +2598,6 @@ rs6000_convert_from_func_ptr_addr (struc

/* Handling the various POWER/PowerPC variants. */

-
-/* The arrays here called registers_MUMBLE hold information about available
- registers.
-
- 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.
-
- Note: kevinb/2002-04-30: Support for the fpscr register was added
- during April, 2002. Slot 70 is being used for PowerPC and slot 71
- for Power. For PowerPC, slot 70 was unused and was already in the
- PPC_UISA_SPRS which is ideally where fpscr should go. For Power,
- slot 70 was being used for "mq", so the next available slot (71)
- was chosen. It would have been nice to be able to make the
- register numbers the same across processor cores, but this wasn't
- possible without either 1) renumbering some registers for some
- processors or 2) assigning fpscr to a really high slot that's
- larger than any current register number. Doing (1) is bad because
- existing stubs would break. Doing (2) is undesirable because it
- would introduce a really large gap between fpscr and the rest of
- the registers for most processors. */
-
-/* Convenience macros for populating register arrays. */
-
-/* Within another macro, convert S to a string. */
-
-#define STR(s) #s
-
-/* Return a struct reg defining register NAME that's 32 bits on 32-bit systems
- and 64 bits on 64-bit systems. */
-#define R(name) { STR(name), 4, 8, 0, 0, -1 }
-
-/* Return a struct reg defining register NAME that's 32 bits on all
- systems. */
-#define R4(name) { STR(name), 4, 4, 0, 0, -1 }
-
-/* Return a struct reg defining register NAME that's 64 bits on all
- systems. */
-#define R8(name) { STR(name), 8, 8, 0, 0, -1 }
-
-/* Return a struct reg defining register NAME that's 128 bits on all
- systems. */
-#define R16(name) { STR(name), 16, 16, 0, 0, -1 }
-
-/* Return a struct reg defining floating-point register NAME. */
-#define F(name) { STR(name), 8, 8, 1, 0, -1 }
-
-/* Return a struct reg defining a pseudo register NAME that is 64 bits
- long on all systems. */
-#define P8(name) { STR(name), 8, 8, 0, 1, -1 }
-
-/* Return a struct reg defining register NAME that's 32 bits on 32-bit
- systems and that doesn't exist on 64-bit systems. */
-#define R32(name) { STR(name), 4, 0, 0, 0, -1 }
-
-/* Return a struct reg defining register NAME that's 64 bits on 64-bit
- systems and that doesn't exist on 32-bit systems. */
-#define R64(name) { STR(name), 0, 8, 0, 0, -1 }
-
-/* Return a struct reg placeholder for a register that doesn't exist. */
-#define R0 { 0, 0, 0, 0, 0, -1 }
-
-/* Return a struct reg defining an anonymous raw register that's 32
- bits on all systems. */
-#define A4 { 0, 4, 4, 0, 0, -1 }
-
-/* Return a struct reg defining an SPR named NAME that is 32 bits on
- 32-bit systems and 64 bits on 64-bit systems. */
-#define S(name) { STR(name), 4, 8, 0, 0, ppc_spr_ ## name }
-
-/* Return a struct reg defining an SPR named NAME that is 32 bits on
- all systems. */
-#define S4(name) { STR(name), 4, 4, 0, 0, ppc_spr_ ## name }
-
-/* Return a struct reg defining an SPR named NAME that is 32 bits on
- all systems, and whose SPR number is NUMBER. */
-#define SN4(name, number) { STR(name), 4, 4, 0, 0, (number) }
-
-/* Return a struct reg defining an SPR named NAME that's 64 bits on
- 64-bit systems and that doesn't exist on 32-bit systems. */
-#define S64(name) { STR(name), 0, 8, 0, 0, ppc_spr_ ## name }
-
-/* UISA registers common across all architectures, including POWER. */
-
-#define COMMON_UISA_REGS \
- /* 0 */ R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), \
- /* 8 */ R(r8), R(r9), R(r10),R(r11),R(r12),R(r13),R(r14),R(r15), \
- /* 16 */ R(r16),R(r17),R(r18),R(r19),R(r20),R(r21),R(r22),R(r23), \
- /* 24 */ R(r24),R(r25),R(r26),R(r27),R(r28),R(r29),R(r30),R(r31), \
- /* 32 */ F(f0), F(f1), F(f2), F(f3), F(f4), F(f5), F(f6), F(f7), \
- /* 40 */ F(f8), F(f9), F(f10),F(f11),F(f12),F(f13),F(f14),F(f15), \
- /* 48 */ F(f16),F(f17),F(f18),F(f19),F(f20),F(f21),F(f22),F(f23), \
- /* 56 */ F(f24),F(f25),F(f26),F(f27),F(f28),F(f29),F(f30),F(f31), \
- /* 64 */ R(pc), R(ps)
-
-/* UISA-level SPRs for PowerPC. */
-#define PPC_UISA_SPRS \
- /* 66 */ R4(cr), S(lr), S(ctr), S4(xer), R4(fpscr)
-
-/* UISA-level SPRs for PowerPC without floating point support. */
-#define PPC_UISA_NOFP_SPRS \
- /* 66 */ R4(cr), S(lr), S(ctr), S4(xer), R0
-
-/* Segment registers, for PowerPC. */
-#define PPC_SEGMENT_REGS \
- /* 71 */ R32(sr0), R32(sr1), R32(sr2), R32(sr3), \
- /* 75 */ R32(sr4), R32(sr5), R32(sr6), R32(sr7), \
- /* 79 */ R32(sr8), R32(sr9), R32(sr10), R32(sr11), \
- /* 83 */ R32(sr12), R32(sr13), R32(sr14), R32(sr15)
-
-/* OEA SPRs for PowerPC. */
-#define PPC_OEA_SPRS \
- /* 87 */ S4(pvr), \
- /* 88 */ S(ibat0u), S(ibat0l), S(ibat1u), S(ibat1l), \
- /* 92 */ S(ibat2u), S(ibat2l), S(ibat3u), S(ibat3l), \
- /* 96 */ S(dbat0u), S(dbat0l), S(dbat1u), S(dbat1l), \
- /* 100 */ S(dbat2u), S(dbat2l), S(dbat3u), S(dbat3l), \
- /* 104 */ S(sdr1), S64(asr), S(dar), S4(dsisr), \
- /* 108 */ S(sprg0), S(sprg1), S(sprg2), S(sprg3), \
- /* 112 */ S(srr0), S(srr1), S(tbl), S(tbu), \
- /* 116 */ S4(dec), S(dabr), S4(ear)
-
-/* AltiVec registers. */
-#define PPC_ALTIVEC_REGS \
- /*119*/R16(vr0), R16(vr1), R16(vr2), R16(vr3), R16(vr4), R16(vr5), R16(vr6), R16(vr7), \
- /*127*/R16(vr8), R16(vr9), R16(vr10),R16(vr11),R16(vr12),R16(vr13),R16(vr14),R16(vr15), \
- /*135*/R16(vr16),R16(vr17),R16(vr18),R16(vr19),R16(vr20),R16(vr21),R16(vr22),R16(vr23), \
- /*143*/R16(vr24),R16(vr25),R16(vr26),R16(vr27),R16(vr28),R16(vr29),R16(vr30),R16(vr31), \
- /*151*/R4(vscr), R4(vrsave)
-
-
-/* On machines supporting the SPE APU, the general-purpose registers
- are 64 bits long. There are SIMD vector instructions to treat them
- as pairs of floats, but the rest of the instruction set treats them
- as 32-bit registers, and only operates on their lower halves.
-
- In the GDB regcache, we treat their high and low halves as separate
- registers. The low halves we present as the general-purpose
- registers, and then we have pseudo-registers that stitch together
- the upper and lower halves and present them as pseudo-registers. */
-
-/* SPE GPR lower halves --- raw registers. */
-#define PPC_SPE_GP_REGS \
- /* 0 */ R4(r0), R4(r1), R4(r2), R4(r3), R4(r4), R4(r5), R4(r6), R4(r7), \
- /* 8 */ R4(r8), R4(r9), R4(r10),R4(r11),R4(r12),R4(r13),R4(r14),R4(r15), \
- /* 16 */ R4(r16),R4(r17),R4(r18),R4(r19),R4(r20),R4(r21),R4(r22),R4(r23), \
- /* 24 */ R4(r24),R4(r25),R4(r26),R4(r27),R4(r28),R4(r29),R4(r30),R4(r31)
-
-/* SPE GPR upper halves --- anonymous raw registers. */
-#define PPC_SPE_UPPER_GP_REGS \
- /* 0 */ A4, A4, A4, A4, A4, A4, A4, A4, \
- /* 8 */ A4, A4, A4, A4, A4, A4, A4, A4, \
- /* 16 */ A4, A4, A4, A4, A4, A4, A4, A4, \
- /* 24 */ A4, A4, A4, A4, A4, A4, A4, A4
-
-/* SPE GPR vector registers --- pseudo registers based on underlying
- gprs and the anonymous upper half raw registers. */
-#define PPC_EV_PSEUDO_REGS \
-/* 0*/P8(ev0), P8(ev1), P8(ev2), P8(ev3), P8(ev4), P8(ev5), P8(ev6), P8(ev7), \
-/* 8*/P8(ev8), P8(ev9), P8(ev10),P8(ev11),P8(ev12),P8(ev13),P8(ev14),P8(ev15),\
-/*16*/P8(ev16),P8(ev17),P8(ev18),P8(ev19),P8(ev20),P8(ev21),P8(ev22),P8(ev23),\
-/*24*/P8(ev24),P8(ev25),P8(ev26),P8(ev27),P8(ev28),P8(ev29),P8(ev30),P8(ev31)
-
-/* IBM POWER (pre-PowerPC) architecture, user-level view. We only cover
- user-level SPR's. */
-static const struct reg registers_power[] =
-{
- COMMON_UISA_REGS,
- /* 66 */ R4(cnd), S(lr), S(cnt), S4(xer), S4(mq),
- /* 71 */ R4(fpscr)
-};
-
-/* PowerPC UISA - a PPC processor as viewed by user-level code. A UISA-only
- view of the PowerPC. */
-static const struct reg registers_powerpc[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_ALTIVEC_REGS
-};
-
-/* IBM PowerPC 403.
-
- Some notes about the "tcr" special-purpose register:
- - On the 403 and 403GC, SPR 986 is named "tcr", and it controls the
- 403's programmable interval timer, fixed interval timer, and
- watchdog timer.
- - On the 602, SPR 984 is named "tcr", and it controls the 602's
- watchdog timer, and nothing else.
-
- Some of the fields are similar between the two, but they're not
- compatible with each other. Since the two variants have different
- registers, with different numbers, but the same name, we can't
- splice the register name to get the SPR number. */
-static const struct reg registers_403[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(icdbdr), S(esr), S(dear), S(evpr),
- /* 123 */ S(cdbcr), S(tsr), SN4(tcr, ppc_spr_403_tcr), S(pit),
- /* 127 */ S(tbhi), S(tblo), S(srr2), S(srr3),
- /* 131 */ S(dbsr), S(dbcr), S(iac1), S(iac2),
- /* 135 */ S(dac1), S(dac2), S(dccr), S(iccr),
- /* 139 */ S(pbl1), S(pbu1), S(pbl2), S(pbu2)
-};
-
-/* IBM PowerPC 403GC.
- See the comments about 'tcr' for the 403, above. */
-static const struct reg registers_403GC[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(icdbdr), S(esr), S(dear), S(evpr),
- /* 123 */ S(cdbcr), S(tsr), SN4(tcr, ppc_spr_403_tcr), S(pit),
- /* 127 */ S(tbhi), S(tblo), S(srr2), S(srr3),
- /* 131 */ S(dbsr), S(dbcr), S(iac1), S(iac2),
- /* 135 */ S(dac1), S(dac2), S(dccr), S(iccr),
- /* 139 */ S(pbl1), S(pbu1), S(pbl2), S(pbu2),
- /* 143 */ S(zpr), S(pid), S(sgr), S(dcwr),
- /* 147 */ S(tbhu), S(tblu)
-};
-
-/* Motorola PowerPC 505. */
-static const struct reg registers_505[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(eie), S(eid), S(nri)
-};
-
-/* Motorola PowerPC 860 or 850. */
-static const struct reg registers_860[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(eie), S(eid), S(nri), S(cmpa),
- /* 123 */ S(cmpb), S(cmpc), S(cmpd), S(icr),
- /* 127 */ S(der), S(counta), S(countb), S(cmpe),
- /* 131 */ S(cmpf), S(cmpg), S(cmph), S(lctrl1),
- /* 135 */ S(lctrl2), S(ictrl), S(bar), S(ic_cst),
- /* 139 */ S(ic_adr), S(ic_dat), S(dc_cst), S(dc_adr),
- /* 143 */ S(dc_dat), S(dpdr), S(dpir), S(immr),
- /* 147 */ S(mi_ctr), S(mi_ap), S(mi_epn), S(mi_twc),
- /* 151 */ S(mi_rpn), S(md_ctr), S(m_casid), S(md_ap),
- /* 155 */ S(md_epn), S(m_twb), S(md_twc), S(md_rpn),
- /* 159 */ S(m_tw), S(mi_dbcam), S(mi_dbram0), S(mi_dbram1),
- /* 163 */ S(md_dbcam), S(md_dbram0), S(md_dbram1)
-};
-
-/* Motorola PowerPC 601. 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. */
-static const struct reg registers_601[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr),
- /* 123 */ S(pir), S(mq), S(rtcu), S(rtcl)
-};
-
-/* Motorola PowerPC 602.
- See the notes under the 403 about 'tcr'. */
-static const struct reg registers_602[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(hid0), S(hid1), S(iabr), R0,
- /* 123 */ R0, SN4(tcr, ppc_spr_602_tcr), S(ibr), S(esasrr),
- /* 127 */ S(sebr), S(ser), S(sp), S(lt)
-};
-
-/* Motorola/IBM PowerPC 603 or 603e. */
-static const struct reg registers_603[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(hid0), S(hid1), S(iabr), R0,
- /* 123 */ R0, S(dmiss), S(dcmp), S(hash1),
- /* 127 */ S(hash2), S(imiss), S(icmp), S(rpa)
-};
-
-/* Motorola PowerPC 604 or 604e. */
-static const struct reg registers_604[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr),
- /* 123 */ S(pir), S(mmcr0), S(pmc1), S(pmc2),
- /* 127 */ S(sia), S(sda)
-};
-
-/* Motorola/IBM PowerPC 750 or 740. */
-static const struct reg registers_750[] =
-{
- COMMON_UISA_REGS,
- PPC_UISA_SPRS,
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* 119 */ S(hid0), S(hid1), S(iabr), S(dabr),
- /* 123 */ R0, S(ummcr0), S(upmc1), S(upmc2),
- /* 127 */ S(usia), S(ummcr1), S(upmc3), S(upmc4),
- /* 131 */ S(mmcr0), S(pmc1), S(pmc2), S(sia),
- /* 135 */ S(mmcr1), S(pmc3), S(pmc4), S(l2cr),
- /* 139 */ S(ictc), S(thrm1), S(thrm2), S(thrm3)
-};
-
-
-/* Motorola PowerPC 7400. */
-static const struct reg registers_7400[] =
-{
- /* gpr0-gpr31, fpr0-fpr31 */
- COMMON_UISA_REGS,
- /* cr, lr, ctr, xer, fpscr */
- PPC_UISA_SPRS,
- /* sr0-sr15 */
- PPC_SEGMENT_REGS,
- PPC_OEA_SPRS,
- /* vr0-vr31, vrsave, vscr */
- PPC_ALTIVEC_REGS
- /* FIXME? Add more registers? */
-};
-
-/* Motorola e500. */
-static const struct reg registers_e500[] =
-{
- /* 0 .. 31 */ PPC_SPE_GP_REGS,
- /* 32 .. 63 */ PPC_SPE_UPPER_GP_REGS,
- /* 64 .. 65 */ R(pc), R(ps),
- /* 66 .. 70 */ PPC_UISA_NOFP_SPRS,
- /* 71 .. 72 */ R8(acc), S4(spefscr),
- /* NOTE: Add new registers here the end of the raw register
- list and just before the first pseudo register. */
- /* 73 .. 104 */ PPC_EV_PSEUDO_REGS
-};
-
/* Information about a particular processor variant. */

struct variant
@@ -3049,151 +2614,64 @@ struct variant
/* bfd_arch_info.mach corresponding to variant. */
unsigned long mach;

- /* Number of real registers. */
- int nregs;
-
- /* Number of pseudo registers. */
- int npregs;
-
- /* Number of total registers (the sum of nregs and npregs). */
- int num_tot_regs;
-
- /* Table of register names; registers[R] is the name of the register
- number R. */
- const struct reg *regs;
+ /* Target description for this variant. */
+ struct target_desc **tdesc;
};

-#define tot_num_registers(list) (sizeof (list) / sizeof((list)[0]))
-
-static int
-num_registers (const struct reg *reg_list, int num_tot_regs)
-{
- int i;
- int nregs = 0;
-
- for (i = 0; i < num_tot_regs; i++)
- if (!reg_list[i].pseudo)
- nregs++;
-
- return nregs;
-}
-
-static int
-num_pseudo_registers (const struct reg *reg_list, int num_tot_regs)
-{
- int i;
- int npregs = 0;
-
- for (i = 0; i < num_tot_regs; i++)
- if (reg_list[i].pseudo)
- npregs ++;
-
- return npregs;
-}
-
-/* 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[] =
{
-
{"powerpc", "PowerPC user-level", bfd_arch_powerpc,
- bfd_mach_ppc, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc, &tdesc_powerpc_32},
{"power", "POWER user-level", bfd_arch_rs6000,
- bfd_mach_rs6k, -1, -1, tot_num_registers (registers_power),
- registers_power},
+ bfd_mach_rs6k, &tdesc_rs6000},
{"403", "IBM PowerPC 403", bfd_arch_powerpc,
- bfd_mach_ppc_403, -1, -1, tot_num_registers (registers_403),
- registers_403},
+ bfd_mach_ppc_403, &tdesc_powerpc_403},
{"601", "Motorola PowerPC 601", bfd_arch_powerpc,
- bfd_mach_ppc_601, -1, -1, tot_num_registers (registers_601),
- registers_601},
+ bfd_mach_ppc_601, &tdesc_powerpc_601},
{"602", "Motorola PowerPC 602", bfd_arch_powerpc,
- bfd_mach_ppc_602, -1, -1, tot_num_registers (registers_602),
- registers_602},
+ bfd_mach_ppc_602, &tdesc_powerpc_602},
{"603", "Motorola/IBM PowerPC 603 or 603e", bfd_arch_powerpc,
- bfd_mach_ppc_603, -1, -1, tot_num_registers (registers_603),
- registers_603},
+ bfd_mach_ppc_603, &tdesc_powerpc_603},
{"604", "Motorola PowerPC 604 or 604e", bfd_arch_powerpc,
- 604, -1, -1, tot_num_registers (registers_604),
- registers_604},
+ 604, &tdesc_powerpc_604},
{"403GC", "IBM PowerPC 403GC", bfd_arch_powerpc,
- bfd_mach_ppc_403gc, -1, -1, tot_num_registers (registers_403GC),
- registers_403GC},
+ bfd_mach_ppc_403gc, &tdesc_powerpc_403gc},
{"505", "Motorola PowerPC 505", bfd_arch_powerpc,
- bfd_mach_ppc_505, -1, -1, tot_num_registers (registers_505),
- registers_505},
+ bfd_mach_ppc_505, &tdesc_powerpc_505},
{"860", "Motorola PowerPC 860 or 850", bfd_arch_powerpc,
- bfd_mach_ppc_860, -1, -1, tot_num_registers (registers_860),
- registers_860},
+ bfd_mach_ppc_860, &tdesc_powerpc_860},
{"750", "Motorola/IBM PowerPC 750 or 740", bfd_arch_powerpc,
- bfd_mach_ppc_750, -1, -1, tot_num_registers (registers_750),
- registers_750},
+ bfd_mach_ppc_750, &tdesc_powerpc_750},
{"7400", "Motorola/IBM PowerPC 7400 (G4)", bfd_arch_powerpc,
- bfd_mach_ppc_7400, -1, -1, tot_num_registers (registers_7400),
- registers_7400},
+ bfd_mach_ppc_7400, &tdesc_powerpc_7400},
{"e500", "Motorola PowerPC e500", bfd_arch_powerpc,
- bfd_mach_ppc_e500, -1, -1, tot_num_registers (registers_e500),
- registers_e500},
+ bfd_mach_ppc_e500, &tdesc_powerpc_e500},

/* 64-bit */
{"powerpc64", "PowerPC 64-bit user-level", bfd_arch_powerpc,
- bfd_mach_ppc64, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc64, &tdesc_powerpc_64},
{"620", "Motorola PowerPC 620", bfd_arch_powerpc,
- bfd_mach_ppc_620, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc_620, &tdesc_powerpc_64},
{"630", "Motorola PowerPC 630", bfd_arch_powerpc,
- bfd_mach_ppc_630, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc_630, &tdesc_powerpc_64},
{"a35", "PowerPC A35", bfd_arch_powerpc,
- bfd_mach_ppc_a35, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc_a35, &tdesc_powerpc_64},
{"rs64ii", "PowerPC rs64ii", bfd_arch_powerpc,
- bfd_mach_ppc_rs64ii, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc_rs64ii, &tdesc_powerpc_64},
{"rs64iii", "PowerPC rs64iii", bfd_arch_powerpc,
- bfd_mach_ppc_rs64iii, -1, -1, tot_num_registers (registers_powerpc),
- registers_powerpc},
+ bfd_mach_ppc_rs64iii, &tdesc_powerpc_64},

/* FIXME: I haven't checked the register sets of the following. */
{"rs1", "IBM POWER RS1", bfd_arch_rs6000,
- bfd_mach_rs6k_rs1, -1, -1, tot_num_registers (registers_power),
- registers_power},
+ bfd_mach_rs6k_rs1, &tdesc_rs6000},
{"rsc", "IBM POWER RSC", bfd_arch_rs6000,
- bfd_mach_rs6k_rsc, -1, -1, tot_num_registers (registers_power),
- registers_power},
+ bfd_mach_rs6k_rsc, &tdesc_rs6000},
{"rs2", "IBM POWER RS2", bfd_arch_rs6000,
- bfd_mach_rs6k_rs2, -1, -1, tot_num_registers (registers_power),
- registers_power},
+ bfd_mach_rs6k_rs2, &tdesc_rs6000},

- {0, 0, 0, 0, 0, 0, 0, 0}
+ {0, 0, 0, 0, 0}
};

-/* Initialize the number of registers and pseudo registers in each variant. */
-
-static void
-init_variants (void)
-{
- struct variant *v;
-
- for (v = variants; v->name; v++)
- {
- if (v->nregs == -1)
- v->nregs = num_registers (v->regs, v->num_tot_regs);
- if (v->npregs == -1)
- v->npregs = num_pseudo_registers (v->regs, v->num_tot_regs);
- }
-}
-
/* Return the variant corresponding to architecture ARCH and machine number
MACH. If no such variant exists, return null. */

@@ -3481,14 +2959,17 @@ rs6000_gdbarch_init (struct gdbarch_info
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
- int wordsize, from_xcoff_exec, from_elf_exec, i, off;
- struct reg *regs;
- const struct variant *v;
+ int wordsize, from_xcoff_exec, from_elf_exec;
enum bfd_architecture arch;
unsigned long mach;
bfd abfd;
int sysv_abi;
asection *sect;
+ int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
+ int tdesc_wordsize = -1;
+ const struct target_desc *tdesc = info.target_desc;
+ struct tdesc_arch_data *tdesc_data = NULL;
+ int num_sprs = 0;

from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
@@ -3514,6 +2995,8 @@ rs6000_gdbarch_init (struct gdbarch_info
else
wordsize = 4;
}
+ else if (tdesc_has_registers (tdesc))
+ wordsize = -1;
else
{
if (info.bfd_arch_info != NULL && info.bfd_arch_info->bits_per_word != 0)
@@ -3523,27 +3006,6 @@ rs6000_gdbarch_init (struct gdbarch_info
wordsize = 4;
}

- /* Find a candidate among extant architectures. */
- for (arches = gdbarch_list_lookup_by_info (arches, &info);
- arches != NULL;
- arches = gdbarch_list_lookup_by_info (arches->next, &info))
- {
- /* Word size in the various PowerPC bfd_arch_info structs isn't
- meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
- separate word size check. */
- tdep = gdbarch_tdep (arches->gdbarch);
- if (tdep && tdep->wordsize == wordsize)
- return arches->gdbarch;
- }
-
- /* None found, create a new architecture from INFO, whose bfd_arch_info
- validity depends on the source:
- - executable useless
- - rs6000_host_arch() good
- - core file good
- - "set arch" trust blindly
- - GDB startup useless but harmless */
-
if (!from_xcoff_exec)
{
arch = info.bfd_arch_info->arch;
@@ -3556,8 +3018,6 @@ rs6000_gdbarch_init (struct gdbarch_info
info.bfd_arch_info = bfd_get_arch_info (&abfd);
mach = info.bfd_arch_info->mach;
}
- tdep = XCALLOC (1, struct gdbarch_tdep);
- tdep->wordsize = wordsize;

/* For e500 executables, the apuinfo section is of help here. Such
section contains the identifier and revision number of each
@@ -3579,47 +3039,262 @@ rs6000_gdbarch_init (struct gdbarch_info
}
}

- gdbarch = gdbarch_alloc (&info, tdep);
+ /* Find a default target description which describes our register
+ layout, if we do not already have one. */
+ if (! tdesc_has_registers (tdesc))
+ {
+ const struct variant *v;
+
+ /* Choose variant. */
+ v = find_variant_by_arch (arch, mach);
+ if (!v)
+ return NULL;
+
+ tdesc = *v->tdesc;
+ }
+
+ gdb_assert (tdesc_has_registers (tdesc));
+
+ /* Check any target description for validity. */
+ if (tdesc_has_registers (tdesc))
+ {
+ static const char *const 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 segment_regs[] = {
+ "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
+ "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15"
+ };
+ const struct tdesc_feature *feature;
+ int i, valid_p;
+ static const char *const msr_names[] = { "msr", "ps" };
+ static const char *const cr_names[] = { "cr", "cnd" };
+ static const char *const ctr_names[] = { "ctr", "cnt" };
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.core");
+ if (feature == NULL)
+ return NULL;
+
+ tdesc_data = tdesc_data_alloc ();
+
+ valid_p = 1;
+ for (i = 0; i < ppc_num_gprs; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, i, gprs[i]);
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_PC_REGNUM,
+ "pc");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_LR_REGNUM,
+ "lr");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data, PPC_XER_REGNUM,
+ "xer");
+
+ /* Allow alternate names for these registers, to accomodate GDB's
+ historic naming. */
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ PPC_MSR_REGNUM, msr_names);
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ PPC_CR_REGNUM, cr_names);
+ valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
+ PPC_CTR_REGNUM, ctr_names);
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ have_mq = tdesc_numbered_register (feature, tdesc_data, PPC_MQ_REGNUM,
+ "mq");
+
+ tdesc_wordsize = tdesc_register_size (feature, "pc") / 8;
+ if (wordsize == -1)
+ wordsize = tdesc_wordsize;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.fpu");
+ if (feature != NULL)
+ {
+ static const char *const 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"
+ };
+ valid_p = 1;
+ for (i = 0; i < ppc_num_fprs; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_F0_REGNUM + i, fprs[i]);
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_FPSCR_REGNUM, "fpscr");

- /* Initialize the number of real and pseudo registers in each variant. */
- init_variants ();
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_fpu = 1;
+ }
+ else
+ have_fpu = 0;

- /* Choose variant. */
- v = find_variant_by_arch (arch, mach);
- if (!v)
- return NULL;
-
- tdep->regs = v->regs;
-
- tdep->ppc_gp0_regnum = 0;
- tdep->ppc_toc_regnum = 2;
- tdep->ppc_ps_regnum = 65;
- tdep->ppc_cr_regnum = 66;
- tdep->ppc_lr_regnum = 67;
- tdep->ppc_ctr_regnum = 68;
- tdep->ppc_xer_regnum = 69;
- if (v->mach == bfd_mach_ppc_601)
- tdep->ppc_mq_regnum = 124;
- else if (arch == bfd_arch_rs6000)
- tdep->ppc_mq_regnum = 70;
- else
- tdep->ppc_mq_regnum = -1;
- tdep->ppc_fp0_regnum = 32;
- tdep->ppc_fpscr_regnum = (arch == bfd_arch_rs6000) ? 71 : 70;
- tdep->ppc_sr0_regnum = 71;
- tdep->ppc_vr0_regnum = -1;
- tdep->ppc_vrsave_regnum = -1;
- tdep->ppc_ev0_upper_regnum = -1;
- tdep->ppc_ev0_regnum = -1;
- tdep->ppc_ev31_regnum = -1;
- tdep->ppc_acc_regnum = -1;
- tdep->ppc_spefscr_regnum = -1;
-
- set_gdbarch_pc_regnum (gdbarch, 64);
- set_gdbarch_sp_regnum (gdbarch, 1);
- set_gdbarch_deprecated_fp_regnum (gdbarch, 1);
- set_gdbarch_fp0_regnum (gdbarch, 32);
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.altivec");
+ if (feature != NULL)
+ {
+ static const char *const vector_regs[] = {
+ "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"
+ };
+
+ valid_p = 1;
+ for (i = 0; i < ppc_num_gprs; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_VR0_REGNUM + i,
+ vector_regs[i]);
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_VSCR_REGNUM, "vscr");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_VRSAVE_REGNUM, "vrsave");
+
+ if (have_spe || !valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_altivec = 1;
+ }
+ else
+ have_altivec = 0;
+
+ /* On machines supporting the SPE APU, the general-purpose registers
+ are 64 bits long. There are SIMD vector instructions to treat them
+ as pairs of floats, but the rest of the instruction set treats them
+ as 32-bit registers, and only operates on their lower halves.
+
+ In the GDB regcache, we treat their high and low halves as separate
+ registers. The low halves we present as the general-purpose
+ registers, and then we have pseudo-registers that stitch together
+ the upper and lower halves and present them as pseudo-registers.
+
+ Thus, the target description is expected to supply the upper
+ halves separately. */
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.spe");
+ if (feature != NULL)
+ {
+ static const char *const upper_spe[] = {
+ "ev0h", "ev1h", "ev2h", "ev3h",
+ "ev4h", "ev5h", "ev6h", "ev7h",
+ "ev8h", "ev9h", "ev10h", "ev11h",
+ "ev12h", "ev13h", "ev14h", "ev15h",
+ "ev16h", "ev17h", "ev18h", "ev19h",
+ "ev20h", "ev21h", "ev22h", "ev23h",
+ "ev24h", "ev25h", "ev26h", "ev27h",
+ "ev28h", "ev29h", "ev30h", "ev31h"
+ };
+
+ valid_p = 1;
+ for (i = 0; i < ppc_num_gprs; i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SPE_UPPER_GP0_REGNUM + i,
+ upper_spe[i]);
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SPE_ACC_REGNUM, "acc");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SPE_FSCR_REGNUM, "spefscr");
+
+ if (have_mq || have_fpu || !valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_spe = 1;
+ }
+ else
+ have_spe = 0;
+ }
+
+ /* If we have a 64-bit binary on a 32-bit target, complain. Also
+ complain for a 32-bit binary on a 64-bit target; we do not yet
+ support that. For instance, the 32-bit ABI routines expect
+ 32-bit GPRs.
+
+ As long as there isn't an explicit target description, we'll
+ choose one based on the BFD architecture and get a word size
+ matching the binary (probably powerpc:common or
+ powerpc:common64). So there is only trouble if a 64-bit target
+ supplies a 64-bit description while debugging a 32-bit
+ binary. */
+ if (tdesc_wordsize != -1 && tdesc_wordsize != wordsize)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ /* Find a candidate among extant architectures. */
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Word size in the various PowerPC bfd_arch_info structs isn't
+ meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
+ separate word size check. */
+ tdep = gdbarch_tdep (arches->gdbarch);
+ if (tdep && tdep->wordsize == wordsize)
+ {
+ if (tdesc_data != NULL)
+ tdesc_data_cleanup (tdesc_data);
+ return arches->gdbarch;
+ }
+ }
+
+ /* None found, create a new architecture from INFO, whose bfd_arch_info
+ validity depends on the source:
+ - executable useless
+ - rs6000_host_arch() good
+ - core file good
+ - "set arch" trust blindly
+ - GDB startup useless but harmless */
+
+ tdep = XCALLOC (1, struct gdbarch_tdep);
+ tdep->wordsize = wordsize;
+
+ gdbarch = gdbarch_alloc (&info, tdep);
+
+ tdep->ppc_gp0_regnum = PPC_R0_REGNUM;
+ tdep->ppc_toc_regnum = PPC_R0_REGNUM + 2;
+ tdep->ppc_ps_regnum = PPC_MSR_REGNUM;
+ tdep->ppc_cr_regnum = PPC_CR_REGNUM;
+ tdep->ppc_lr_regnum = PPC_LR_REGNUM;
+ tdep->ppc_ctr_regnum = PPC_CTR_REGNUM;
+ tdep->ppc_xer_regnum = PPC_XER_REGNUM;
+ tdep->ppc_mq_regnum = have_mq ? PPC_MQ_REGNUM : -1;
+
+ tdep->ppc_fp0_regnum = have_fpu ? PPC_F0_REGNUM : -1;
+ tdep->ppc_fpscr_regnum = have_fpu ? PPC_FPSCR_REGNUM : -1;
+ tdep->ppc_vr0_regnum = have_altivec ? PPC_VR0_REGNUM : -1;
+ tdep->ppc_vrsave_regnum = have_altivec ? PPC_VRSAVE_REGNUM : -1;
+ tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1;
+ tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1;
+ tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1;
+
+ set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
+ set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
+ set_gdbarch_deprecated_fp_regnum (gdbarch, PPC_R0_REGNUM + 1);
+ set_gdbarch_fp0_regnum (gdbarch, tdep->ppc_fp0_regnum);
set_gdbarch_register_sim_regno (gdbarch, rs6000_register_sim_regno);
+
+ /* The XML specification for PowerPC sensibly calls the MSR "msr".
+ GDB traditionally called it "ps", though, so let GDB add an
+ alias. */
+ set_gdbarch_ps_regnum (gdbarch, tdep->ppc_ps_regnum);
+
if (sysv_abi && wordsize == 8)
set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value);
else if (sysv_abi && wordsize == 4)
@@ -3635,66 +3310,22 @@ rs6000_gdbarch_init (struct gdbarch_info
else
tdep->lr_frame_offset = 8;

- if (v->arch == bfd_arch_rs6000)
- tdep->ppc_sr0_regnum = -1;
- else if (v->arch == bfd_arch_powerpc)
- switch (v->mach)
- {
- case bfd_mach_ppc:
- tdep->ppc_sr0_regnum = -1;
- tdep->ppc_vr0_regnum = 71;
- tdep->ppc_vrsave_regnum = 104;
- break;
- case bfd_mach_ppc_7400:
- tdep->ppc_vr0_regnum = 119;
- tdep->ppc_vrsave_regnum = 152;
- break;
- case bfd_mach_ppc_e500:
- tdep->ppc_toc_regnum = -1;
- tdep->ppc_ev0_upper_regnum = 32;
- tdep->ppc_ev0_regnum = 73;
- tdep->ppc_ev31_regnum = 104;
- tdep->ppc_acc_regnum = 71;
- tdep->ppc_spefscr_regnum = 72;
- tdep->ppc_fp0_regnum = -1;
- tdep->ppc_fpscr_regnum = -1;
- tdep->ppc_sr0_regnum = -1;
- set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
- set_gdbarch_register_reggroup_p (gdbarch, e500_register_reggroup_p);
- break;
-
- case bfd_mach_ppc64:
- case bfd_mach_ppc_620:
- case bfd_mach_ppc_630:
- case bfd_mach_ppc_a35:
- case bfd_mach_ppc_rs64ii:
- case bfd_mach_ppc_rs64iii:
- /* These processor's register sets don't have segment registers. */
- tdep->ppc_sr0_regnum = -1;
- break;
- }
- else
- internal_error (__FILE__, __LINE__,
- _("rs6000_gdbarch_init: "
- "received unexpected BFD 'arch' value"));
+ if (have_spe)
+ {
+ set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
+ }

set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

- /* Sanity check on registers. */
- gdb_assert (strcmp (tdep->regs[tdep->ppc_gp0_regnum].name, "r0") == 0);
-
/* Select instruction printer. */
if (arch == bfd_arch_rs6000)
set_gdbarch_print_insn (gdbarch, print_insn_rs6000);
else
set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);

- set_gdbarch_num_regs (gdbarch, v->nregs);
- set_gdbarch_num_pseudo_regs (gdbarch, v->npregs);
- set_gdbarch_register_name (gdbarch, rs6000_register_name);
- set_gdbarch_register_type (gdbarch, rs6000_register_type);
- set_gdbarch_register_reggroup_p (gdbarch, rs6000_register_reggroup_p);
+ set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS + num_sprs);
+ set_gdbarch_num_pseudo_regs (gdbarch, have_spe ? 32 : 0);

set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
@@ -3781,17 +3412,6 @@ rs6000_gdbarch_init (struct gdbarch_info
switch (info.osabi)
{
case GDB_OSABI_LINUX:
- /* FIXME: pgilliam/2005-10-21: Assume all PowerPC 64-bit linux systems
- have altivec registers. If not, ptrace will fail the first time it's
- called to access one and will not be called again. This wart will
- be removed when Daniel Jacobowitz's proposal for autodetecting target
- registers is implemented. */
- if ((v->arch == bfd_arch_powerpc) && ((v->mach)== bfd_mach_ppc64))
- {
- tdep->ppc_vr0_regnum = 71;
- tdep->ppc_vrsave_regnum = 104;
- }
- /* Fall Thru */
case GDB_OSABI_NETBSD_AOUT:
case GDB_OSABI_NETBSD_ELF:
case GDB_OSABI_UNKNOWN:
@@ -3809,7 +3429,18 @@ rs6000_gdbarch_init (struct gdbarch_info
frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
}

- init_sim_regno_table (gdbarch);
+ set_tdesc_pseudo_register_type (gdbarch, rs6000_pseudo_register_type);
+ set_tdesc_pseudo_register_reggroup_p (gdbarch,
+ rs6000_pseudo_register_reggroup_p);
+ tdesc_use_registers (gdbarch, tdesc, tdesc_data);
+
+ /* Override the normal target description method to make the SPE upper
+ halves anonymous. */
+ set_gdbarch_register_name (gdbarch, rs6000_register_name);
+
+ /* Recording the numbering of pseudo registers. */
+ tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1;
+ tdep->ppc_ev31_regnum = have_spe ? tdep->ppc_ev0_regnum + 31 : -1;

return gdbarch;
}
@@ -3834,4 +3465,20 @@ _initialize_rs6000_tdep (void)
{
gdbarch_register (bfd_arch_rs6000, rs6000_gdbarch_init, rs6000_dump_tdep);
gdbarch_register (bfd_arch_powerpc, rs6000_gdbarch_init, rs6000_dump_tdep);
+
+ /* Initialize the standard target descriptions. */
+ initialize_tdesc_powerpc_32 ();
+ initialize_tdesc_powerpc_403 ();
+ initialize_tdesc_powerpc_403gc ();
+ initialize_tdesc_powerpc_505 ();
+ initialize_tdesc_powerpc_601 ();
+ initialize_tdesc_powerpc_602 ();
+ initialize_tdesc_powerpc_603 ();
+ initialize_tdesc_powerpc_604 ();
+ initialize_tdesc_powerpc_64 ();
+ initialize_tdesc_powerpc_7400 ();
+ initialize_tdesc_powerpc_750 ();
+ initialize_tdesc_powerpc_860 ();
+ initialize_tdesc_powerpc_e500 ();
+ initialize_tdesc_rs6000 ();
}
Index: gdb/target-descriptions.c
===================================================================
RCS file: /cvs/src/src/gdb/target-descriptions.c,v
retrieving revision 1.12
diff -u -p -r1.12 target-descriptions.c
--- gdb/target-descriptions.c 15 Oct 2007 19:19:17 -0000 1.12
+++ gdb/target-descriptions.c 15 Oct 2007 19:28:56 -0000
@@ -352,10 +352,12 @@ static struct
{ "int16", &builtin_type_int16 },
{ "int32", &builtin_type_int32 },
{ "int64", &builtin_type_int64 },
+ { "int128", &builtin_type_int128 },
{ "uint8", &builtin_type_uint8 },
{ "uint16", &builtin_type_uint16 },
{ "uint32", &builtin_type_uint32 },
{ "uint64", &builtin_type_uint64 },
+ { "uint128", &builtin_type_uint128 },
{ "ieee_single", &builtin_type_ieee_single },
{ "ieee_double", &builtin_type_ieee_double },
{ "arm_fpa_ext", &builtin_type_arm_ext }
@@ -421,10 +423,9 @@ tdesc_data_cleanup (void *data_untyped)

/* Search FEATURE for a register named NAME. */

-int
-tdesc_numbered_register (const struct tdesc_feature *feature,
- struct tdesc_arch_data *data,
- int regno, const char *name)
+static struct tdesc_reg *
+tdesc_find_register_early (const struct tdesc_feature *feature,
+ const char *name)
{
int ixr;
struct tdesc_reg *reg;
@@ -433,18 +434,32 @@ tdesc_numbered_register (const struct td
VEC_iterate (tdesc_reg_p, feature->registers, ixr, reg);
ixr++)
if (strcasecmp (reg->name, name) == 0)
- {
- /* Make sure the vector includes a REGNO'th element. */
- while (regno >= VEC_length (tdesc_reg_p, data->registers))
- VEC_safe_push (tdesc_reg_p, data->registers, NULL);
- VEC_replace (tdesc_reg_p, data->registers, regno, reg);
- return 1;
- }
+ return reg;

- return 0;
+ return NULL;
+}
+
+/* Search FEATURE for a register named NAME. Assign REGNO to it. */
+
+int
+tdesc_numbered_register (const struct tdesc_feature *feature,
+ struct tdesc_arch_data *data,
+ int regno, const char *name)
+{
+ struct tdesc_reg *reg = tdesc_find_register_early (feature, name);
+
+ if (reg == NULL)
+ return 0;
+
+ /* Make sure the vector includes a REGNO'th element. */
+ while (regno >= VEC_length (tdesc_reg_p, data->registers))
+ VEC_safe_push (tdesc_reg_p, data->registers, NULL);
+ VEC_replace (tdesc_reg_p, data->registers, regno, reg);
+ return 1;
}

-/* Search FEATURE for a register whose name is in NAMES. */
+/* Search FEATURE for a register whose name is in NAMES and assign
+ REGNO to it. */

int
tdesc_numbered_register_choices (const struct tdesc_feature *feature,
@@ -460,6 +475,19 @@ tdesc_numbered_register_choices (const s
return 0;
}

+/* Search FEATURE for a register named NAME, and return its size in
+ bits. The register must exist. */
+
+int
+tdesc_register_size (const struct tdesc_feature *feature,
+ const char *name)
+{
+ struct tdesc_reg *reg = tdesc_find_register_early (feature, name);
+
+ gdb_assert (reg != NULL);
+ return reg->bitsize;
+}
+
/* Look up a register by its GDB internal register number. */

static struct tdesc_reg *
@@ -682,18 +710,16 @@ set_tdesc_pseudo_register_reggroup_p

void
tdesc_use_registers (struct gdbarch *gdbarch,
+ const struct target_desc *target_desc,
struct tdesc_arch_data *early_data)
{
int num_regs = gdbarch_num_regs (gdbarch);
int i, ixf, ixr;
- const struct target_desc *target_desc;
struct tdesc_feature *feature;
struct tdesc_reg *reg;
struct tdesc_arch_data *data;
htab_t reg_hash;

- target_desc = gdbarch_target_desc (gdbarch);
-
/* We can't use the description for registers if it doesn't describe
any. This function should only be called after validating
registers, so the caller should know that registers are
Index: gdb/target-descriptions.h
===================================================================
RCS file: /cvs/src/src/gdb/target-descriptions.h,v
retrieving revision 1.8
diff -u -p -r1.8 target-descriptions.h
--- gdb/target-descriptions.h 23 Aug 2007 18:08:45 -0000 1.8
+++ gdb/target-descriptions.h 15 Oct 2007 19:28:56 -0000
@@ -61,8 +61,12 @@ void set_tdesc_pseudo_register_reggroup_
(struct gdbarch *gdbarch,
gdbarch_register_reggroup_p_ftype *pseudo_reggroup_p);

-/* Update GDBARCH to use the target description for registers. Fixed
- register assignments are taken from EARLY_DATA, which is freed.
+/* Update GDBARCH to use the TARGET_DESC for registers. TARGET_DESC
+ may be GDBARCH's target description or (if GDBARCH does not have
+ one which describes registers) another target description
+ constructed by the gdbarch initialization routine.
+
+ Fixed register assignments are taken from EARLY_DATA, which is freed.
All registers which have not been assigned fixed numbers are given
numbers above the current value of gdbarch_num_regs.
gdbarch_num_regs and various register-related predicates are updated to
@@ -71,6 +75,7 @@ void set_tdesc_pseudo_register_reggroup_
successfully validating the required registers. */

void tdesc_use_registers (struct gdbarch *gdbarch,
+ const struct target_desc *target_desc,
struct tdesc_arch_data *early_data);

/* Allocate initial data for validation of a target description during
@@ -93,6 +98,12 @@ int tdesc_numbered_register (const struc
struct tdesc_arch_data *data,
int regno, const char *name);

+/* Search FEATURE for a register named NAME, and return its size in
+ bits. The register must exist. */
+
+int tdesc_register_size (const struct tdesc_feature *feature,
+ const char *name);
+
/* Search FEATURE for a register with any of the names from NAMES
(NULL-terminated). Record REGNO and the register in DATA; when
tdesc_use_registers is called, REGNO will be assigned to the
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.437
diff -u -p -r1.437 gdb.texinfo
--- gdb/doc/gdb.texinfo 15 Oct 2007 19:19:17 -0000 1.437
+++ gdb/doc/gdb.texinfo 15 Oct 2007 19:28:58 -0000
@@ -26102,12 +26102,14 @@ types. The currently supported types ar
@itemx int16
@itemx int32
@itemx int64
+@itemx int128
Signed integer types holding the specified number of bits.

@item uint8
@itemx uint16
@itemx uint32
@itemx uint64
+@itemx uint128
Unsigned integer types holding the specified number of bits.

@item code_ptr
@@ -26226,6 +26228,29 @@ This feature is optional. If present, i
@samp{fpiaddr}.
@end table

+@subsection PowerPC Features
+@cindex target descriptions, PowerPC features
+
+The @samp{org.gnu.gdb.power.core} feature is required for PowerPC
+targets. It should contain registers @samp{r0} through @samp{r31},
+@samp{pc}, @samp{msr}, @samp{cr}, @samp{lr}, @samp{ctr}, and
+@samp{xer}. They may be 32-bit or 64-bit depending on the target.
+
+The @samp{org.gnu.gdb.power.fpu} feature is optional. It should
+contain registers @samp{f0} through @samp{f31} and @samp{fpscr}.
+
+The @samp{org.gnu.gdb.power.altivec} feature is optional. It should
+contain registers @samp{vr0} through @samp{vr31}, @samp{vscr},
+and @samp{vrsave}.
+
+The @samp{org.gnu.gdb.power.spe} feature is optional. It should
+contain registers @samp{ev0h} through @samp{ev31h}, @samp{acc}, and
+@samp{spefscr}. SPE targets should provide 32-bit registers in
+@samp{org.gnu.gdb.power.core} and provide the upper halves in
+@samp{ev0h} through @samp{ev31h}. @value{GDBN} will combine
+these to present registers @samp{ev0} through @samp{ev31} to the
+user.
+
@include gpl.texi

@raisesections
Index: gdb/testsuite/gdb.xml/tdesc-regs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.xml/tdesc-regs.exp,v
retrieving revision 1.3
diff -u -p -r1.3 tdesc-regs.exp
--- gdb/testsuite/gdb.xml/tdesc-regs.exp 23 Aug 2007 18:14:19 -0000 1.3
+++ gdb/testsuite/gdb.xml/tdesc-regs.exp 15 Oct 2007 19:28:59 -0000
@@ -24,6 +24,7 @@ gdb_start
# architecture, or the description will be rejected.

set core-regs ""
+set regdir ""
switch -glob -- [istarget] {
"*arm-*-*" {
set core-regs {arm-core.xml}
@@ -34,6 +35,10 @@ switch -glob -- [istarget] {
"mips*-*-*" {
set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml}
}
+ "powerpc*-*-*" {
+ set regdir "rs6000/"
+ set core-regs {power-core.xml}
+ }
}

# If no core registers were specified, assume this target does not
@@ -60,7 +65,7 @@ gdb_test "set tdesc file $srcdir/$subdir
# will be found by <xi:include>.
foreach src ${core-regs} {
file delete "$src"
- file copy "$srcdir/../features/$src" "$src"
+ file copy "$srcdir/../features/$regdir$src" "$src"
}

# Similarly, we need to copy files under test into the objdir.
Index: include/gdb/sim-ppc.h
===================================================================
RCS file: /cvs/src/src/include/gdb/sim-ppc.h,v
retrieving revision 1.4
diff -u -p -r1.4 sim-ppc.h
--- include/gdb/sim-ppc.h 23 Aug 2007 18:17:33 -0000 1.4
+++ include/gdb/sim-ppc.h 15 Oct 2007 19:28:59 -0000
@@ -762,6 +762,10 @@ enum
};

+/* Return the register name for the supplied SPR number if any, or
+ NULL if none. */
+extern const char *sim_spr_register_name (int);
+
#ifdef __cplusplus
}
#endif
Index: sim/ppc/gdb-sim.c
===================================================================
RCS file: /cvs/src/src/sim/ppc/gdb-sim.c,v
retrieving revision 1.3
diff -u -p -r1.3 gdb-sim.c
--- sim/ppc/gdb-sim.c 24 Aug 2007 14:28:42 -0000 1.3
+++ sim/ppc/gdb-sim.c 15 Oct 2007 19:29:00 -0000
@@ -28,11 +28,10 @@
#include "gdb/remote-sim.h"
#include "gdb/sim-ppc.h"

-/* Return the name of the register whose number is REGNUM, or zero if
- REGNUM is an invalid register number. */
-
-static const char *
-regnum2spr (int spr)
+/* Return the register name for the supplied SPR if any, or NULL if
+ none. */
+const char *
+sim_spr_register_name (int spr)
{
if (spr_is_valid (spr))
return spr_name (spr);
@@ -40,6 +39,11 @@ regnum2spr (int spr)
return NULL;
}

+#define regnum2spr(SPR) sim_spr_register_name (SPR)
+
+/* Return the name of the register whose number is REGNUM, or zero if
+ REGNUM is an invalid register number. */
+
static const char *
regnum2name (int regnum)
{