This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 04 Jun 2003 15:38:06 -0400
- Subject: [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE
Hello,
I've been looking at merging the MIPS specific REGISTER_TO_TYPE with
REGISTER_TO_VALUE but first some background.
GDB currently has three register<->type conversion methods (I'm only
looking at the forward conversions here):
REGISTER_CONVERTIBLE:
REGISTER_CONVERT_TO_RAW:
REGISTER_CONVERT_TO_VIRTUAL:
Used by value_/of/_register.
They date back to when GDB was trying to raw register values into an
internal form. For instance (from memory), the m68k was converting it's
floating point registers into strict ieee.
These methods are no longer needed, Instead, registers are always
exactly described by their type and the register's underlying contents
are left unchanged. If, as with the MIPS, a register has multiple
views, then it is handled by having multiple pseudo registers.
CONVERT_REGISTER_P
REGISTER_TO_VALUE
VALUE_TO_REGISTER
Use by value_/from/_register.
These methods are used to perform single register <-> value
conversions. For instance, the Alpha will store integer values
(variables) in floating point registers. When GDB goes to extract an
integer's value it needs to perform an Alpha specific float<->integer
conversion. The original code re-used REGISTER_CONVERTIBLE but was
later separated out.
REGISTER_TO_TYPE
TYPE_TO_REGISTER
Used by value_/from/_register.
The MIPS uses this to convert a value spread across multiple
registers (REGISTER_TO_VALUE applies to a single register only).
So ...
The REGISTER_CONVERTIBLE series is ``dead''. I should at least
deprecate them. The only thing really making them stay around is the
MIPS and there Kevins stuff should eliminate it. The other
architectures still using them can (as the Alpha just did) simply switch
to REGISTER_TO_VALUE.
As for REGISTER_TO_TYPE and REGISTER_TO_VALUE, they very much have
overlapping functionality. The only significant difference is that one
applies to a single register, while the second applies to multiple
registers. Even the condition selecting which to apply is ``magic''.
num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
1);
if (num_storage_locs > 1
... REGISTER_TO_TYPE ...
else
... REGISTER_TO_VALUE ...
(remember a register can still have different raw and virtual sizes :-()
With this in mind, I'm thinking that REGISTER_TO_TYPE and
REGISTER_TO_VALUE should be merged. To that end, I can see several ways
of doing it:
- Don't merge - add REGISTER_TO_TYPE to the architecture vector
- Retain the current logic - just apply REGISTER_TO_VALUE to values
stored across multiple registers
- Add a frame parameter to REGISTER_TO_VALUE and make it responsible for
both extracting the bytes from the register[s] and then storing them in
the ``struct value''.
The last option is interesting, it would let the target draw the value
from any register based on REGNUM. The i386 with its long-long problem
might be interested in this (you'll notice in the patch I made an
attempt at doing this only I didn't see it affect the test results).
Thoughts?
Andrew
2003-06-04 Andrew Cagney <cagney@redhat.com>
* mips-tdep.c (mips_value_to_register): Replace
mips_register_convert_to_raw.
* mips-tdep.c (mips_register_to_value): Replace
mips_register_convert_to_virtual.
(mips_gdbarch_init): Set conver_register_p, value_to_register and
register_to_value.
* i386-tdep.c (i386_convert_register_p): Replace
i386_register_convertible.
(i386_register_to_value): Replace
i386_register_convert_to_virtual.
(i386_value_to_register): Replace i386_register_convert_to_raw.
* arch-utils.c (legacy_convert_register_p): Update.
(legacy_register_to_value): Update. Use "frame" to get the
register value.
* arch-utils.h (legacy_convert_register_p): Add "type" parameter.
(legacy_register_to_value): Add "frame" parameter, drop "from"
parameter.
* valops.c (value_assign): Pass the value's type to
CONVERT_REGISTER_P.
* findvar.c (value_from_register): Rewrite. Eliminate use of
REGISTER_CONVERT_TO_TYPE. Pass "type" to CONVERT_REGISTER_P.
Pass "frame" to REGISTER_TO_VALUE.
* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
(REGISTER_TO_VALUE): Add a "frame" and drop "from" parameter.
* gdbarch.h, gdbarch.c: Re-generate.
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.83
diff -u -r1.83 arch-utils.c
--- arch-utils.c 15 May 2003 22:58:36 -0000 1.83
+++ arch-utils.c 4 Jun 2003 18:34:52 -0000
@@ -440,16 +440,18 @@
}
int
-legacy_convert_register_p (int regnum)
+legacy_convert_register_p (int regnum, struct type *type)
{
return REGISTER_CONVERTIBLE (regnum);
}
void
-legacy_register_to_value (int regnum, struct type *type,
- char *from, char *to)
+legacy_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *buf)
{
- REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+ char tmp[MAX_REGISTER_SIZE];
+ frame_read_register (frame, regnum, tmp);
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, type, tmp, buf);
}
void
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.46
diff -u -r1.46 arch-utils.h
--- arch-utils.h 15 May 2003 22:58:36 -0000 1.46
+++ arch-utils.h 4 Jun 2003 18:34:52 -0000
@@ -165,8 +165,8 @@
(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 int legacy_convert_register_p (int regnum, struct type *type);
+extern void legacy_register_to_value (struct frame_info *frame, int regnum, struct type *type, void *buf);
extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to);
/* For compatibility with older architectures, returns
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.57
diff -u -r1.57 findvar.c
--- findvar.c 2 Jun 2003 02:09:39 -0000 1.57
+++ findvar.c 4 Jun 2003 18:34:52 -0000
@@ -624,145 +624,80 @@
struct value *
value_from_register (struct type *type, int regnum, struct frame_info *frame)
{
- char raw_buffer[MAX_REGISTER_SIZE];
- CORE_ADDR addr;
- int optim;
struct value *v = allocate_value (type);
- char *value_bytes = 0;
- int value_bytes_copied = 0;
- int num_storage_locs;
- enum lval_type lval;
- int len;
-
CHECK_TYPEDEF (type);
- len = TYPE_LENGTH (type);
-
- VALUE_REGNO (v) = regnum;
-
- num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
- ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
- 1);
- if (num_storage_locs > 1
-#if 0
- // OBSOLETE #ifdef GDB_TARGET_IS_H8500
- // OBSOLETE || TYPE_CODE (type) == TYPE_CODE_PTR
- // OBSOLETE #endif
-#endif
- )
+ if (CONVERT_REGISTER_P (regnum, type))
+ {
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ /* The ISA/ABI need to something weird when obtaining the
+ specified value from this register. It might need to combine
+ several registers, starting with REGNUM, in a strange way
+ (see MIPS and i386). It might need to convert the [float]
+ register into the corresponding [integer] type (see Alpha). */
+ /* Probe the ABI to find out where this first register lives.
+ Don't fetch the value. Use that information to describe the
+ variable location. Then ask the ABI for the actual value. */
+ /* Is this the best way of doing this? The alternative would be
+ to make REGISTER_TO_VALUE entirely responsible for populating
+ the value. */
+ frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+ REGISTER_TO_VALUE (frame, regnum, type, VALUE_CONTENTS_RAW (v));
+ VALUE_REGNO (v) = realnum;
+ VALUE_OPTIMIZED_OUT (v) = optim;
+ VALUE_LVAL (v) = lval;
+ VALUE_ADDRESS (v) = addr;
+ }
+ else
{
- /* Value spread across multiple storage locations. */
-
int local_regnum;
int mem_stor = 0, reg_stor = 0;
int mem_tracking = 1;
CORE_ADDR last_addr = 0;
CORE_ADDR first_addr = 0;
-
- value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
+ int first_realnum = regnum;
+ int len = TYPE_LENGTH (type);
+ int value_bytes_copied;
+ int optimized = 0;
+ char *value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
/* Copy all of the data out, whereever it may be. */
-
-#if 0
- // OBSOLETE #ifdef GDB_TARGET_IS_H8500
- // OBSOLETE /* This piece of hideosity is required because the H8500 treats registers
- // OBSOLETE differently depending upon whether they are used as pointers or not. As a
- // OBSOLETE pointer, a register needs to have a page register tacked onto the front.
- // OBSOLETE An alternate way to do this would be to have gcc output different register
- // OBSOLETE numbers for the pointer & non-pointer form of the register. But, it
- // OBSOLETE doesn't, so we're stuck with this. */
- // OBSOLETE
- // OBSOLETE if (TYPE_CODE (type) == TYPE_CODE_PTR
- // OBSOLETE && len > 2)
- // OBSOLETE {
- // OBSOLETE int page_regnum;
- // OBSOLETE
- // OBSOLETE switch (regnum)
- // OBSOLETE {
- // OBSOLETE case R0_REGNUM:
- // OBSOLETE case R1_REGNUM:
- // OBSOLETE case R2_REGNUM:
- // OBSOLETE case R3_REGNUM:
- // OBSOLETE page_regnum = SEG_D_REGNUM;
- // OBSOLETE break;
- // OBSOLETE case R4_REGNUM:
- // OBSOLETE case R5_REGNUM:
- // OBSOLETE page_regnum = SEG_E_REGNUM;
- // OBSOLETE break;
- // OBSOLETE case R6_REGNUM:
- // OBSOLETE case R7_REGNUM:
- // OBSOLETE page_regnum = SEG_T_REGNUM;
- // OBSOLETE break;
- // OBSOLETE }
- // OBSOLETE
- // OBSOLETE value_bytes[0] = 0;
- // OBSOLETE get_saved_register (value_bytes + 1,
- // OBSOLETE &optim,
- // OBSOLETE &addr,
- // OBSOLETE frame,
- // OBSOLETE page_regnum,
- // OBSOLETE &lval);
- // OBSOLETE
- // OBSOLETE if (register_cached (page_regnum) == -1)
- // OBSOLETE return NULL; /* register value not available */
- // OBSOLETE
- // OBSOLETE if (lval == lval_register)
- // OBSOLETE reg_stor++;
- // OBSOLETE else
- // OBSOLETE mem_stor++;
- // OBSOLETE first_addr = addr;
- // OBSOLETE last_addr = addr;
- // OBSOLETE
- // OBSOLETE get_saved_register (value_bytes + 2,
- // OBSOLETE &optim,
- // OBSOLETE &addr,
- // OBSOLETE frame,
- // OBSOLETE regnum,
- // OBSOLETE &lval);
- // OBSOLETE
- // OBSOLETE if (register_cached (regnum) == -1)
- // OBSOLETE return NULL; /* register value not available */
- // OBSOLETE
- // OBSOLETE if (lval == lval_register)
- // OBSOLETE reg_stor++;
- // OBSOLETE else
- // OBSOLETE {
- // OBSOLETE mem_stor++;
- // OBSOLETE mem_tracking = mem_tracking && (addr == last_addr);
- // OBSOLETE }
- // OBSOLETE last_addr = addr;
- // OBSOLETE }
- // OBSOLETE else
- // OBSOLETE #endif /* GDB_TARGET_IS_H8500 */
-#endif
- for (local_regnum = regnum;
- value_bytes_copied < len;
- (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
- ++local_regnum))
- {
- int realnum;
- frame_register (frame, local_regnum, &optim, &lval, &addr,
- &realnum, value_bytes + value_bytes_copied);
-
- if (register_cached (local_regnum) == -1)
- return NULL; /* register value not available */
-
- if (regnum == local_regnum)
+ for (local_regnum = regnum, value_bytes_copied = 0;
+ value_bytes_copied < len;
+ (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
+ ++local_regnum))
+ {
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ frame_register (frame, local_regnum, &optim, &lval, &addr,
+ &realnum, value_bytes + value_bytes_copied);
+ optimized += optim;
+ if (register_cached (local_regnum) == -1)
+ return NULL; /* register value not available */
+
+ if (regnum == local_regnum)
+ {
first_addr = addr;
- if (lval == lval_register)
- reg_stor++;
- else
- {
- mem_stor++;
-
- mem_tracking =
- (mem_tracking
- && (regnum == local_regnum
- || addr == last_addr));
- }
- last_addr = addr;
- }
-
+ first_realnum = realnum;
+ }
+ if (lval == lval_register)
+ reg_stor++;
+ else
+ {
+ mem_stor++;
+
+ mem_tracking = (mem_tracking
+ && (regnum == local_regnum
+ || addr == last_addr));
+ }
+ last_addr = addr;
+ }
+
if ((reg_stor && mem_stor)
|| (mem_stor && !mem_tracking))
/* Mixed storage; all of the hassle we just went through was
@@ -781,67 +716,29 @@
{
VALUE_LVAL (v) = lval_register;
VALUE_ADDRESS (v) = first_addr;
+ VALUE_REGNO (v) = first_realnum;
}
else
internal_error (__FILE__, __LINE__,
"value_from_register: Value not stored anywhere!");
-
- VALUE_OPTIMIZED_OUT (v) = optim;
-
+
+ VALUE_OPTIMIZED_OUT (v) = optimized;
+
/* Any structure stored in more than one register will always be
- an integral number of registers. Otherwise, you'd need to do
+ an integral number of registers. Otherwise, you need to do
some fiddling with the last register copied here for little
endian machines. */
-
- /* Copy into the contents section of the value. */
- memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len);
-
- /* Finally do any conversion necessary when extracting this
- type from more than one register. */
-#ifdef REGISTER_CONVERT_TO_TYPE
- REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v));
-#endif
- return v;
- }
-
- /* Data is completely contained within a single register. Locate the
- register's contents in a real register or in core;
- read the data in raw format. */
-
- {
- int realnum;
- frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer);
- }
-
- if (register_cached (regnum) == -1)
- return NULL; /* register value not available */
-
- VALUE_OPTIMIZED_OUT (v) = optim;
- VALUE_LVAL (v) = lval;
- VALUE_ADDRESS (v) = addr;
-
- /* Convert the raw register to the corresponding data value's memory
- format, if necessary. */
-
- if (CONVERT_REGISTER_P (regnum))
- {
- REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v));
- }
- else
- {
- /* Raw and virtual formats are the same for this register. */
-
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum))
- {
- /* Big-endian, and we want less than full size. */
- VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
- }
-
- memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && len < REGISTER_RAW_SIZE (regnum))
+ /* Big-endian, and we want less than full size. */
+ VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
+ else
+ VALUE_OFFSET (v) = 0;
+ memcpy (VALUE_CONTENTS_RAW (v), value_bytes + VALUE_OFFSET (v), len);
}
-
return v;
}
+
/* Given a struct symbol for a variable or function,
and a stack frame id,
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.218
diff -u -r1.218 gdbarch.c
--- gdbarch.c 2 Jun 2003 02:54:33 -0000 1.218
+++ gdbarch.c 4 Jun 2003 18:34:53 -0000
@@ -990,8 +990,8 @@
#ifdef CONVERT_REGISTER_P
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
- "CONVERT_REGISTER_P(regnum)",
- XSTRING (CONVERT_REGISTER_P (regnum)));
+ "CONVERT_REGISTER_P(regnum, type)",
+ XSTRING (CONVERT_REGISTER_P (regnum, type)));
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
"gdbarch_dump: CONVERT_REGISTER_P = <0x%08lx>\n",
@@ -2140,8 +2140,8 @@
/* 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)));
+ "REGISTER_TO_VALUE(frame, regnum, type, buf)",
+ XSTRING (REGISTER_TO_VALUE (frame, regnum, type, buf)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -4114,7 +4114,7 @@
}
int
-gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum)
+gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->convert_register_p == 0)
@@ -4122,7 +4122,7 @@
"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);
+ return gdbarch->convert_register_p (regnum, type);
}
void
@@ -4133,7 +4133,7 @@
}
void
-gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to)
+gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->register_to_value == 0)
@@ -4141,7 +4141,7 @@
"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);
+ gdbarch->register_to_value (frame, regnum, type, buf);
}
void
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.188
diff -u -r1.188 gdbarch.h
--- gdbarch.h 2 Jun 2003 02:54:33 -0000 1.188
+++ gdbarch.h 4 Jun 2003 18:34:53 -0000
@@ -1451,32 +1451,32 @@
/* 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))
+#define CONVERT_REGISTER_P(regnum, type) (legacy_convert_register_p (regnum, type))
#endif
-typedef int (gdbarch_convert_register_p_ftype) (int regnum);
-extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum);
+typedef int (gdbarch_convert_register_p_ftype) (int regnum, struct type *type);
+extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type);
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 !defined (CONVERT_REGISTER_P)
-#define CONVERT_REGISTER_P(regnum) (gdbarch_convert_register_p (current_gdbarch, regnum))
+#define CONVERT_REGISTER_P(regnum, type) (gdbarch_convert_register_p (current_gdbarch, regnum, type))
#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))
+#define REGISTER_TO_VALUE(frame, regnum, type, buf) (legacy_register_to_value (frame, regnum, type, buf))
#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);
+typedef void (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, void *buf);
+extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf);
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 !defined (REGISTER_TO_VALUE)
-#define REGISTER_TO_VALUE(regnum, type, from, to) (gdbarch_register_to_value (current_gdbarch, regnum, type, from, to))
+#define REGISTER_TO_VALUE(frame, regnum, type, buf) (gdbarch_register_to_value (current_gdbarch, frame, regnum, type, buf))
#endif
/* Default (function) for non- multi-arch platforms. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.240
diff -u -r1.240 gdbarch.sh
--- gdbarch.sh 2 Jun 2003 02:54:34 -0000 1.240
+++ gdbarch.sh 4 Jun 2003 18:34:55 -0000
@@ -557,8 +557,8 @@
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:CONVERT_REGISTER_P:int:convert_register_p:int regnum, struct type *type:regnum, type::0:legacy_convert_register_p::0
+f:1:REGISTER_TO_VALUE:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, void *buf:frame, regnum, type, buf::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
#
f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, const void *buf:type, buf:::unsigned_pointer_to_address::0
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.151
diff -u -r1.151 i386-tdep.c
--- i386-tdep.c 2 Jun 2003 02:54:35 -0000 1.151
+++ i386-tdep.c 4 Jun 2003 18:34:56 -0000
@@ -1326,52 +1326,55 @@
this is still sloppy. */
static int
-i386_register_convertible (int regnum)
+i386_convert_register_p (int regnum, struct type *type)
{
- return i386_fp_regnum_p (regnum);
+ if (i386_fp_regnum_p (regnum)
+ && TYPE_CODE (type) != TYPE_CODE_FLT)
+ /* Floating point registers have different register and memory
+ representations and hence need converting. */
+ return 1;
+ if (regnum < 3
+ && TYPE_CODE (type) == TYPE_CODE_INT
+ && TYPE_LENGTH (type) == 8)
+ /* A long long in registers, apparently GCC uses a set pair of
+ registers but they are not contigious. */
+ return 1;
+ /* Nothing interesting. */
+ return 0;
}
/* Convert data from raw format for register REGNUM in buffer FROM to
virtual format with type TYPE in buffer TO. */
+/* GCC allocates registers in the following order. */
+static int next_int64_regnum[] = { /*ax,dx,cx,bx*/ 2, 1, 3, };
+
static void
-i386_register_convert_to_virtual (int regnum, struct type *type,
- char *from, char *to)
+i386_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *to)
{
- gdb_assert (i386_fp_regnum_p (regnum));
-
- /* We only support floating-point values. */
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
+ if (i386_fp_regnum_p (regnum))
{
- warning ("Cannot convert floating-point register value "
- "to non-floating-point type.");
- memset (to, 0, TYPE_LENGTH (type));
- return;
+ char from[MAX_REGISTER_SIZE];
+ /* Read/convert to TYPE. This should be a no-op if TYPE is
+ equivalent to the extended floating-point format used by the
+ FPU. */
+ frame_read_register (frame, regnum, from);
+ convert_typed_floating (from, builtin_type_i387_ext, to, type);
+ }
+ else if (regnum < 3)
+ {
+ frame_read_register (frame, regnum, to);
+ frame_read_register (frame, next_int64_regnum[regnum], (char *) to + 4);
}
-
- /* Convert to TYPE. This should be a no-op if TYPE is equivalent to
- the extended floating-point format used by the FPU. */
- convert_typed_floating (from, builtin_type_i387_ext, to, type);
}
/* Convert data from virtual format with type TYPE in buffer FROM to
raw format for register REGNUM in buffer TO. */
static void
-i386_register_convert_to_raw (struct type *type, int regnum,
- char *from, char *to)
+i386_value_to_register (struct type *type, int regnum, char *from, char *to)
{
- gdb_assert (i386_fp_regnum_p (regnum));
-
- /* We only support floating-point values. */
- if (TYPE_CODE (type) != TYPE_CODE_FLT)
- {
- warning ("Cannot convert non-floating-point type "
- "to floating-point register value.");
- memset (to, 0, TYPE_LENGTH (type));
- return;
- }
-
/* Convert from TYPE. This should be a no-op if TYPE is equivalent
to the extended floating-point format used by the FPU. */
convert_typed_floating (from, type, to, builtin_type_i387_ext);
@@ -1686,10 +1689,9 @@
/* Call dummy code. */
set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
- set_gdbarch_register_convertible (gdbarch, i386_register_convertible);
- set_gdbarch_register_convert_to_virtual (gdbarch,
- i386_register_convert_to_virtual);
- set_gdbarch_register_convert_to_raw (gdbarch, i386_register_convert_to_raw);
+ set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207
diff -u -r1.207 mips-tdep.c
--- mips-tdep.c 1 Jun 2003 19:02:19 -0000 1.207
+++ mips-tdep.c 4 Jun 2003 18:34:57 -0000
@@ -634,9 +634,28 @@
TYPE_LENGTH (virtual_type));
}
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+ return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+ && REGISTER_RAW_SIZE (regnum) == 4
+ && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
+ && TYPE_CODE(type) == TYPE_CODE_FLT
+ && TYPE_LENGTH(type) == 8);
+}
+
+void
+mips_register_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *buffer)
+{
+ frame_read_register (frame, regnum + 0, (char *) buffer + 4);
+ frame_read_register (frame, regnum + 1, buffer);
+}
+
void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct type *type, int regnum, char *in, char *out)
{
+#if 0
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& REGISTER_RAW_SIZE (regnum) == 4
&& (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
@@ -646,24 +665,9 @@
char temp[4];
memcpy (temp, ((char *)(buffer))+4, 4);
memcpy (((char *)(buffer))+4, (buffer), 4);
- memcpy (((char *)(buffer)), temp, 4);
+ memcpy (((char *)(buffer)), temp, 4);
}
-}
-
-void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
-{
-if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
- && REGISTER_RAW_SIZE (regnum) == 4
- && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
- && TYPE_CODE(type) == TYPE_CODE_FLT
- && TYPE_LENGTH(type) == 8)
- {
- char temp[4];
- memcpy (temp, ((char *)(buffer))+4, 4);
- memcpy (((char *)(buffer))+4, (buffer), 4);
- memcpy (((char *)(buffer)), temp, 4);
- }
+#endif
}
/* Return the GDB type object for the "standard" data type
@@ -5961,11 +5965,9 @@
set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
- set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
- set_gdbarch_register_convert_to_virtual (gdbarch,
- mips_register_convert_to_virtual);
- set_gdbarch_register_convert_to_raw (gdbarch,
- mips_register_convert_to_raw);
+ set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.109
diff -u -r1.109 valops.c
--- valops.c 14 May 2003 17:43:20 -0000 1.109
+++ valops.c 4 Jun 2003 18:34:58 -0000
@@ -501,10 +501,13 @@
convert FROMVAL's contents now, with result in `raw_buffer',
and set USE_BUFFER to the number of bytes to write. */
+ /* FIXME: Should instead do this in the below switch when it is
+ clear that this really is a lval_register that needs conversion. */
+
if (VALUE_REGNO (toval) >= 0)
{
int regno = VALUE_REGNO (toval);
- if (CONVERT_REGISTER_P (regno))
+ if (CONVERT_REGISTER_P (regno, VALUE_TYPE (toval)))
{
struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
@@ -661,9 +664,11 @@
TYPE_LENGTH (type));
/* Do any conversion necessary when storing this type to
more than one register. */
+#if 0
#ifdef REGISTER_CONVERT_FROM_TYPE
REGISTER_CONVERT_FROM_TYPE (value_reg, type,
(buffer + byte_offset));
+#endif
#endif
}