2003-06-14 Andrew Cagney <cagney@redhat.com>

Mark Kettenis  <kettenis@gnu.org>

	* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
	(REGISTER_TO_VALUE, VALUE_TO_REGISTER): Replace raw buffer
	parameter with "frame".
	* gdbarch.h, gdbarch.c: Re-generate.
	* frame.h (put_frame_register): Declare.
	* frame.c (put_frame_register): New function.
	* arch-utils.c (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.
	* 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.
	* 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.
	* i386-tdep.c (I386_EBX_REGNUM, I386_ECX_REGNUM, I386_ESI_REGNUM,
	I386_EDI_REGNUM): New defines.
	(i386_next_regnum, i386_convert_register_p,
	i386_register_to_value, i386_value_to_register): New functions.
	(i386_register_convertible, i386_register_convert_to_virtual,
	i386_convert_to_raw): Remove functions.
	(i386_gdbarch_init): Set convert_register_p, register_to_value and
	value_to_register instead of register_convertible,
	register_convert_to_virtual and register_convert_to_raw.
	* 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.
	* alpha-tdep.c (alpha_convert_register_p): Update.
	(alpha_value_to_register): Update, store the register.
	(alpha_register_to_value): Update, fetch the register.
This commit is contained in:
Andrew Cagney 2003-06-14 22:35:25 +00:00
parent 81a58f5b70
commit ff2e87acc7
13 changed files with 401 additions and 382 deletions

View File

@ -1,3 +1,43 @@
2003-06-14 Andrew Cagney <cagney@redhat.com>
Mark Kettenis <kettenis@gnu.org>
* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
(REGISTER_TO_VALUE, VALUE_TO_REGISTER): Replace raw buffer
parameter with "frame".
* gdbarch.h, gdbarch.c: Re-generate.
* frame.h (put_frame_register): Declare.
* frame.c (put_frame_register): New function.
* arch-utils.c (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.
* 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.
* 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.
* i386-tdep.c (I386_EBX_REGNUM, I386_ECX_REGNUM, I386_ESI_REGNUM,
I386_EDI_REGNUM): New defines.
(i386_next_regnum, i386_convert_register_p,
i386_register_to_value, i386_value_to_register): New functions.
(i386_register_convertible, i386_register_convert_to_virtual,
i386_convert_to_raw): Remove functions.
(i386_gdbarch_init): Set convert_register_p, register_to_value and
value_to_register instead of register_convertible,
register_convert_to_virtual and register_convert_to_raw.
* 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.
* alpha-tdep.c (alpha_convert_register_p): Update.
(alpha_value_to_register): Update, store the register.
(alpha_register_to_value): Update, fetch the register.
2003-06-14 Theodore A. Roth <troth@openavr.org>
* avr-tdep.c (avr_remote_translate_xfer_address): Delete function.

View File

@ -206,14 +206,17 @@ alpha_sts (void *out, const void *in)
registers is different. */
static int
alpha_convert_register_p (int regno)
alpha_convert_register_p (int regno, struct type *type)
{
return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
}
static void
alpha_register_to_value (int regnum, struct type *valtype, char *in, char *out)
alpha_register_to_value (struct frame_info *frame, int regnum,
struct type *valtype, void *out)
{
char in[MAX_REGISTER_SIZE];
frame_register_read (frame, regnum, in);
switch (TYPE_LENGTH (valtype))
{
case 4:
@ -228,8 +231,10 @@ alpha_register_to_value (int regnum, struct type *valtype, char *in, char *out)
}
static void
alpha_value_to_register (struct type *valtype, int regnum, char *in, char *out)
alpha_value_to_register (struct frame_info *frame, int regnum,
struct type *valtype, const void *in)
{
char out[MAX_REGISTER_SIZE];
switch (TYPE_LENGTH (valtype))
{
case 4:
@ -241,6 +246,7 @@ alpha_value_to_register (struct type *valtype, int regnum, char *in, char *out)
default:
error ("Cannot store value in floating point register");
}
put_frame_register (frame, regnum, out);
}

View File

@ -440,23 +440,29 @@ 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 DEPRECATED_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 *to)
{
char from[MAX_REGISTER_SIZE];
frame_read_register (frame, regnum, from);
DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
}
void
legacy_value_to_register (struct type *type, int regnum,
char *from, char *to)
legacy_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const void *tmp)
{
char to[MAX_REGISTER_SIZE];
char *from = alloca (TYPE_LENGTH (type));
memcpy (from, from, TYPE_LENGTH (type));
DEPRECATED_REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
put_frame_register (frame, regnum, to);
}

View File

@ -160,9 +160,11 @@ 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 type *type, void *to);
extern void legacy_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const void *from);
/* For compatibility with older architectures, returns
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid

View File

@ -624,145 +624,75 @@ 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))
{
/* 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, type, VALUE_CONTENTS_RAW (v));
VALUE_LVAL (v) = lval_reg_frame_relative;
VALUE_FRAME_ID (v) = get_frame_id (frame);
VALUE_FRAME_REGNUM (v) = regnum;
}
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 +711,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;
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);
}
/* 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);
}
return v;
}
/* Given a struct symbol for a variable or function,
and a stack frame id,

View File

@ -673,6 +673,36 @@ frame_read_signed_register (struct frame_info *frame, int regnum,
frame_unwind_signed_register (frame->next, regnum, val);
}
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
deprecated_unwind_get_saved_register (char *raw_buffer,
int *optimizedp,

View File

@ -332,6 +332,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

View File

@ -989,8 +989,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",
@ -2148,8 +2148,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, type, buf)",
XSTRING (REGISTER_TO_VALUE (frame, regnum, type, buf)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@ -2670,8 +2670,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, regnum, type, buf)",
XSTRING (VALUE_TO_REGISTER (frame, regnum, type, buf)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@ -4335,7 +4335,7 @@ set_gdbarch_deprecated_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)
@ -4343,7 +4343,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
@ -4354,7 +4354,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 type *type, void *buf)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->register_to_value == 0)
@ -4362,7 +4362,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, type, buf);
}
void
@ -4373,7 +4373,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, int regnum, struct type *type, const void *buf)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->value_to_register == 0)
@ -4381,7 +4381,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, regnum, type, buf);
}
void

View File

@ -1688,47 +1688,47 @@ extern void set_gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdba
/* 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. */
#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, regnum, type, buf) (legacy_value_to_register (frame, regnum, type, buf))
#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, int regnum, struct type *type, const void *buf);
extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const void *buf);
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, regnum, type, buf) (gdbarch_value_to_register (current_gdbarch, frame, regnum, type, buf))
#endif
/* Default (function) for non- multi-arch platforms. */

