From 7cc46491b1832408d1d5472e3f0c17c8a1d78ccb Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Mon, 15 Oct 2007 19:45:31 +0000 Subject: [PATCH] * 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. * 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. --- gdb/ChangeLog | 72 ++ gdb/Makefile.in | 21 +- gdb/NEWS | 2 + gdb/arm-tdep.c | 2 +- gdb/doc/ChangeLog | 6 + gdb/doc/gdb.texinfo | 25 + gdb/m68k-tdep.c | 2 +- gdb/mips-tdep.c | 2 +- gdb/ppc-tdep.h | 211 +----- gdb/rs6000-tdep.c | 1193 ++++++++++++---------------------- gdb/target-descriptions.c | 58 +- gdb/target-descriptions.h | 15 +- gdb/testsuite/ChangeLog | 6 +- gdb/testsuite/gdb.xml/tdesc-regs.exp | 7 +- include/gdb/ChangeLog | 4 + include/gdb/sim-ppc.h | 4 + sim/ppc/ChangeLog | 5 + sim/ppc/gdb-sim.c | 14 +- 18 files changed, 660 insertions(+), 989 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4a33f28..38a3993 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,77 @@ 2007-10-15 Daniel Jacobowitz + * 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 + * 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, diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 151d139..722d361 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) \ diff --git a/gdb/NEWS b/gdb/NEWS index d0adea7..81e1cfa 100644 --- 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, diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 9438038..82e5a6a 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -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, diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index f3ae004..8e58bcc 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,5 +1,11 @@ 2007-10-15 Daniel Jacobowitz + * gdb.texinfo (Predefined Target Types): Add int128 + and uint128. + (Standard Target Features): Add PowerPC features. + +2007-10-15 Daniel Jacobowitz + * gdb.texinfo (Maintenance Commands): Document "maint print c-tdesc". 2007-10-12 Ulrich Weigand diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index c42cc48..f6d7e9e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index 6095015..87e8c1d 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -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; } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 8d2cfa7..39a22e0 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -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. */ diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index 3c16973..76fcf9e 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -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 diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 0f51356..4b43bcf 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -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 *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 (); } diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c index 2f1b82e..bb5b8ab 100644 --- a/gdb/target-descriptions.c +++ b/gdb/target-descriptions.c @@ -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 diff --git a/gdb/target-descriptions.h b/gdb/target-descriptions.h index 0f94a0d..95fb942 100644 --- a/gdb/target-descriptions.h +++ b/gdb/target-descriptions.h @@ -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 diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 2317941..db68a56 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,4 +1,8 @@ -2007/10/15 Pierre Muller +2007-10-15 Daniel Jacobowitz + + * gdb.xml/tdesc-regs.exp: Add PowerPC support. + +2007-10-15 Pierre Muller * gdb.base/sigstep.c (main): Add checks for return values for setitimer call. diff --git a/gdb/testsuite/gdb.xml/tdesc-regs.exp b/gdb/testsuite/gdb.xml/tdesc-regs.exp index 40f1915..bcde956 100644 --- a/gdb/testsuite/gdb.xml/tdesc-regs.exp +++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp @@ -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 . 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. diff --git a/include/gdb/ChangeLog b/include/gdb/ChangeLog index 67e5d97..ce08b7b 100644 --- a/include/gdb/ChangeLog +++ b/include/gdb/ChangeLog @@ -1,3 +1,7 @@ +2007-10-15 Daniel Jacobowitz + + * sim-ppc.h (sim_spr_register_name): New prototype. + 2007-10-11 Jesper Nilsson * callback.h (cb_is_stdin, cb_is_stdout, cb_is_stderr): Add prototypes. diff --git a/include/gdb/sim-ppc.h b/include/gdb/sim-ppc.h index 36ce927..3134323 100644 --- a/include/gdb/sim-ppc.h +++ b/include/gdb/sim-ppc.h @@ -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 diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index a7efe94..c8b4a5a 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,8 @@ +2007-10-15 Daniel Jacobowitz + + * gdb-sim.c (regnum2spr): Rename to... + (sim_spr_register_name): ... this. Make global. + 2007-09-04 Jerome Guitton * sim/ppc/emul_bugapi.c (emul_bugapi_create): quote the file diff --git a/sim/ppc/gdb-sim.c b/sim/ppc/gdb-sim.c index 5431a66..a8eaa08 100644 --- a/sim/ppc/gdb-sim.c +++ b/sim/ppc/gdb-sim.c @@ -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) { -- 2.7.4