Andrew Stubbs wrote:
Hi all,
The SH port does not currently define any register groups. Instead, it
just relies on the default in reggroup.c. This is not quite adequate
as it is not always clear from the type where a register should
naturally sit. In particular the 'fv' vector registers are classified
as general, not float or vector.
The attached patch adds a function to do the register classification.
It does not know about all the registers of sh2a or any of the dsp
variants (because I don't), but should not make the situation any
worse for those.
Is this patch OK?
I attach an updated patch with the Makefile properly adjusted.
Andrew Stubbs
------------------------------------------------------------------------
2005-11-07 Andrew Stubbs <andrew.stubbs@st.com>
* sh-tdep.c: Include reggroups.h.
(sh_register_reggroup_p): New function.
(sh_gdbarch_init): Add call to set_gdbarch_register_reggroup_p.
* Makefile.in (sh-tdep.o): Add dependency on reggroups.h.
Index: src/gdb/sh-tdep.c
===================================================================
--- src.orig/gdb/sh-tdep.c 2005-11-07 11:50:24.000000000 +0000
+++ src/gdb/sh-tdep.c 2005-11-07 14:57:31.000000000 +0000
@@ -44,6 +44,7 @@
#include "regcache.h"
#include "doublest.h"
#include "osabi.h"
+#include "reggroups.h"
#include "sh-tdep.h"
@@ -1812,6 +1813,51 @@ sh_default_register_type (struct gdbarch
return builtin_type_int;
}
+/* Is a register in a reggroup?
+ The default code in reggroup.c doesn't identify system registers, some
+ float registers or any of the vector registers.
+ TODO: sh2a and dsp registers. */
+int
+sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+ struct reggroup *reggroup)
+{
+ if (REGISTER_NAME (regnum) == NULL
+ || *REGISTER_NAME (regnum) == '\0')
+ return 0;
+ if (reggroup == all_reggroup)
+ return 1;
+ if (reggroup == save_reggroup || reggroup == restore_reggroup)
+ return regnum < NUM_REGS; /* i.e. not pseudo regs */
+
+ if (FP0_REGNUM != -1
+ && ((regnum >= FP0_REGNUM && regnum <= FP_LAST_REGNUM)
+ || (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
+ || (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM)
+ || (regnum == FPUL_REGNUM)
+ || (regnum == FPSCR_REGNUM)))
+ {
+ if (reggroup == float_reggroup)
+ return 1;
+ if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM
+ && reggroup == vector_reggroup)
+ return 1;
+ }
+ else if (reggroup == system_reggroup
+ && (regnum == PC_REGNUM
+ || regnum == PR_REGNUM
+ || regnum == GBR_REGNUM
+ || regnum == VBR_REGNUM
+ || regnum == SR_REGNUM
+ || regnum == FPSCR_REGNUM
+ || regnum == SSR_REGNUM
+ || regnum == SPC_REGNUM))
+ return 1;
+ else if (reggroup == general_reggroup)
+ return 1;
+
+ return 0;
+}
+
/* On the sh4, the DRi pseudo registers are problematic if the target
is little endian. When the user writes one of those registers, for
instance with 'ser var $dr0=1', we want the double to be stored
@@ -2549,6 +2595,7 @@ sh_gdbarch_init (struct gdbarch_info inf
set_gdbarch_num_pseudo_regs (gdbarch, 0);
set_gdbarch_register_type (gdbarch, sh_default_register_type);
+ set_gdbarch_register_reggroup_p (gdbarch, sh_register_reggroup_p);
set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2005-11-07 14:50:50.000000000 +0000
+++ src/gdb/Makefile.in 2005-11-07 14:58:39.000000000 +0000
@@ -2535,7 +2535,7 @@ sh-tdep.o: sh-tdep.c $(defs_h) $(frame_h
$(value_h) $(dis_asm_h) $(inferior_h) $(gdb_string_h) \
$(gdb_assert_h) $(arch_utils_h) $(floatformat_h) $(regcache_h) \
$(doublest_h) $(osabi_h) $(sh_tdep_h) $(elf_bfd_h) $(solib_svr4_h) \
- $(elf_sh_h) $(gdb_sim_sh_h)
+ $(elf_sh_h) $(gdb_sim_sh_h) $(reggroups_h)
solib-aix5.o: solib-aix5.c $(defs_h) $(gdb_string_h) $(elf_external_h) \
$(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) $(gdbcore_h) \
$(command_h) $(target_h) $(frame_h) $(gdb_regex_h) $(inferior_h) \