OSDN Git Service

* NEWS: Document target described register support for PowerPC.
authorDaniel Jacobowitz <dan@debian.org>
Mon, 15 Oct 2007 19:45:31 +0000 (19:45 +0000)
committerDaniel Jacobowitz <dan@debian.org>
Mon, 15 Oct 2007 19:45:31 +0000 (19:45 +0000)
* 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.

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

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

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

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

18 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/NEWS
gdb/arm-tdep.c
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/m68k-tdep.c
gdb/mips-tdep.c
gdb/ppc-tdep.h
gdb/rs6000-tdep.c
gdb/target-descriptions.c
gdb/target-descriptions.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.xml/tdesc-regs.exp
include/gdb/ChangeLog
include/gdb/sim-ppc.h
sim/ppc/ChangeLog
sim/ppc/gdb-sim.c

index 4a33f28..38a3993 100644 (file)
@@ -1,5 +1,77 @@
 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>
+
        * features/rs6000/powerpc-32.c, features/rs6000/powerpc-403.c,
        features/rs6000/powerpc-403gc.c, features/rs6000/powerpc-505.c,
        features/rs6000/powerpc-601.c, features/rs6000/powerpc-602.c,
index 151d139..722d361 100644 (file)
@@ -888,6 +888,20 @@ features_headers = $(defs_h) $(gdbtypes_h) $(target_descriptions_h)
 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) $(frame_h) $(inferior_h) $(symtab_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 d0adea7..81e1cfa 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -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 9438038..82e5a6a 100644 (file)
@@ -3074,7 +3074,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   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 f3ae004..8e58bcc 100644 (file)
@@ -1,5 +1,11 @@
 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.texinfo (Maintenance Commands): Document "maint print c-tdesc".
 
 2007-10-12  Ulrich Weigand  <uweigand@de.ibm.com>
index c42cc48..f6d7e9e 100644 (file)
@@ -26102,12 +26102,14 @@ types.  The currently supported types are:
 @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, it should contain registers
 @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 6095015..87e8c1d 100644 (file)
@@ -1257,7 +1257,7 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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 8d2cfa7..39a22e0 100644 (file)
@@ -5649,7 +5649,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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 3c16973..76fcf9e 100644 (file)
@@ -139,7 +139,6 @@ extern void ppc_collect_fpregset (const struct regset *regset,
 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 0f51356..4b43bcf 100644 (file)
@@ -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 */
 
 #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 *arch)
   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 *arch)
   /* 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 *arch)
     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 gdbarch *gdbarch)
   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 wordsize)
   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;
+  /* 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);
 
-  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;
-
-  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 gdbarch *gdbarch, int regnum,
 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_info *frame,
                           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_info *frame,
                           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 gdbarch *gdbarch, struct regcache *regcache,
                     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 (struct gdbarch *gdbarch,
 
 /* 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 info, struct gdbarch_list *arches)
 {
   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 info, struct gdbarch_list *arches)
       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 info, struct gdbarch_list *arches)
        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, struct gdbarch_list *arches)
       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 info, struct gdbarch_list *arches)
        }
     }
 
+  /* 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");
+
+         if (!valid_p)
+           {
+             tdesc_data_cleanup (tdesc_data);
+             return NULL;
+           }
+         have_fpu = 1;
+       }
+      else
+       have_fpu = 0;
+
+      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);
 
-  /* Initialize the number of real and pseudo registers in each variant.  */
-  init_variants ();
-
-  /* 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);
+  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 info, struct gdbarch_list *arches)
   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 info, struct gdbarch_list *arches)
   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 info, struct gdbarch_list *arches)
       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 2f1b82e..bb5b8ab 100644 (file)
@@ -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 tdesc_feature *feature,
        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 whose name is in NAMES.  */
+/* 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 and assign
+   REGNO to it.  */
 
 int
 tdesc_numbered_register_choices (const struct tdesc_feature *feature,
@@ -460,6 +475,19 @@ tdesc_numbered_register_choices (const struct tdesc_feature *feature,
   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 0f94a0d..95fb942 100644 (file)
@@ -61,8 +61,12 @@ void set_tdesc_pseudo_register_reggroup_p
   (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_p
    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 struct tdesc_feature *feature,
                             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 2317941..db68a56 100644 (file)
@@ -1,4 +1,8 @@
-2007/10/15  Pierre Muller  <muller@ics.u-strasbg.fr>
+2007-10-15  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.xml/tdesc-regs.exp: Add PowerPC support.
+
+2007-10-15  Pierre Muller  <muller@ics.u-strasbg.fr>
 
        * gdb.base/sigstep.c (main): Add checks for
        return values for setitimer call.
index 40f1915..bcde956 100644 (file)
@@ -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/single-reg.xml" \
 # 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 67e5d97..ce08b7b 100644 (file)
@@ -1,3 +1,7 @@
+2007-10-15  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sim-ppc.h (sim_spr_register_name): New prototype.
+
 2007-10-11  Jesper Nilsson  <jesper.nilsson@axis.com>
 
        * callback.h (cb_is_stdin, cb_is_stdout, cb_is_stderr): Add prototypes.
index 36ce927..3134323 100644 (file)
@@ -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 a7efe94..c8b4a5a 100644 (file)
@@ -1,3 +1,8 @@
+2007-10-15  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb-sim.c (regnum2spr): Rename to...
+       (sim_spr_register_name): ... this.  Make global.
+
 2007-09-04  Jerome Guitton  <guitton@adacore.com>
 
        * sim/ppc/emul_bugapi.c (emul_bugapi_create): quote the file
index 5431a66..a8eaa08 100644 (file)
 #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)
 {