[rfc] Use target descriptions for PowerPC

Daniel Jacobowitz
2007-10-05T16:38:23Z

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.

The PowerPC port already supported a couple of different register
sets, including the original rs6000 / POWER architecture, the user
level registers for 32-bit and 64-bit PowerPC, the supervisor
registers for about a dozen PowerPC variants, and the e500 SPE
registers. The BFD architecture was used to select the correct
variant. The supervisor register sets could only be selected
manually, since ELF files do not mark the intended CPU. I don't know
how useful those are, but I didn't want to deprecate and remove
a potentially useful feature. So here, instead, is an approach
which removes most of the extra code to support those register
sets and replaces them with now-standard descriptions.

This patch is a net decrease of about 400 lines of code. That's
a biased characterization, since the new data files aren't included;
they're much bigger than the deleted macro approach, but also
easier to work with and extend. I preserved the remote target
register layout and numbering for all the existing descriptions.

And with this reorganization we gain support for arbitrary new
registers. I'll use this in a followup patch to add AltiVec and
SPE support to gdbserver, and to improve native GDB support for
SPE.

I've regression tested this patch on powerpc64-linux native, and by
hand on powerpc-linux native (with SPE), powerpc-linux native (with
AltiVec), gdbserver (with SPE), gdbserver (with AltiVec), and
powerpc-eabi (psim). If anyone has the opportunity, testing
on a non-Linux/EABI target would be helpful. You'll need the
generated files which I will post in a moment.

I'd like to check this in next week (HEAD only, of course).

--
Daniel Jacobowitz
CodeSourcery

2007-10-05 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-05 Daniel Jacobowitz <dan@codesourcery.com>

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

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

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

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

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

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

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

---
gdb/Makefile.in | 21
gdb/NEWS | 2
gdb/arm-tdep.c | 2
gdb/doc/gdb.texinfo | 25
gdb/m68k-tdep.c | 2
gdb/mips-tdep.c | 2
gdb/ppc-tdep.h | 211 ------
gdb/rs6000-tdep.c | 1186 ++++++++++++-----------------------
gdb/target-descriptions.c | 58 +
gdb/target-descriptions.h | 15
gdb/testsuite/gdb.xml/tdesc-regs.exp | 7
include/gdb/sim-ppc.h | 4
sim/ppc/gdb-sim.c | 14
13 files changed, 561 insertions(+), 988 deletions(-)

Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2007-10-05 11:19:31.000000000 -0400
+++ src/gdb/doc/gdb.texinfo 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/ppc-tdep.h
===================================================================
--- src.orig/gdb/ppc-tdep.h 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/ppc-tdep.h 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/rs6000-tdep.c
===================================================================
--- src.orig/gdb/rs6000-tdep.c 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/rs6000-tdep.c 2007-10-05 11:59:19.000000000 -0400
@@ -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 (current_gdbarch, 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));
@@ -2170,46 +2201,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. */

@@ -2219,109 +2210,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 (current_gdbarch, regnum) == NULL
- || *gdbarch_register_name (current_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 (current_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
@@ -2330,11 +2283,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
@@ -2343,10 +2298,8 @@ rs6000_register_to_value (struct frame_i
struct type *type,
gdb_byte *to)
{
- const struct reg *reg = gdbarch_tdep (current_gdbarch)->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);
@@ -2359,10 +2312,8 @@ rs6000_value_to_register (struct frame_i
struct type *type,
const gdb_byte *from)
{
- const struct reg *reg = gdbarch_tdep (current_gdbarch)->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);
@@ -2460,28 +2411,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)
@@ -2668,370 +2597,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
@@ -3048,151 +2613,65 @@ 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},
+ /* FIXME */
{"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. */

@@ -3480,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;
@@ -3513,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)
@@ -3522,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;
@@ -3555,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
@@ -3578,47 +3039,254 @@ 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. */
+ 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)
@@ -3634,66 +3302,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);
@@ -3780,17 +3404,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:
@@ -3808,7 +3421,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;
}
@@ -3833,4 +3457,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: src/gdb/testsuite/gdb.xml/tdesc-regs.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.xml/tdesc-regs.exp 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/testsuite/gdb.xml/tdesc-regs.exp 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/target-descriptions.c
===================================================================
--- src.orig/gdb/target-descriptions.c 2007-10-05 11:19:31.000000000 -0400
+++ src/gdb/target-descriptions.c 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/target-descriptions.h
===================================================================
--- src.orig/gdb/target-descriptions.h 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/target-descriptions.h 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/NEWS 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2007-10-05 11:19:31.000000000 -0400
+++ src/gdb/Makefile.in 2007-10-05 11:45:48.000000000 -0400
@@ -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
@@ -2542,7 +2556,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: src/gdb/arm-tdep.c
===================================================================
--- src.orig/gdb/arm-tdep.c 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/arm-tdep.c 2007-10-05 11:37:28.000000000 -0400
@@ -3045,7 +3045,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: src/gdb/m68k-tdep.c
===================================================================
--- src.orig/gdb/m68k-tdep.c 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/m68k-tdep.c 2007-10-05 11:37:28.000000000 -0400
@@ -1255,7 +1255,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: src/gdb/mips-tdep.c
===================================================================
--- src.orig/gdb/mips-tdep.c 2007-10-05 11:19:29.000000000 -0400
+++ src/gdb/mips-tdep.c 2007-10-05 11:37:28.000000000 -0400
@@ -5656,7 +5656,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: src/include/gdb/sim-ppc.h
===================================================================
--- src.orig/include/gdb/sim-ppc.h 2007-10-05 11:19:29.000000000 -0400
+++ src/include/gdb/sim-ppc.h 2007-10-05 11:37:28.000000000 -0400
@@ -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: src/sim/ppc/gdb-sim.c
===================================================================
--- src.orig/sim/ppc/gdb-sim.c 2007-10-05 11:19:29.000000000 -0400
+++ src/sim/ppc/gdb-sim.c 2007-10-05 11:37:28.000000000 -0400
@@ -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)
{