From 13d0122493ff8353509896837bd61fdb571fdb09 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Sun, 12 May 2002 03:09:12 +0000 Subject: [PATCH] * arch-utils.h (legacy_register_to_value): Declare. (legacy_value_to_register): Declare. (legacy_convert_register_p): Declare. * arch-utils.c (legacy_register_to_value): New function. (legacy_value_to_register): New function. (legacy_convert_register_p): New function. * gdbarch.sh (REGISTER_TO_VALUE): Define. (VALUE_TO_REGISTER): Define. (CONVERT_REGISTER_P): Define. * gdbarch.h, gdbarch.c: Regenerate. * valops.c (value_assign): Use CONVERT_REGISTER_P and VALUE_TO_REGISTER. * findvar.c (value_from_register): Use REGISTER_TO_VALUE and CONVERT_REGISTER_P. * gdbint.texinfo (Target Architecture Definition): Document REGISTER_TO_VALUE and VALUE_TO_REGISTER and CONVERT_REGISTER_P. (Target Architecture Definition): Revise section `Using Different Register and Memory Data Representations'. Add section `Raw and Virtual Register Representations'. --- gdb/ChangeLog | 19 ++++++ gdb/arch-utils.c | 20 ++++++ gdb/arch-utils.h | 9 +++ gdb/doc/ChangeLog | 8 +++ gdb/doc/gdbint.texinfo | 141 +++++++++++++++++++++++++++++++++++------ gdb/findvar.c | 8 +-- gdb/gdbarch.c | 108 +++++++++++++++++++++++++++++++ gdb/gdbarch.h | 51 +++++++++++++++ gdb/gdbarch.sh | 4 ++ gdb/valops.c | 5 +- 10 files changed, 345 insertions(+), 28 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4699c43ba36..c6c9442e544 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,22 @@ +2002-05-11 Andrew Cagney + + * arch-utils.h (legacy_register_to_value): Declare. + (legacy_value_to_register): Declare. + (legacy_convert_register_p): Declare. + * arch-utils.c (legacy_register_to_value): New function. + (legacy_value_to_register): New function. + (legacy_convert_register_p): New function. + + * gdbarch.sh (REGISTER_TO_VALUE): Define. + (VALUE_TO_REGISTER): Define. + (CONVERT_REGISTER_P): Define. + * gdbarch.h, gdbarch.c: Regenerate. + + * valops.c (value_assign): Use CONVERT_REGISTER_P and + VALUE_TO_REGISTER. + * findvar.c (value_from_register): Use REGISTER_TO_VALUE and + CONVERT_REGISTER_P. + 2005-05-11 Daniel Jacobowitz Peter Schauer diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 1fb8e36fef4..bde89a8fa8e 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -429,6 +429,26 @@ legacy_pc_in_sigtramp (CORE_ADDR pc, char *name) return IN_SIGTRAMP(pc, name); } +int +legacy_convert_register_p (int regnum) +{ + return REGISTER_CONVERTIBLE (regnum); +} + +void +legacy_register_to_value (int regnum, struct type *type, + char *from, char *to) +{ + REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to); +} + +void +legacy_value_to_register (struct type *type, int regnum, + char *from, char *to) +{ + REGISTER_CONVERT_TO_RAW (type, regnum, from, to); +} + /* Functions to manipulate the endianness of the target. */ diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index bcd17aaf713..594a83209a3 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -157,6 +157,15 @@ extern int generic_register_size (int regnum); /* Prop up old targets that use various IN_SIGTRAMP() macros. */ extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name); +/* The orginal register_convert*() functions were overloaded. They + were used to both: convert between virtual and raw register formats + (something that is discouraged); and to convert a register to the + type of a corresponding variable. These legacy functions preserve + that overloaded behavour in existing targets. */ +extern int legacy_convert_register_p (int regnum); +extern void legacy_register_to_value (int regnum, struct type *type, char *from, char *to); +extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to); + /* Initialize a ``struct info''. Can't use memset(0) since some default values are not zero. */ extern void gdbarch_info_init (struct gdbarch_info *info); diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 3ddf6f683fd..32128006c3d 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,11 @@ +2002-05-11 Andrew Cagney + + * gdbint.texinfo (Target Architecture Definition): Document + REGISTER_TO_VALUE and VALUE_TO_REGISTER and CONVERT_REGISTER_P. + (Target Architecture Definition): Revise section `Using Different + Register and Memory Data Representations'. Add section `Raw and + Virtual Register Representations'. + 2002-05-11 Andrew Cagney * gdbint.texinfo (Target Architecture Definition): Mention diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index a52c19c225d..f371659f6bf 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -2487,22 +2487,19 @@ C@t{++} reference type. @end deftypefn -@section Using Different Register and Memory Data Representations -@cindex raw representation -@cindex virtual representation -@cindex representations, raw and virtual -@cindex register data formats, converting -@cindex @code{struct value}, converting register contents to - -@emph{Maintainer's note: The way GDB manipulates registers is undergoing -significant change. Many of the macros and functions refered to in the -section below are likely to be made obsolete. For instance, instead of -having different raw and virtual register sizes, an architecture can -define pseudo-registers that map onto the raw registers. - -See the @uref{http://www.gnu.org/software/gdb/bugs/, Bug Tracking -Database} and @uref{http://sources.redhat.com/gdb/current/ari, ARI -Index} for more up-to-date information.} +@section Raw and Virtual Register Representations +@cindex raw register representation +@cindex virtual register representation +@cindex representations, raw and virtual registers + +@emph{Maintainer note: This section is pretty much obsolete. The +functionality described here has largely been replaced by +pseudo-registers and the mechanisms described in @ref{Target +Architecture Definition, , Using Different Register and Memory Data +Representations}. See also @uref{http://www.gnu.org/software/gdb/bugs/, +Bug Tracking Database} and +@uref{http://sources.redhat.com/gdb/current/ari/, ARI Index} for more +up-to-date information.} Some architectures use one representation for a value when it lives in a register, but use a different representation when it lives in memory. @@ -2510,6 +2507,10 @@ In @value{GDBN}'s terminology, the @dfn{raw} representation is the one used in the target registers, and the @dfn{virtual} representation is the one used in memory, and within @value{GDBN} @code{struct value} objects. +@emph{Maintainer note: Notice that the same mechanism is being used to +both convert a register to a @code{struct value} and alternative +register forms.} + For almost all data types on almost all architectures, the virtual and raw representations are identical, and no special handling is needed. However, they do occasionally differ. For example: @@ -2594,6 +2595,85 @@ their @var{reg} and @var{type} arguments in different orders. @end deftypefn +@section Using Different Register and Memory Data Representations +@cindex register representation +@cindex memory representation +@cindex representations, register and memory +@cindex register data formats, converting +@cindex @code{struct value}, converting register contents to + +@emph{Maintainer's note: The way GDB manipulates registers is undergoing +significant change. Many of the macros and functions refered to in this +section are likely to be subject to further revision. See +@uref{http://sources.redhat.com/gdb/current/ari/, A.R. Index} and +@uref{http://www.gnu.org/software/gdb/bugs, Bug Tracking Database} for +further information. cagney/2002-05-06.} + +Some architectures can represent a data object in a register using a +form that is different to the objects more normal memory representation. +For example: + +@itemize @bullet + +@item +The Alpha architecture can represent 32 bit integer values in +floating-point registers. + +@item +The x86 architecture supports 80-bit floating-point registers. The +@code{long double} data type occupies 96 bits in memory but only 80 bits +when stored in a register. + +@end itemize + +In general, the register representation of a data type is determined by +the architecture, or @value{GDBN}'s interface to the architecture, while +the memory representation is determined by the Application Binary +Interface. + +For almost all data types on almost all architectures, the two +representations are identical, and no special handling is needed. +However, they do occasionally differ. Your architecture may define the +following macros to request conversions between the register and memory +representations of a data type: + +@deftypefn {Target Macro} int CONVERT_REGISTER_P (int @var{reg}) +Return non-zero if the representation of a data value stored in this +register may be different to the representation of that same data value +when stored in memory. + +When non-zero, the macros @code{REGISTER_TO_VALUE} and +@code{VALUE_TO_REGISTER} are used to perform any necessary conversion. +@end deftypefn + +@deftypefn {Target Macro} void REGISTER_TO_VALUE (int @var{reg}, struct type *@var{type}, char *@var{from}, char *@var{to}) +Convert the value of register number @var{reg} to a data object of type +@var{type}. The buffer at @var{from} holds the register's value in raw +format; the converted value should be placed in the buffer at @var{to}. + +Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take +their @var{reg} and @var{type} arguments in different orders. + +You should only use @code{REGISTER_TO_VALUE} with registers for which +the @code{CONVERT_REGISTER_P} macro returns a non-zero value. +@end deftypefn + +@deftypefn {Target Macro} void VALUE_TO_REGISTER (struct type *@var{type}, int @var{reg}, char *@var{from}, char *@var{to}) +Convert a data value of type @var{type} to register number @var{reg}' +raw format. + +Note that @code{REGISTER_TO_VALUE} and @code{VALUE_TO_REGISTER} take +their @var{reg} and @var{type} arguments in different orders. + +You should only use @code{VALUE_TO_REGISTER} with registers for which +the @code{CONVERT_REGISTER_P} macro returns a non-zero value. +@end deftypefn + +@deftypefn {Target Macro} void REGISTER_CONVERT_TO_TYPE (int @var{regnum}, struct type *@var{type}, char *@var{buf}) +See @file{mips-tdep.c}. It does not do what you want. +@end deftypefn + + @section Frame Interpretation @section Inferior Call Setup @@ -2839,6 +2919,12 @@ otherwise, we should leave it alone. The function @code{default_coerce_float_to_double} provides this behavior; it is the default value, for compatibility with older configurations. +@item int CONVERT_REGISTER_P(@var{regnum}) +@findex CONVERT_REGISTER_P +Return non-zero if register @var{regnum} can represent data values in a +non-standard form. +@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. + @item CPLUS_MARKER @findex CPLUS_MARKERz Define this to expand into the character that G@t{++} uses to distinguish @@ -3176,36 +3262,43 @@ address the pointer refers to. @item REGISTER_CONVERTIBLE (@var{reg}) @findex REGISTER_CONVERTIBLE Return non-zero if @var{reg} uses different raw and virtual formats. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. + +@item REGISTER_TO_VALUE(@var{regnum}, @var{type}, @var{from}, @var{to}) +@findex REGISTER_TO_VALUE +Convert the raw contents of register @var{regnum} into a value of type +@var{type}. @xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. @item REGISTER_RAW_SIZE (@var{reg}) @findex REGISTER_RAW_SIZE Return the raw size of @var{reg}; defaults to the size of the register's virtual type. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item REGISTER_VIRTUAL_SIZE (@var{reg}) @findex REGISTER_VIRTUAL_SIZE Return the virtual size of @var{reg}; defaults to the size of the register's virtual type. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +Return the virtual size of @var{reg}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item REGISTER_VIRTUAL_TYPE (@var{reg}) @findex REGISTER_VIRTUAL_TYPE Return the virtual type of @var{reg}. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item REGISTER_CONVERT_TO_VIRTUAL(@var{reg}, @var{type}, @var{from}, @var{to}) @findex REGISTER_CONVERT_TO_VIRTUAL Convert the value of register @var{reg} from its raw form to its virtual form. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item REGISTER_CONVERT_TO_RAW(@var{type}, @var{reg}, @var{from}, @var{to}) @findex REGISTER_CONVERT_TO_RAW Convert the value of register @var{reg} from its virtual form to its raw form. -@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. +@xref{Target Architecture Definition, , Raw and Virtual Register Representations}. @item RETURN_VALUE_ON_STACK(@var{type}) @findex RETURN_VALUE_ON_STACK @@ -3587,6 +3680,12 @@ being considered is known to have been compiled by GCC; this is helpful for systems where GCC is known to use different calling convention than other compilers. +@item VALUE_TO_REGISTER(@var{type}, @var{regnum}, @var{from}, @var{to}) +@findex VALUE_TO_REGISTER +Convert a value of type @var{type} into the raw contents of register +@var{regnum}'s. +@xref{Target Architecture Definition, , Using Different Register and Memory Data Representations}. + @item VARIABLES_INSIDE_BLOCK (@var{desc}, @var{gcc_p}) @findex VARIABLES_INSIDE_BLOCK For dbx-style debugging information, if the compiler puts variable diff --git a/gdb/findvar.c b/gdb/findvar.c index 0f116ed9adf..1faaa905113 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -813,12 +813,12 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) VALUE_LVAL (v) = lval; VALUE_ADDRESS (v) = addr; - /* Convert raw data to virtual format if necessary. */ + /* Convert the raw register to the corresponding data value's memory + format, if necessary. */ - if (REGISTER_CONVERTIBLE (regnum)) + if (CONVERT_REGISTER_P (regnum)) { - REGISTER_CONVERT_TO_VIRTUAL (regnum, type, - raw_buffer, VALUE_CONTENTS_RAW (v)); + REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v)); } else { diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 38c8843e42b..52cc959e238 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -200,6 +200,9 @@ struct gdbarch gdbarch_register_convertible_ftype *register_convertible; gdbarch_register_convert_to_virtual_ftype *register_convert_to_virtual; gdbarch_register_convert_to_raw_ftype *register_convert_to_raw; + gdbarch_convert_register_p_ftype *convert_register_p; + gdbarch_register_to_value_ftype *register_to_value; + gdbarch_value_to_register_ftype *value_to_register; gdbarch_fetch_pseudo_register_ftype *fetch_pseudo_register; gdbarch_store_pseudo_register_ftype *store_pseudo_register; gdbarch_pointer_to_address_ftype *pointer_to_address; @@ -399,6 +402,9 @@ struct gdbarch startup_gdbarch = 0, 0, 0, + 0, + 0, + 0, generic_in_function_epilogue_p, construct_inferior_arguments, 0, @@ -501,6 +507,9 @@ gdbarch_alloc (const struct gdbarch_info *info, current_gdbarch->init_frame_pc = init_frame_pc_default; current_gdbarch->coerce_float_to_double = default_coerce_float_to_double; current_gdbarch->register_convertible = generic_register_convertible_not; + current_gdbarch->convert_register_p = legacy_convert_register_p; + current_gdbarch->register_to_value = legacy_register_to_value; + current_gdbarch->value_to_register = legacy_value_to_register; current_gdbarch->pointer_to_address = unsigned_pointer_to_address; current_gdbarch->address_to_pointer = unsigned_address_to_pointer; current_gdbarch->return_value_on_stack = generic_return_value_on_stack_not; @@ -682,6 +691,9 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of register_convertible, invalid_p == 0 */ /* Skip verify of register_convert_to_virtual, invalid_p == 0 */ /* Skip verify of register_convert_to_raw, invalid_p == 0 */ + /* Skip verify of convert_register_p, invalid_p == 0 */ + /* Skip verify of register_to_value, invalid_p == 0 */ + /* Skip verify of value_to_register, invalid_p == 0 */ /* Skip verify of fetch_pseudo_register, has predicate */ /* Skip verify of store_pseudo_register, has predicate */ /* Skip verify of pointer_to_address, invalid_p == 0 */ @@ -1011,6 +1023,17 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) (long) current_gdbarch->convert_from_func_ptr_addr /*CONVERT_FROM_FUNC_PTR_ADDR ()*/); #endif +#ifdef CONVERT_REGISTER_P + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "CONVERT_REGISTER_P(regnum)", + XSTRING (CONVERT_REGISTER_P (regnum))); + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: CONVERT_REGISTER_P = 0x%08lx\n", + (long) current_gdbarch->convert_register_p + /*CONVERT_REGISTER_P ()*/); +#endif #ifdef DECR_PC_AFTER_BREAK fprintf_unfiltered (file, "gdbarch_dump: DECR_PC_AFTER_BREAK # %s\n", @@ -1701,6 +1724,20 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: REGISTER_SIZE = %d\n", REGISTER_SIZE); #endif +#ifdef REGISTER_TO_VALUE +#if GDB_MULTI_ARCH + /* Macro might contain `[{}]' when not multi-arch */ + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "REGISTER_TO_VALUE(regnum, type, from, to)", + XSTRING (REGISTER_TO_VALUE (regnum, type, from, to))); +#endif + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: REGISTER_TO_VALUE = 0x%08lx\n", + (long) current_gdbarch->register_to_value + /*REGISTER_TO_VALUE ()*/); +#endif #ifdef REGISTER_VIRTUAL_SIZE fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", @@ -2155,6 +2192,20 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: USE_STRUCT_CONVENTION = 0x%08lx\n", (long) current_gdbarch->use_struct_convention /*USE_STRUCT_CONVENTION ()*/); +#endif +#ifdef VALUE_TO_REGISTER +#if GDB_MULTI_ARCH + /* Macro might contain `[{}]' when not multi-arch */ + fprintf_unfiltered (file, + "gdbarch_dump: %s # %s\n", + "VALUE_TO_REGISTER(type, regnum, from, to)", + XSTRING (VALUE_TO_REGISTER (type, regnum, from, to))); +#endif + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, + "gdbarch_dump: VALUE_TO_REGISTER = 0x%08lx\n", + (long) current_gdbarch->value_to_register + /*VALUE_TO_REGISTER ()*/); #endif if (current_gdbarch->dump_tdep != NULL) current_gdbarch->dump_tdep (current_gdbarch, file); @@ -3539,6 +3590,63 @@ set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarch->register_convert_to_raw = register_convert_to_raw; } +int +gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch->convert_register_p == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_convert_register_p invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n"); + return gdbarch->convert_register_p (regnum); +} + +void +set_gdbarch_convert_register_p (struct gdbarch *gdbarch, + gdbarch_convert_register_p_ftype convert_register_p) +{ + gdbarch->convert_register_p = convert_register_p; +} + +void +gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch->register_to_value == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_register_to_value invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n"); + gdbarch->register_to_value (regnum, type, from, to); +} + +void +set_gdbarch_register_to_value (struct gdbarch *gdbarch, + gdbarch_register_to_value_ftype register_to_value) +{ + gdbarch->register_to_value = register_to_value; +} + +void +gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch->value_to_register == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_value_to_register invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_value_to_register called\n"); + gdbarch->value_to_register (type, regnum, from, to); +} + +void +set_gdbarch_value_to_register (struct gdbarch *gdbarch, + gdbarch_value_to_register_ftype value_to_register) +{ + gdbarch->value_to_register = value_to_register; +} + int gdbarch_fetch_pseudo_register_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 84b8c7d8211..94f12d22c3f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1267,6 +1267,57 @@ extern void set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarc #endif #endif +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (CONVERT_REGISTER_P) +#define CONVERT_REGISTER_P(regnum) (legacy_convert_register_p (regnum)) +#endif + +typedef int (gdbarch_convert_register_p_ftype) (int regnum); +extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum); +extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_REGISTER_P) +#error "Non multi-arch definition of CONVERT_REGISTER_P" +#endif +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_REGISTER_P) +#define CONVERT_REGISTER_P(regnum) (gdbarch_convert_register_p (current_gdbarch, regnum)) +#endif +#endif + +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (REGISTER_TO_VALUE) +#define REGISTER_TO_VALUE(regnum, type, from, to) (legacy_register_to_value (regnum, type, from, to)) +#endif + +typedef void (gdbarch_register_to_value_ftype) (int regnum, struct type *type, char *from, char *to); +extern void gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to); +extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_TO_VALUE) +#error "Non multi-arch definition of REGISTER_TO_VALUE" +#endif +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (REGISTER_TO_VALUE) +#define REGISTER_TO_VALUE(regnum, type, from, to) (gdbarch_register_to_value (current_gdbarch, regnum, type, from, to)) +#endif +#endif + +/* Default (function) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (VALUE_TO_REGISTER) +#define VALUE_TO_REGISTER(type, regnum, from, to) (legacy_value_to_register (type, regnum, from, to)) +#endif + +typedef void (gdbarch_value_to_register_ftype) (struct type *type, int regnum, char *from, char *to); +extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to); +extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register); +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (VALUE_TO_REGISTER) +#error "Non multi-arch definition of VALUE_TO_REGISTER" +#endif +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) || !defined (VALUE_TO_REGISTER) +#define VALUE_TO_REGISTER(type, regnum, from, to) (gdbarch_value_to_register (current_gdbarch, type, regnum, from, to)) +#endif +#endif + /* This function is called when the value of a pseudo-register needs to be updated. Typically it will be defined on a per-architecture basis. */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 4aed81b6b7b..dab4aac8ad5 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -514,6 +514,10 @@ f:1:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_convertible_not::0 f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0 f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, char *from, char *to:type, regnum, from, to:::0::0 +# +f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum:regnum::0:legacy_convert_register_p::0 +f:1:REGISTER_TO_VALUE:void:register_to_value:int regnum, struct type *type, char *from, char *to:regnum, type, from, to::0:legacy_register_to_value::0 +f:1:VALUE_TO_REGISTER:void:value_to_register:struct type *type, int regnum, char *from, char *to:type, regnum, from, to::0:legacy_value_to_register::0 # This function is called when the value of a pseudo-register needs to # be updated. Typically it will be defined on a per-architecture # basis. diff --git a/gdb/valops.c b/gdb/valops.c index 33b28cdf1f5..cd5d4ca87f8 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -563,11 +563,10 @@ value_assign (struct value *toval, struct value *fromval) if (VALUE_REGNO (toval) >= 0) { int regno = VALUE_REGNO (toval); - if (REGISTER_CONVERTIBLE (regno)) + if (CONVERT_REGISTER_P (regno)) { struct type *fromtype = check_typedef (VALUE_TYPE (fromval)); - REGISTER_CONVERT_TO_RAW (fromtype, regno, - VALUE_CONTENTS (fromval), raw_buffer); + VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer); use_buffer = REGISTER_RAW_SIZE (regno); } } -- 2.30.2