View File

@ -585,9 +585,9 @@ f:2:DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL:void:deprecated_register_convert_to_v
# For raw <-> cooked register conversions, replaced by pseudo registers.
f:2:DEPRECATED_REGISTER_CONVERT_TO_RAW:void:deprecated_register_convert_to_raw:struct type *type, int regnum, const 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 type *type, void *buf:frame, regnum, type, buf::0:legacy_register_to_value::0
f:1:VALUE_TO_REGISTER:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const void *buf:frame, regnum, type, buf::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

View File

@ -1324,65 +1324,148 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
else
regcache_raw_write (regcache, regnum, buf);
}
/* Return true iff register REGNUM's virtual format is different from
its raw format. Note that this definition assumes that the host
supports IEEE 32-bit floats, since it doesn't say that SSE
registers need conversion. Even if we can't find a counterexample,
this is still sloppy. */
/* These registers don't have pervasive standard uses. Move them to
i386-tdep.h if necessary. */
#define I386_EBX_REGNUM 3 /* %ebx */
#define I386_ECX_REGNUM 1 /* %ecx */
#define I386_ESI_REGNUM 6 /* %esi */
#define I386_EDI_REGNUM 7 /* %edi */
/* Return the register number of the register allocated by GCC after
REGNUM, or -1 if there is no such register. */
static int
i386_register_convertible (int regnum)
i386_next_regnum (int regnum)
{
/* GCC allocates the registers in the order:
%eax, %edx, %ecx, %ebx, %esi, %edi, %ebp, %esp, ...
Since storing a variable in %esp doesn't make any sense we return
-1 for %ebp and for %esp itself. */
static int next_regnum[] =
{
I386_EDX_REGNUM, /* Slot for %eax. */
I386_EBX_REGNUM, /* Slot for %ecx. */
I386_ECX_REGNUM, /* Slot for %edx. */
I386_ESI_REGNUM, /* Slot for %ebx. */
-1, -1, /* Slots for %esp and %ebp. */
I386_EDI_REGNUM, /* Slot for %esi. */
I386_EBP_REGNUM /* Slot for %edi. */
};
if (regnum < sizeof (next_regnum) / sizeof (next_regnum[0]))
return next_regnum[regnum];
return -1;
}
/* Return nonzero if a value of type TYPE stored in register REGNUM
needs any special handling. */
static int
i386_convert_register_p (int regnum, struct type *type)
{
/* Values may be spread across multiple registers. Most debugging
formats aren't expressive enough to specify the locations, so
some heuristics is involved. Right now we only handle types that
are exactly 8 bytes long as GCC doesn't seem to put any other
types into registers. */
if (TYPE_LENGTH (type) == 8 && i386_next_regnum (regnum) != -1)
return 1;
return i386_fp_regnum_p (regnum);
}
/* Convert data from raw format for register REGNUM in buffer FROM to
virtual format with type TYPE in buffer TO. */
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
return its contents in TO. */
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));
/* FIXME: kettenis/20030609: What should we do if REGNUM isn't
available in FRAME (i.e. if it wasn't saved)? */
/* 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[I386_MAX_REGISTER_SIZE];
/* 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);
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
warning ("Cannot convert floating-point register value "
"to non-floating-point type.");
return;
}
/* 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
{
gdb_assert (TYPE_LENGTH (type) == 8);
/* Read the first part. */
gdb_assert (register_size (current_gdbarch, regnum) == 4);
frame_read_register (frame, regnum, (char *) to + 0);
/* Read the second part. */
regnum = i386_next_regnum (regnum);
gdb_assert (regnum != -1);
gdb_assert (register_size (current_gdbarch, regnum));
frame_read_register (frame, regnum, (char *) to + 4);
}
}
/* Convert data from virtual format with type TYPE in buffer FROM to
raw format for register REGNUM in buffer TO. */
/* Write the contents FROM of a value of type TYPE into register
REGNUM in frame FRAME. */
static void
i386_register_convert_to_raw (struct type *type, int regnum,
const char *from, char *to)
i386_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const void *from)
{
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 non-floating-point type "
"to floating-point register value.");
memset (to, 0, TYPE_LENGTH (type));
return;
}
char to[I386_MAX_REGISTER_SIZE];
/* 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);
/* 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.");
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);
put_frame_register (frame, regnum, to);
}
else
{
gdb_assert (TYPE_LENGTH (type) == 8);
/* Write the first part. */
gdb_assert (register_size (current_gdbarch, regnum) == 4);
put_frame_register (frame, regnum, (const char *) from + 0);
/* Write the second part. */
regnum = i386_next_regnum (regnum);
gdb_assert (regnum != -1);
gdb_assert (register_size (current_gdbarch, regnum) == 4);
put_frame_register (frame, regnum, (const char *) from + 4);
}
}
#ifdef STATIC_TRANSFORM_NAME
/* SunPRO encodes the static variables. This is not related to C++
@ -1692,9 +1775,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Call dummy code. */
set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
set_gdbarch_deprecated_register_convertible (gdbarch, i386_register_convertible);
set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, i386_register_convert_to_virtual);
set_gdbarch_deprecated_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);

