aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-06-06 18:02:30 +0000
committerAndrew Cagney <cagney@redhat.com>2003-06-06 18:02:30 +0000
commit699c254494692d0d3bc6691c5da1205431908909 (patch)
treeb8dbda3092de4c9440c42dd03e68dec814bb78c4
parent6e70edab446871d228f63af6e142b5b45bfb804d (diff)
downloadfsf-binutils-gdb-699c254494692d0d3bc6691c5da1205431908909.zip
fsf-binutils-gdb-699c254494692d0d3bc6691c5da1205431908909.tar.gz
fsf-binutils-gdb-699c254494692d0d3bc6691c5da1205431908909.tar.bz2
2003-06-06 Andrew Cagney <cagney@redhat.com>
* frame.h (put_frame_register): Declare. * frame.c (put_frame_register): New function. * arch-utils.c: Include "gdbcore.h". (legacy_convert_register_p): Add "type" parameter. (legacy_register_to_value): Rewrite, use "frame" to get the register value. (legacy_value_to_register): Rewrite, use "frame" to find the register's location before storing. * arch-utils.h (legacy_convert_register_p): Update. (legacy_register_to_value, legacy_value_to_register): Update. * Makefile.in (arch-utils.o): Update dependencies. * 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, VALUE_TO_REGISTER): Replace "type", "from" and "to" parameters with "frame" and "value". * gdbarch.h, gdbarch.c: Re-generate. * mips-tdep.c (mips_convert_register_p): New function. (mips_value_to_register): Replace mips_register_convert_from_type. (mips_register_to_value): Replace mips_register_convert_to_type. (mips_gdbarch_init): Set conver_register_p, value_to_register and register_to_value. * valops.c (value_assign): Move the CONVERT_REGISTER code to the lval_reg_frame_relative + lval_register branch of the switch. Do not use REGISTER_CONVERT_FROM_TYPE. Use put_frame_register.
-rw-r--r--gdb/ChangeLog35
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/arch-utils.c48
-rw-r--r--gdb/arch-utils.h6
-rw-r--r--gdb/findvar.c249
-rw-r--r--gdb/frame.c30
-rw-r--r--gdb/frame.h6
-rw-r--r--gdb/gdbarch.c24
-rw-r--r--gdb/gdbarch.h24
-rwxr-xr-xgdb/gdbarch.sh6
-rw-r--r--gdb/mips-tdep.c48
-rw-r--r--gdb/valops.c157
12 files changed, 296 insertions, 339 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 30c3a86..83f1191 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,38 @@
+2003-06-06 Andrew Cagney <cagney@redhat.com>
+
+ * frame.h (put_frame_register): Declare.
+ * frame.c (put_frame_register): New function.
+
+ * arch-utils.c: Include "gdbcore.h".
+ (legacy_convert_register_p): Add "type" parameter.
+ (legacy_register_to_value): Rewrite, use "frame" to get the
+ register value.
+ (legacy_value_to_register): Rewrite, use "frame" to find the
+ register's location before storing.
+ * arch-utils.h (legacy_convert_register_p): Update.
+ (legacy_register_to_value, legacy_value_to_register): Update.
+
+ * Makefile.in (arch-utils.o): Update dependencies.
+
+ * 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, VALUE_TO_REGISTER): Replace "type", "from" and
+ "to" parameters with "frame" and "value".
+ * gdbarch.h, gdbarch.c: Re-generate.
+
+ * mips-tdep.c (mips_convert_register_p): New function.
+ (mips_value_to_register): Replace mips_register_convert_from_type.
+ (mips_register_to_value): Replace mips_register_convert_to_type.
+ (mips_gdbarch_init): Set conver_register_p, value_to_register and
+ register_to_value.
+
+ * valops.c (value_assign): Move the CONVERT_REGISTER code to the
+ lval_reg_frame_relative + lval_register branch of the switch. Do
+ not use REGISTER_CONVERT_FROM_TYPE. Use put_frame_register.
+
2003-06-06 Michal Ludvig <mludvig@suse.cz>
* x86-64-tdep.c (x86_64_fill_fxsave): Pass correct regnums
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 823fa46..1e02370 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1539,7 +1539,7 @@ arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) \
$(inferior_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(annotate_h) \
$(gdb_string_h) $(regcache_h) $(gdb_assert_h) $(sim_regno_h) \
- $(version_h) $(floatformat_h)
+ $(version_h) $(floatformat_h) $(gdbcore_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index 48f7f7e..d437b1e 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -47,6 +47,7 @@
#include "version.h"
#include "floatformat.h"
+#include "gdbcore.h"
/* Implementation of extract return value that grubs around in the
register cache. */
@@ -440,23 +441,54 @@ legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
}
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)
-{
- REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+legacy_register_to_value (struct frame_info *frame, int regnum,
+ struct value *v)
+{
+ char from[MAX_REGISTER_SIZE];
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ frame_register (frame, regnum, &optim, &lval, &addr, &realnum, from);
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, VALUE_TYPE (v), from,
+ VALUE_CONTENTS_RAW (v));
+ VALUE_LVAL (v) = lval;
+ VALUE_REGNO (v) = realnum;
+ VALUE_ADDRESS (v) = addr;
+ /* Note: This function is just trying to keep old code alive, don't
+ let it handle anything other than a few obvious cases. */
+ gdb_assert (lval == lval_register || lval == lval_memory);
+ VALUE_OPTIMIZED_OUT (v) = optim;
}
void
-legacy_value_to_register (struct type *type, int regnum,
- char *from, char *to)
+legacy_value_to_register (struct frame_info *frame, struct value *v)
{
- REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ char to[MAX_REGISTER_SIZE];
+ REGISTER_CONVERT_TO_RAW (VALUE_TYPE (v), VALUE_REGNO (v),
+ VALUE_CONTENTS (v), to);
+ switch (VALUE_LVAL (v))
+ {
+ case lval_register:
+ /* FIXME: How to get from the frame to the, several levels
+ inner, regcache? */
+ regcache_cooked_write (current_regcache, VALUE_REGNO (v), to);
+ break;
+ case lval_memory:
+ write_memory (VALUE_ADDRESS (v), to,
+ register_size (gdbarch, (VALUE_REGNO (v))));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "Unhandled lval %d",
+ (int) VALUE_LVAL (v));
+ }
}
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
index 27f219b..1e7425c 100644
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -165,9 +165,9 @@ extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name);
(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);
+extern int legacy_convert_register_p (int regnum, struct type *type);
+extern void legacy_register_to_value (struct frame_info *frame, int regnum, struct value *v);
+extern void legacy_value_to_register (struct frame_info *frame, struct value *v);
/* For compatibility with older architectures, returns
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 4aa4f46..5bcb1e8 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -624,145 +624,76 @@ addresses have not been bound by the dynamic loader. Try again when executable i
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 gdbarch *gdbarch = get_frame_arch (frame);
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
+ re-order non-adjacent, starting with REGNUM (see MIPS and
+ i386). It might need to convert the [float] register into
+ the corresponding [integer] type (see Alpha). The assumption
+ is that REGISTER_TO_VALUE populates the entire value
+ including the location. */
+ REGISTER_TO_VALUE (frame, regnum, v);
+ }
+ 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;
+ }
+
+ /* FIXME: cagney/2003-06-04: Shouldn't this always use
+ lval_reg_frame_relative? If it doesn't and the register's
+ location changes (say after a resume) then this value is
+ going to have wrong information. */
if ((reg_stor && mem_stor)
|| (mem_stor && !mem_tracking))
/* Mixed storage; all of the hassle we just went through was
@@ -781,67 +712,29 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
{
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,
diff --git a/gdb/frame.c b/gdb/frame.c
index dd69dde..e196a5f 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -674,6 +674,36 @@ frame_read_signed_register (struct frame_info *frame, int regnum,
}
void
+put_frame_register (struct frame_info *frame, int regnum, const void *buf)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+ if (optim)
+ error ("Attempt to assign to a value that was optimized out.");
+ switch (lval)
+ {
+ case lval_memory:
+ {
+ /* FIXME: write_memory doesn't yet take constant buffers.
+ Arrrg! */
+ char tmp[MAX_REGISTER_SIZE];
+ memcpy (tmp, buf, register_size (gdbarch, regnum));
+ write_memory (addr, tmp, register_size (gdbarch, regnum));
+ break;
+ }
+ case lval_register:
+ regcache_cooked_write (current_regcache, realnum, buf);
+ break;
+ default:
+ error ("Attempt to assign to an unmodifiable value.");
+ }
+}
+
+void
generic_unwind_get_saved_register (char *raw_buffer,
int *optimizedp,
CORE_ADDR *addrp,
diff --git a/gdb/frame.h b/gdb/frame.h
index bfd9469..1531fdb 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -325,6 +325,12 @@ extern void frame_read_signed_register (struct frame_info *frame,
extern void frame_read_unsigned_register (struct frame_info *frame,
int regnum, ULONGEST *val);
+/* The reverse. Store a register value relative to the specified
+ frame. Note: this call makes the frame's state undefined. The
+ register and frame caches must be flushed. */
+extern void put_frame_register (struct frame_info *frame, int regnum,
+ const void *buf);
+
/* Map between a frame register number and its name. A frame register
space is a superset of the cooked register space --- it also
includes builtin registers. If NAMELEN is negative, use the NAME's
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 7c0a8fd..3d129cd 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -990,8 +990,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
#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 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
/* 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, v)",
+ XSTRING (REGISTER_TO_VALUE (frame, regnum, v)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -2636,8 +2636,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
/* 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)));
+ "VALUE_TO_REGISTER(frame, v)",
+ XSTRING (VALUE_TO_REGISTER (frame, v)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -4114,7 +4114,7 @@ set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch,
}
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_convert_register_p (struct gdbarch *gdbarch, int regnum)
"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 @@ set_gdbarch_convert_register_p (struct gdbarch *gdbarch,
}
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 value *v)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->register_to_value == 0)
@@ -4141,7 +4141,7 @@ gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *typ
"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, v);
}
void
@@ -4152,7 +4152,7 @@ set_gdbarch_register_to_value (struct gdbarch *gdbarch,
}
void
-gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to)
+gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, struct value *v)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->value_to_register == 0)
@@ -4160,7 +4160,7 @@ gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnu
"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);
+ gdbarch->value_to_register (frame, v);
}
void
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 9678f4f..7920bba 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1451,47 +1451,47 @@ extern void set_gdbarch_register_convert_to_raw (struct gdbarch *gdbarch, gdbarc
/* 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, v) (legacy_register_to_value (frame, regnum, v))
#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 value *v);
+extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct value *v);
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, v) (gdbarch_register_to_value (current_gdbarch, frame, regnum, v))
#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))
+#define VALUE_TO_REGISTER(frame, v) (legacy_value_to_register (frame, v))
#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);
+typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, struct value *v);
+extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, struct value *v);
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 !defined (VALUE_TO_REGISTER)
-#define VALUE_TO_REGISTER(type, regnum, from, to) (gdbarch_value_to_register (current_gdbarch, type, regnum, from, to))
+#define VALUE_TO_REGISTER(frame, v) (gdbarch_value_to_register (current_gdbarch, frame, v))
#endif
/* Default (function) for non- multi-arch platforms. */
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 006ec96..c577ba0 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -557,9 +557,9 @@ f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_c
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
+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 value *v:frame, regnum, v::0:legacy_register_to_value::0
+f:1:VALUE_TO_REGISTER:void:value_to_register:struct frame_info *frame, struct value *v:frame, v::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
f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 7bc4aeb..2f2cc2f 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -634,36 +634,33 @@ mips_register_convert_to_raw (struct type *virtual_type, int n,
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_convert_to_type (int regnum, struct type *type, char *buffer)
+mips_register_to_value (struct frame_info *frame, int regnum,
+ struct value *v)
{
- 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);
- }
+ frame_read_register (frame, regnum + 0, VALUE_CONTENTS_RAW (v) + 4);
+ frame_read_register (frame, regnum + 1, VALUE_CONTENTS_RAW (v) + 0);
+ VALUE_LVAL (v) = lval_reg_frame_relative;
+ VALUE_FRAME_ID (v) = get_frame_id (frame);
+ VALUE_FRAME_REGNUM (v) = regnum;
}
void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct frame_info *frame, struct value *v)
{
-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);
- }
+ int regnum = VALUE_FRAME_REGNUM (v);
+ put_frame_register (frame, regnum + 0, VALUE_CONTENTS (v) + 4);
+ put_frame_register (frame, regnum + 1, VALUE_CONTENTS (v) + 0);
}
/* Return the GDB type object for the "standard" data type
@@ -5966,6 +5963,9 @@ mips_gdbarch_init (struct gdbarch_info info,
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,
diff --git a/gdb/valops.c b/gdb/valops.c
index e6fb6c8..1115bdf 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -496,22 +496,6 @@ value_assign (struct value *toval, struct value *fromval)
COERCE_ARRAY (fromval);
CHECK_TYPEDEF (type);
- /* If TOVAL is a special machine register requiring conversion
- of program values to a special raw format,
- convert FROMVAL's contents now, with result in `raw_buffer',
- and set USE_BUFFER to the number of bytes to write. */
-
- if (VALUE_REGNO (toval) >= 0)
- {
- int regno = VALUE_REGNO (toval);
- if (CONVERT_REGISTER_P (regno))
- {
- struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
- VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
- use_buffer = REGISTER_RAW_SIZE (regno);
- }
- }
-
/* Since modifying a register can trash the frame chain, and modifying memory
can trash the frame cache, we save the old frame and then restore the new
frame afterwards. */
@@ -585,17 +569,8 @@ value_assign (struct value *toval, struct value *fromval)
case lval_reg_frame_relative:
case lval_register:
{
- /* value is stored in a series of registers in the frame
- specified by the structure. Copy that value out, modify
- it, and copy it back in. */
- int amount_copied;
- int amount_to_copy;
- char *buffer;
- int value_reg;
- int reg_offset;
- int byte_offset;
- int regno;
struct frame_info *frame;
+ int value_reg;
/* Figure out which frame this is in currently. */
if (VALUE_LVAL (toval) == lval_register)
@@ -611,92 +586,78 @@ value_assign (struct value *toval, struct value *fromval)
if (!frame)
error ("Value being assigned to is no longer active.");
-
- /* Locate the first register that falls in the value that
- needs to be transfered. Compute the offset of the value in
- that register. */
- {
- int offset;
- for (reg_offset = value_reg, offset = 0;
- offset + REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
- reg_offset++);
- byte_offset = VALUE_OFFSET (toval) - offset;
- }
-
- /* Compute the number of register aligned values that need to
- be copied. */
- if (VALUE_BITSIZE (toval))
- amount_to_copy = byte_offset + 1;
- else
- amount_to_copy = byte_offset + TYPE_LENGTH (type);
-
- /* And a bounce buffer. Be slightly over generous. */
- buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
-
- /* Copy it in. */
- for (regno = reg_offset, amount_copied = 0;
- amount_copied < amount_to_copy;
- amount_copied += REGISTER_RAW_SIZE (regno), regno++)
- {
- frame_register_read (frame, regno, buffer + amount_copied);
- }
- /* Modify what needs to be modified. */
- if (VALUE_BITSIZE (toval))
- {
- modify_field (buffer + byte_offset,
- value_as_long (fromval),
- VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
- }
- else if (use_buffer)
+ if (CONVERT_REGISTER_P (VALUE_REGNO (toval), VALUE_TYPE (toval)))
{
- memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
+ /* If TOVAL is a special machine register requiring
+ conversion of program values to a special raw format,
+ convert FROMVAL's contents now, with result in
+ `raw_buffer', and set USE_BUFFER to the number of bytes
+ to write. Let VALUE_TO_REGISTER sort out the mess. */
+ VALUE_TO_REGISTER (frame, fromval);
}
else
{
- memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
- TYPE_LENGTH (type));
- /* Do any conversion necessary when storing this type to
- more than one register. */
-#ifdef REGISTER_CONVERT_FROM_TYPE
- REGISTER_CONVERT_FROM_TYPE (value_reg, type,
- (buffer + byte_offset));
-#endif
- }
+ /* TOVAL is stored in a series of registers in the frame
+ specified by the structure. Copy that value out,
+ modify it, and copy it back in. */
+ int amount_copied;
+ int amount_to_copy;
+ char *buffer;
+ int reg_offset;
+ int byte_offset;
+ int regno;
+
+ /* Locate the first register that falls in the value that
+ needs to be transfered. Compute the offset of the
+ value in that register. */
+ {
+ int offset;
+ for (reg_offset = value_reg, offset = 0;
+ offset + REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
+ reg_offset++);
+ byte_offset = VALUE_OFFSET (toval) - offset;
+ }
- /* Copy it out. */
- for (regno = reg_offset, amount_copied = 0;
- amount_copied < amount_to_copy;
- amount_copied += REGISTER_RAW_SIZE (regno), regno++)
- {
- enum lval_type lval;
- CORE_ADDR addr;
- int optim;
- int realnum;
+ /* Compute the number of register aligned values that need
+ to be copied. */
+ if (VALUE_BITSIZE (toval))
+ amount_to_copy = byte_offset + 1;
+ else
+ amount_to_copy = byte_offset + TYPE_LENGTH (type);
- /* Just find out where to put it. */
- frame_register (frame, regno, &optim, &lval, &addr, &realnum,
- NULL);
+ /* And a bounce buffer. Be slightly over generous. */
+ buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
+
+ /* Copy it in. */
+ for (regno = reg_offset, amount_copied = 0;
+ amount_copied < amount_to_copy;
+ amount_copied += REGISTER_RAW_SIZE (regno), regno++)
+ frame_register_read (frame, regno, buffer + amount_copied);
- if (optim)
- error ("Attempt to assign to a value that was optimized out.");
- if (lval == lval_memory)
- write_memory (addr, buffer + amount_copied,
- REGISTER_RAW_SIZE (regno));
- else if (lval == lval_register)
- regcache_cooked_write (current_regcache, realnum,
- (buffer + amount_copied));
+ /* Modify what needs to be modified. */
+ if (VALUE_BITSIZE (toval))
+ modify_field (buffer + byte_offset,
+ value_as_long (fromval),
+ VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
+ else if (use_buffer)
+ memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
else
- error ("Attempt to assign to an unmodifiable value.");
- }
+ memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
+ TYPE_LENGTH (type));
+ /* Copy it out. */
+ for (regno = reg_offset, amount_copied = 0;
+ amount_copied < amount_to_copy;
+ amount_copied += REGISTER_RAW_SIZE (regno), regno++)
+ put_frame_register (frame, regno, buffer + amount_copied);
+
+ }
if (register_changed_hook)
register_changed_hook (-1);
target_changed_event ();
-
+ break;
}
- break;
-
default:
error ("Left operand of assignment is not an lvalue.");