Message ID | e6065f2e-f76d-0190-dc34-d04da1a33e84@oracle.com |
---|---|
State | New |
Headers | show |
On 17-01-06 16:12:09, Ivo Raisr wrote: > > I think I see the line now as well. Please find patch #1 together > with a ChangeLog entry. > The patch was successfully built and tested on Solaris sparc. > After you find it ok, I will prepare patch #2. > I. > ChangeLog entry: > 2017-01-06 Ivo Raisr <ivo.raisr@oracle.com> > > Split real and pseudo registers in preparation for registers provided > by a target. Registers provided by target description can have more real > registers and pseudo registers need to be positioned after them. We don't document "changes" in this way. If you think it is important to mention them, put them in the commit log. > @@ -57,6 +63,12 @@ struct gdbarch_tdep > int pc_regnum; > int npc_regnum; > > + /* Register names specific for architecture (sparc32 vs. sparc64) */ > + const char **fpu_register_names; > + size_t fpu_registers_num; > + const char **cp0_register_names; > + size_t cp0_registers_num; > + These four fields are added, but not used at all, so could you move them to patch #2? -- Yao (齐尧)
On 17-01-09 22:18:22, Ivo Raisr wrote: > ChangeLog entry: > 2017-01-09 Ivo Raisr <ivo.raisr@oracle.com> > > Split real and pseudo registers. > * sparc-tdep.h: Separate real and pseudo registers. We describe the changes in the ChangeLog, so the change can be described like this: * sparc-tdep.h (SPARC_CORE_REGISTERS): New macro. (sparc32_pseudo_regnum): New enum. > * sparc64-tdep.h: Separate real and pseudo registers. * sparc64-tdep.h (sparc64_pseudo_regnum): New enum. > * sparc-tdep.c (sparc32_pseudo_register_name): New function returning > pseudo register names on sparc 32-bit. "New function" should be enough to describe the change. > (sparc32_register_name): Use sparc32_pseudo_register_name(). > (sparc32_pseudo_register_type): New function returning pseudo register > types on sparc 32-bit. > (sparc32_register_type): Use sparc32_pseudo_register_type(). > (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Pseudo > registers may have different numbers. > * sparc64-tdep.c (sparc64_pseudo_register_name): New function returning > pseudo register names on sparc 64-bit. > (sparc64_register_name): Use sparc64_pseudo_register_name(). > (sparc64_pseudo_register_type): New function returning pseudo register > types on sparc 64-bit. > (sparc64_register_type): Use sparc64_pseudo_register_type(). > (sparc64_pseudo_register_read, sparc64_pseudo_register_write): Pseudo > registers may have different numbers. > (sparc64_store_floating_fields, sparc64_extract_floating_fields, > sparc64_store_arguments): Pseudo registers may have different numbers; > deal with it. > --- a/gdb/sparc-tdep.c 2016-02-09 19:19:39.000000000 +0000 > +++ gdb-7.11/gdb/sparc-tdep.c 2017-01-09 13:11:30.421265402 +0000 > @@ -295,20 +295,23 @@ sparc_structure_or_union_p (const struct > } > > /* Register information. */ > +#define SPARC32_FPU_REGISTERS \ > + "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" > +#define SPARC32_CP0_REGISTERS \ > + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" > + > +static const char *sparc_core_register_names[] = { SPARC_CORE_REGISTERS }; > +static const char *sparc32_fpu_register_names[] = { SPARC32_FPU_REGISTERS }; > +static const char *sparc32_cp0_register_names[] = { SPARC32_CP0_REGISTERS }; They are not used in this patch at all. Should be moved to patch #2. > > static const char *sparc32_register_names[] = > { > - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", > - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", > - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", > - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", > - > - "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", > - > - "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" > + SPARC_CORE_REGISTERS, > + SPARC32_FPU_REGISTERS, > + SPARC32_CP0_REGISTERS > }; > > /* Total number of registers. */ > @@ -327,17 +330,26 @@ static const char *sparc32_pseudo_regist > #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) > > /* Return the name of register REGNUM. */ > +static const char * > +sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) Don't insert the new function between sparc32_register_name and its comments. We also need comments to sparc32_pseudo_register_name. /* Return the name of pseudo register REGNUM. */ static const char * sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) .... /* Return the name of register REGNUM. */ static const char * sparc32_register_name (struct gdbarch *gdbarch, int regnum) > /* Return the GDB type object for the "standard" data type of data in > register REGNUM. */ > +static struct type * > +sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) Likewise, don't insert sparc32_pseudo_register_type between sparc32_register_type and its type. > --- a/gdb/sparc64-tdep.c 2016-02-09 19:19:39.000000000 +0000 > +++ gdb-7.11/gdb/sparc64-tdep.c 2017-01-09 13:11:51.858903807 +0000 > @@ -226,28 +226,29 @@ sparc64_fprs_type (struct gdbarch *gdbar > > > /* Register information. */ > +#define SPARC64_FPU_REGISTERS \ > + "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", \ > + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ > + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62" > +#define SPARC64_CP0_REGISTERS \ > + "pc", "npc", \ > + /* FIXME: Give "state" a name until we start using register groups. */ \ > + "state", \ > + "fsr", \ > + "fprs", \ > + "y" > + > +static const char *sparc64_fpu_register_names[] = { SPARC64_FPU_REGISTERS }; > +static const char *sparc64_cp0_register_names[] = { SPARC64_CP0_REGISTERS }; They are not used, should be moved to patch #2. > @@ -273,28 +274,57 @@ static const char *sparc64_pseudo_regist > #define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names) > > /* Return the name of register REGNUM. */ > +static const char * > +sparc64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) sparc64_pseudo_register_name is added between sparc64_register_name and its comments. > +{ > + regnum -= gdbarch_num_regs (gdbarch); > + > + if (regnum < SPARC64_NUM_PSEUDO_REGS) > + return sparc64_pseudo_register_names[regnum]; > + > + internal_error (__FILE__, __LINE__, > + _("sparc64_pseudo_register_name: bad register number %d"), > + regnum); > +} > > static const char * > sparc64_register_name (struct gdbarch *gdbarch, int regnum) > { > - if (regnum >= 0 && regnum < SPARC64_NUM_REGS) > + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) > return sparc64_register_names[regnum]; > > - if (regnum >= SPARC64_NUM_REGS > - && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) > - return sparc64_pseudo_register_names[regnum - SPARC64_NUM_REGS]; > - > - return NULL; > + return sparc64_pseudo_register_name (gdbarch, regnum); > } > > /* Return the GDB type object for the "standard" data type of data in > register REGNUM. */ > +static struct type * > +sparc64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) Likewise. > +{ > + regnum -= gdbarch_num_regs (gdbarch); > + > + if (regnum == SPARC64_CWP_REGNUM) > + return builtin_type (gdbarch)->builtin_int64; > + if (regnum == SPARC64_PSTATE_REGNUM) > + return sparc64_pstate_type (gdbarch); > + if (regnum == SPARC64_ASI_REGNUM) > + return builtin_type (gdbarch)->builtin_int64; > + if (regnum == SPARC64_CCR_REGNUM) > + return builtin_type (gdbarch)->builtin_int64; > + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) > + return builtin_type (gdbarch)->builtin_double; > + if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) > + return builtin_type (gdbarch)->builtin_long_double; > + > + internal_error (__FILE__, __LINE__, > + _("sparc64_pseudo_register_type: bad register number %d"), > + regnum); > +} > -- Yao (齐尧)
On 17-01-11 14:14:10, Ivo Raisr wrote: Patch is good to me, some nits below. Fix these nits, and then you can push it in! > ChangeLog entry: > 2017-01-11 Ivo Raisr <ivo.raisr@oracle.com> > > Split real and pseudo registers. > * sparc-tdep.h (SPARC_CORE_REGISTERS): New macro. > (sparc32_pseudo_regnum): New enum. > * sparc64-tdep.h (sparc64_pseudo_regnum): New enum. > * sparc-tdep.c (SPARC32_FPU_REGISTERS): New macro. > (SPARC32_CP0_REGISTERS): New macro. > (sparc32_pseudo_register_name): New function. > (sparc32_register_name): Use sparc32_pseudo_register_name(). (sparc32_register_name): Use sparc32_pseudo_register_name. > (sparc32_pseudo_register_type): New function. > (sparc32_register_type): Use sparc32_pseudo_register_type(). Likewise. > (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Pseudo > registers may have different numbers. (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Handle pseudo register numbers. > * sparc64-tdep.c SPARC64_FPU_REGISTERS): New macro. > (SPARC64_CP0_REGISTERS): New macro. > (sparc64_pseudo_register_name): New function. > (sparc64_register_name): Use sparc64_pseudo_register_name(). > (sparc64_pseudo_register_type): New function. > (sparc64_register_type): Use sparc64_pseudo_register_type(). > (sparc64_pseudo_register_read, sparc64_pseudo_register_write): Pseudo > registers may have different numbers. > (sparc64_store_floating_fields, sparc64_extract_floating_fields, > sparc64_store_arguments): Pseudo registers may have different numbers; > deal with it. > --- a/gdb/sparc-tdep.h 2016-02-09 19:19:39.000000000 +0000 > +++ gdb-7.11/gdb/sparc-tdep.h 2017-01-09 13:26:11.749929515 +0000 > @@ -20,6 +20,12 @@ > #ifndef SPARC_TDEP_H > #define SPARC_TDEP_H 1 > > +#define SPARC_CORE_REGISTERS \ > + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ > + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \ > + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ > + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" > + > struct frame_info; > struct gdbarch; > struct regcache; > @@ -85,7 +91,7 @@ struct gdbarch_tdep > > enum sparc_regnum > { > - SPARC_G0_REGNUM, /* %g0 */ > + SPARC_G0_REGNUM = 0, /* %g0 */ > SPARC_G1_REGNUM, > SPARC_G2_REGNUM, > SPARC_G3_REGNUM, > @@ -140,9 +146,12 @@ enum sparc32_regnum > SPARC32_NPC_REGNUM, /* %npc */ > SPARC32_FSR_REGNUM, /* %fsr */ > SPARC32_CSR_REGNUM, /* %csr */ > +}; > > - /* Pseudo registers. */ > - SPARC32_D0_REGNUM, /* %d0 */ > +/* Pseudo registers. */ > +enum sparc32_pseudo_regnum > +{ > + SPARC32_D0_REGNUM = 0, /* %d0 */ > SPARC32_D30_REGNUM /* %d30 */ > = SPARC32_D0_REGNUM + 15 > }; > --- a/gdb/sparc-tdep.c 2016-02-09 19:19:39.000000000 +0000 > +++ gdb-7.11/gdb/sparc-tdep.c 2017-01-11 04:23:28.543904210 +0000 > @@ -295,20 +295,19 @@ sparc_structure_or_union_p (const struct > } > > /* Register information. */ > +#define SPARC32_FPU_REGISTERS \ > + "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" > +#define SPARC32_CP0_REGISTERS \ > + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" > > static const char *sparc32_register_names[] = > { > - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", > - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", > - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", > - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", > - > - "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", > - > - "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" > + SPARC_CORE_REGISTERS, > + SPARC32_FPU_REGISTERS, > + SPARC32_CP0_REGISTERS > }; > > /* Total number of registers. */ > @@ -326,18 +325,28 @@ static const char *sparc32_pseudo_regist > /* Total number of pseudo registers. */ > #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) > > -/* Return the name of register REGNUM. */ > +/* Return the name of pseudo register REGNUM. */ Add a blank line between function and its comment. > +static const char * > +sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) > +{ > + regnum -= gdbarch_num_regs (gdbarch); > + > + if (regnum < SPARC32_NUM_PSEUDO_REGS) > + return sparc32_pseudo_register_names[regnum]; > > + internal_error (__FILE__, __LINE__, > + _("sparc32_pseudo_register_name: bad register number %d"), > + regnum); > +} > + > +/* Return the name of register REGNUM. */ Likewise. > static const char * > sparc32_register_name (struct gdbarch *gdbarch, int regnum) > { > - if (regnum >= 0 && regnum < SPARC32_NUM_REGS) > + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) > return sparc32_register_names[regnum]; > > - if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) > - return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; > - > - return NULL; > + return sparc32_pseudo_register_name (gdbarch, regnum); > } > > /* Construct types for ISA-specific registers. */ > @@ -398,17 +407,28 @@ sparc_fsr_type (struct gdbarch *gdbarch) > } > > /* Return the GDB type object for the "standard" data type of data in > - register REGNUM. */ > + pseudo register REGNUM. */ Likewise. > +static struct type * > +sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) > +{ > + regnum -= gdbarch_num_regs (gdbarch); > + > + if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) > + return builtin_type (gdbarch)->builtin_double; > + > + internal_error (__FILE__, __LINE__, > + _("sparc32_pseudo_register_type: bad register number %d"), > + regnum); > +} > > +/* Return the GDB type object for the "standard" data type of data in > + register REGNUM. */ Likewise. > static struct type * > sparc32_register_type (struct gdbarch *gdbarch, int regnum) > { > if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) > return builtin_type (gdbarch)->builtin_float; > > - if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) > - return builtin_type (gdbarch)->builtin_double; > - > if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) > return builtin_type (gdbarch)->builtin_data_ptr; > -- Yao (齐尧)
> On 17-01-11 14:14:10, Ivo Raisr wrote: > > Patch is good to me, some nits below. Fix these nits, and then you > can push it in! I fixed all the nits (see attached). Thank you for your review! However I assume I don't have write access to gdb's git repository [1] as the ssh authentication would surely ask for some credentials which I don't posses. I just pushed this patch in your behalf. Salud!
(I know I'm quite behind this thread.) On 01/06/2017 03:12 PM, Ivo Raisr wrote: > > ChangeLog entry: > 2017-01-06 Ivo Raisr <ivo.raisr@oracle.com> > > Split real and pseudo registers in preparation for registers provided > by a target. Registers provided by target description can have more real > registers and pseudo registers need to be positioned after them. I don't quite understand this rationale, and I'm wondering if there's a misunderstanding of register numbering somewhere (maybe mine!). What exactly would go wrong if you just added the new registers between the existing raw and pseudo registers? Other ports do that routinely. Thanks, Pedro Alves
On 25.1.2017 16:46, Pedro Alves wrote: > (I know I'm quite behind this thread.) > > On 01/06/2017 03:12 PM, Ivo Raisr wrote: >> >> ChangeLog entry: >> 2017-01-06 Ivo Raisr <ivo.raisr@oracle.com> >> >> Split real and pseudo registers in preparation for registers provided >> by a target. Registers provided by target description can have more real >> registers and pseudo registers need to be positioned after them. > > I don't quite understand this rationale, and I'm wondering if there's > a misunderstanding of register numbering somewhere (maybe mine!). > > What exactly would go wrong if you just added the new registers > between the existing raw and pseudo registers? Other ports do > that routinely. Good question. The rationale is target provided registers. Consider a typical Valgrind use case where target (gdbserver stub implemented inside Valgrind) supplies 3 times more raw registers than the architecture normally supports. One set mimics the "normal" registers, the other two sets are shadow copies used internally by Memcheck tool to keep track of defined/undefined bits and their origins. So when gdb'ing ordinary process, you have: - raw registers (one set) - pseudo registers However when gdb'ing Valgrind'ed process over gdb remote protocol with --vgdb-shadow-registers=yes, target provides: - first set of raw registers (describes guest state) - second set of raw registers (describes the first shadow copy) - third set of raw registers (describes the second shadow copy) - pseudo registers (actually provided by gdb) So this means pseudo registers numbering must be flexible. Other targets (such as s390x, aarch64, amd64) do it in similar ways. Kind regards, I.
On 01/25/2017 04:05 PM, Ivo Raisr wrote: > > > On 25.1.2017 16:46, Pedro Alves wrote: >> (I know I'm quite behind this thread.) >> >> On 01/06/2017 03:12 PM, Ivo Raisr wrote: >>> >>> ChangeLog entry: >>> 2017-01-06 Ivo Raisr <ivo.raisr@oracle.com> >>> >>> Split real and pseudo registers in preparation for registers >>> provided >>> by a target. Registers provided by target description can have >>> more real >>> registers and pseudo registers need to be positioned after them. >> >> I don't quite understand this rationale, and I'm wondering if there's >> a misunderstanding of register numbering somewhere (maybe mine!). >> >> What exactly would go wrong if you just added the new registers >> between the existing raw and pseudo registers? Other ports do >> that routinely. > > Good question. > The rationale is target provided registers. > Consider a typical Valgrind use case where target (gdbserver stub > implemented inside Valgrind) supplies 3 times more raw registers than > the architecture normally supports. > One set mimics the "normal" registers, the other two sets are shadow > copies used internally by Memcheck tool to keep track of > defined/undefined bits and their origins. > > So when gdb'ing ordinary process, you have: > - raw registers (one set) > - pseudo registers > > However when gdb'ing Valgrind'ed process over gdb remote protocol > with --vgdb-shadow-registers=yes, target provides: > - first set of raw registers (describes guest state) > - second set of raw registers (describes the first shadow copy) > - third set of raw registers (describes the second shadow copy) > - pseudo registers (actually provided by gdb) > > So this means pseudo registers numbering must be flexible. > Other targets (such as s390x, aarch64, amd64) do it in similar ways. Ah, OK. I see what you're doing now. Thanks for clarifying! Thanks, Pedro Alves
On 25.1.2017 17:23, Pedro Alves wrote:
> Ah, OK. I see what you're doing now. Thanks for clarifying!
You are welcome.
Would you mind letting me know if the second patch for this series
is ok to commit? All the issues and nits reported by Yao have been fixed.
Thank you,
I.
On Wed, Jan 25, 2017 at 4:25 PM, Ivo Raisr <ivo.raisr@oracle.com> wrote: > > You are welcome. > Would you mind letting me know if the second patch for this series > is ok to commit? All the issues and nits reported by Yao have been fixed. > Thank you, I am reviewing it now. -- Yao (齐尧)
--- a/gdb/sparc-tdep.h 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc-tdep.h 2017-01-06 04:12:14.291269940 +0000 @@ -20,6 +20,12 @@ #ifndef SPARC_TDEP_H #define SPARC_TDEP_H 1 +#define SPARC_CORE_REGISTERS \ + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \ + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" + struct frame_info; struct gdbarch; struct regcache; @@ -57,6 +63,12 @@ struct gdbarch_tdep int pc_regnum; int npc_regnum; + /* Register names specific for architecture (sparc32 vs. sparc64) */ + const char **fpu_register_names; + size_t fpu_registers_num; + const char **cp0_register_names; + size_t cp0_registers_num; + /* Register sets. */ const struct regset *gregset; size_t sizeof_gregset; @@ -85,7 +97,7 @@ struct gdbarch_tdep enum sparc_regnum { - SPARC_G0_REGNUM, /* %g0 */ + SPARC_G0_REGNUM = 0, /* %g0 */ SPARC_G1_REGNUM, SPARC_G2_REGNUM, SPARC_G3_REGNUM, @@ -140,9 +152,12 @@ enum sparc32_regnum SPARC32_NPC_REGNUM, /* %npc */ SPARC32_FSR_REGNUM, /* %fsr */ SPARC32_CSR_REGNUM, /* %csr */ +}; - /* Pseudo registers. */ - SPARC32_D0_REGNUM, /* %d0 */ +/* Pseudo registers. */ +enum sparc32_pseudo_regnum +{ + SPARC32_D0_REGNUM = 0, /* %d0 */ SPARC32_D30_REGNUM /* %d30 */ = SPARC32_D0_REGNUM + 15 }; --- a/gdb/sparc-tdep.c 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc-tdep.c 2017-01-06 04:12:14.293179005 +0000 @@ -295,20 +295,23 @@ sparc_structure_or_union_p (const struct } /* Register information. */ +#define SPARC32_FPU_REGISTERS \ + "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" +#define SPARC32_CP0_REGISTERS \ + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" + +static const char *sparc_core_register_names[] = { SPARC_CORE_REGISTERS }; +static const char *sparc32_fpu_register_names[] = { SPARC32_FPU_REGISTERS }; +static const char *sparc32_cp0_register_names[] = { SPARC32_CP0_REGISTERS }; static const char *sparc32_register_names[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "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", - - "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" + SPARC_CORE_REGISTERS, + SPARC32_FPU_REGISTERS, + SPARC32_CP0_REGISTERS }; /* Total number of registers. */ @@ -327,17 +330,26 @@ static const char *sparc32_pseudo_regist #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) /* Return the name of register REGNUM. */ +static const char * +sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum < SPARC32_NUM_PSEUDO_REGS) + return sparc32_pseudo_register_names[regnum]; + + internal_error (__FILE__, __LINE__, + _("sparc32_pseudo_register_name: bad register number %d"), + regnum); +} static const char * sparc32_register_name (struct gdbarch *gdbarch, int regnum) { - if (regnum >= 0 && regnum < SPARC32_NUM_REGS) + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) return sparc32_register_names[regnum]; - if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) - return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; - - return NULL; + return sparc32_pseudo_register_name (gdbarch, regnum); } /* Construct types for ISA-specific registers. */ @@ -399,6 +411,18 @@ sparc_fsr_type (struct gdbarch *gdbarch) /* Return the GDB type object for the "standard" data type of data in register REGNUM. */ +static struct type * +sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) + return builtin_type (gdbarch)->builtin_double; + + internal_error (__FILE__, __LINE__, + _("sparc32_pseudo_register_type: bad register number %d"), + regnum); +} static struct type * sparc32_register_type (struct gdbarch *gdbarch, int regnum) @@ -406,9 +430,6 @@ sparc32_register_type (struct gdbarch *g if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) return builtin_type (gdbarch)->builtin_float; - if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) - return builtin_type (gdbarch)->builtin_double; - if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) return builtin_type (gdbarch)->builtin_data_ptr; @@ -421,6 +442,9 @@ sparc32_register_type (struct gdbarch *g if (regnum == SPARC32_FSR_REGNUM) return sparc_fsr_type (gdbarch); + if (regnum >= gdbarch_num_regs (gdbarch)) + return sparc32_pseudo_register_type (gdbarch, regnum); + return builtin_type (gdbarch)->builtin_int32; } @@ -431,6 +455,7 @@ sparc32_pseudo_register_read (struct gdb { enum register_status status; + regnum -= gdbarch_num_regs (gdbarch); gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); @@ -445,6 +470,7 @@ sparc32_pseudo_register_write (struct gd struct regcache *regcache, int regnum, const gdb_byte *buf) { + regnum -= gdbarch_num_regs (gdbarch); gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); @@ -1678,6 +1704,10 @@ sparc32_gdbarch_init (struct gdbarch_inf tdep->pc_regnum = SPARC32_PC_REGNUM; tdep->npc_regnum = SPARC32_NPC_REGNUM; tdep->step_trap = sparc_step_trap; + tdep->fpu_register_names = sparc32_fpu_register_names; + tdep->fpu_registers_num = ARRAY_SIZE (sparc32_fpu_register_names); + tdep->cp0_register_names = sparc32_cp0_register_names; + tdep->cp0_registers_num = ARRAY_SIZE (sparc32_cp0_register_names); set_gdbarch_long_double_bit (gdbarch, 128); set_gdbarch_long_double_format (gdbarch, floatformats_sparc_quad); --- a/gdb/sparc64-tdep.h 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc64-tdep.h 2017-01-06 04:12:14.294032452 +0000 @@ -56,9 +56,12 @@ enum sparc64_regnum SPARC64_FSR_REGNUM, /* %fsr */ SPARC64_FPRS_REGNUM, /* %fprs */ SPARC64_Y_REGNUM, /* %y */ +}; - /* Pseudo registers. */ - SPARC64_CWP_REGNUM, /* %cwp */ +/* Pseudo registers. */ +enum sparc64_pseudo_regnum +{ + SPARC64_CWP_REGNUM = 0, /* %cwp */ SPARC64_PSTATE_REGNUM, /* %pstate */ SPARC64_ASI_REGNUM, /* %asi */ SPARC64_CCR_REGNUM, /* %ccr */ --- a/gdb/sparc64-tdep.c 2016-02-09 19:19:39.000000000 +0000 +++ b/gdb/sparc64-tdep.c 2017-01-06 04:12:14.295659262 +0000 @@ -226,28 +226,29 @@ sparc64_fprs_type (struct gdbarch *gdbar /* Register information. */ +#define SPARC64_FPU_REGISTERS \ + "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", \ + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62" +#define SPARC64_CP0_REGISTERS \ + "pc", "npc", \ + /* FIXME: Give "state" a name until we start using register groups. */ \ + "state", \ + "fsr", \ + "fprs", \ + "y" + +static const char *sparc64_fpu_register_names[] = { SPARC64_FPU_REGISTERS }; +static const char *sparc64_cp0_register_names[] = { SPARC64_CP0_REGISTERS }; static const char *sparc64_register_names[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "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", - "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", - "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", - - "pc", "npc", - - /* FIXME: Give "state" a name until we start using register groups. */ - "state", - "fsr", - "fprs", - "y", + SPARC_CORE_REGISTERS, + SPARC64_FPU_REGISTERS, + SPARC64_CP0_REGISTERS }; /* Total number of registers. */ @@ -273,28 +274,57 @@ static const char *sparc64_pseudo_regist #define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names) /* Return the name of register REGNUM. */ +static const char * +sparc64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum < SPARC64_NUM_PSEUDO_REGS) + return sparc64_pseudo_register_names[regnum]; + + internal_error (__FILE__, __LINE__, + _("sparc64_pseudo_register_name: bad register number %d"), + regnum); +} static const char * sparc64_register_name (struct gdbarch *gdbarch, int regnum) { - if (regnum >= 0 && regnum < SPARC64_NUM_REGS) + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) return sparc64_register_names[regnum]; - if (regnum >= SPARC64_NUM_REGS - && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) - return sparc64_pseudo_register_names[regnum - SPARC64_NUM_REGS]; - - return NULL; + return sparc64_pseudo_register_name (gdbarch, regnum); } /* Return the GDB type object for the "standard" data type of data in register REGNUM. */ +static struct type * +sparc64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum == SPARC64_CWP_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum == SPARC64_PSTATE_REGNUM) + return sparc64_pstate_type (gdbarch); + if (regnum == SPARC64_ASI_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum == SPARC64_CCR_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) + return builtin_type (gdbarch)->builtin_double; + if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) + return builtin_type (gdbarch)->builtin_long_double; + + internal_error (__FILE__, __LINE__, + _("sparc64_pseudo_register_type: bad register number %d"), + regnum); +} static struct type * sparc64_register_type (struct gdbarch *gdbarch, int regnum) { /* Raw registers. */ - if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) return builtin_type (gdbarch)->builtin_data_ptr; if (regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM) @@ -319,19 +349,8 @@ sparc64_register_type (struct gdbarch *g return builtin_type (gdbarch)->builtin_int64; /* Pseudo registers. */ - - if (regnum == SPARC64_CWP_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum == SPARC64_PSTATE_REGNUM) - return sparc64_pstate_type (gdbarch); - if (regnum == SPARC64_ASI_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum == SPARC64_CCR_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) - return builtin_type (gdbarch)->builtin_double; - if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) - return builtin_type (gdbarch)->builtin_long_double; + if (regnum >= gdbarch_num_regs (gdbarch)) + return sparc64_pseudo_register_type (gdbarch, regnum); internal_error (__FILE__, __LINE__, _("invalid regnum")); } @@ -344,7 +363,7 @@ sparc64_pseudo_register_read (struct gdb enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum register_status status; - gdb_assert (regnum >= SPARC64_NUM_REGS); + regnum -= gdbarch_num_regs (gdbarch); if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) { @@ -421,7 +440,8 @@ sparc64_pseudo_register_write (struct gd int regnum, const gdb_byte *buf) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_assert (regnum >= SPARC64_NUM_REGS); + + regnum -= gdbarch_num_regs (gdbarch); if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) { @@ -638,6 +658,7 @@ static void sparc64_store_floating_fields (struct regcache *regcache, struct type *type, const gdb_byte *valbuf, int element, int bitpos) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); int len = TYPE_LENGTH (type); gdb_assert (element < 16); @@ -652,14 +673,15 @@ sparc64_store_floating_fields (struct re gdb_assert (bitpos == 0); gdb_assert ((element % 2) == 0); - regnum = SPARC64_Q0_REGNUM + element / 2; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + element / 2; regcache_cooked_write (regcache, regnum, valbuf); } else if (len == 8) { gdb_assert (bitpos == 0 || bitpos == 64); - regnum = SPARC64_D0_REGNUM + element + bitpos / 64; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element + bitpos / 64; regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8)); } else @@ -712,6 +734,8 @@ static void sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, gdb_byte *valbuf, int bitpos) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + if (sparc64_floating_p (type)) { int len = TYPE_LENGTH (type); @@ -721,14 +745,15 @@ sparc64_extract_floating_fields (struct { gdb_assert (bitpos == 0 || bitpos == 128); - regnum = SPARC64_Q0_REGNUM + bitpos / 128; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + + bitpos / 128; regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); } else if (len == 8) { gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256); - regnum = SPARC64_D0_REGNUM + bitpos / 64; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + bitpos / 64; regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); } else @@ -911,13 +936,13 @@ sparc64_store_arguments (struct regcache /* Float Complex or double Complex arguments. */ if (element < 16) { - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + element; if (len == 16) { - if (regnum < SPARC64_D30_REGNUM) + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D30_REGNUM) regcache_cooked_write (regcache, regnum + 1, valbuf + 8); - if (regnum < SPARC64_D10_REGNUM) + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM) regcache_cooked_write (regcache, SPARC_O0_REGNUM + element + 1, valbuf + 8); @@ -932,12 +957,14 @@ sparc64_store_arguments (struct regcache if (element % 2) element++; if (element < 16) - regnum = SPARC64_Q0_REGNUM + element / 2; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + + element / 2; } else if (len == 8) { if (element < 16) - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element; } else if (len == 4) { @@ -952,7 +979,8 @@ sparc64_store_arguments (struct regcache valbuf = buf; len = 8; if (element < 16) - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element; } } else @@ -969,19 +997,24 @@ sparc64_store_arguments (struct regcache /* If we're storing the value in a floating-point register, also store it in the corresponding %0 register(s). */ - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) - { - gdb_assert (element < 6); - regnum = SPARC_O0_REGNUM + element; - regcache_cooked_write (regcache, regnum, valbuf); - } - else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) - { - gdb_assert (element < 5); - regnum = SPARC_O0_REGNUM + element; - regcache_cooked_write (regcache, regnum, valbuf); - regcache_cooked_write (regcache, regnum + 1, valbuf + 8); - } + if (regnum >= gdbarch_num_regs (gdbarch)) + { + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) + { + gdb_assert (element < 6); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + } + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) + { + gdb_assert (element < 5); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + regcache_cooked_write (regcache, regnum + 1, valbuf + 8); + } + } } /* Always store the argument in memory. */ @@ -1185,6 +1218,10 @@ sparc64_init_abi (struct gdbarch_info in tdep->pc_regnum = SPARC64_PC_REGNUM; tdep->npc_regnum = SPARC64_NPC_REGNUM; + tdep->fpu_register_names = sparc64_fpu_register_names; + tdep->fpu_registers_num = ARRAY_SIZE (sparc64_fpu_register_names); + tdep->cp0_register_names = sparc64_cp0_register_names; + tdep->cp0_registers_num = ARRAY_SIZE (sparc64_cp0_register_names); /* This is what all the fuss is about. */ set_gdbarch_long_bit (gdbarch, 64);