View File

@ -634,36 +634,30 @@ mips_register_convert_to_raw (struct type *virtual_type, int n,
TYPE_LENGTH (virtual_type));
}
void
mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
static int
mips_convert_register_p (int regnum, struct type *type)
{
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);
}
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_from_type (int regnum, struct type *type, char *buffer)
mips_register_to_value (struct frame_info *frame, int regnum,
struct type *type, void *to)
{
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, (char *) to + 4);
frame_read_register (frame, regnum + 1, (char *) to + 0);
}
void
mips_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const void *from)
{
put_frame_register (frame, regnum + 0, (const char *) from + 4);
put_frame_register (frame, regnum + 1, (const char *) from + 0);
}
/* Return the GDB type object for the "standard" data type

View File

@ -498,22 +498,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. */
@ -587,17 +571,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)
@ -613,92 +588,77 @@ 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))
if (VALUE_LVAL (toval) == lval_reg_frame_relative
&& CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))
{
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);
/* If TOVAL is a special machine register requiring
conversion of program values to a special raw format. */
VALUE_TO_REGISTER (frame, VALUE_FRAME_REGNUM (toval),
type, VALUE_CONTENTS (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;
/* 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;
/* Just find out where to put it. */
frame_register (frame, regno, &optim, &lval, &addr, &realnum,
NULL);
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));
/* 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
error ("Attempt to assign to an unmodifiable value.");
}
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)
memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
else
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.");