* sparc-tdep.c (SPARC_F0_REGNUM, SPARC_F1_REGNUM, SPARC_O0_REGNUM,
SPARC_O1_REGNUM): New defines. (sparc32_extract_return_value): Rewrite to operate on a regcache. (sparc32_store_return_value): New function. (sparc_extract_struct_value_address): Rewrite to operate on a regcache. (sparc_gdbarch_init): Don't set deprecated_extract_struct_value_address. Set extract_struct_value_address instead. Don't set deprecated_extract_return_value and deprecated_store_return_value for 32-bit targets. Set extract_return_value and store_return_value instead. * config/sparc/tm-sparc.h (DEPRECATED_STORE_RETURN_VALUE, DEPRECTAED_EXTRACT_RETURN_VALUE, DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS): Don't define these. (STORE_RETURN_VALUE, EXTRACT_RETURN_VALUE, EXTRACT_STRUCT_VALUE_ADDRESS): Define these instead. (sparc_store_return_value): Remove prototype. (sparc32_store_return_value): New prototype. (sparc32_extract_return_value, sparc_extract_struct_value_address): Adjust prototypes.
This commit is contained in:
parent
c9373d2edf
commit
44b7b84e51
3 changed files with 145 additions and 43 deletions
|
@ -1,3 +1,27 @@
|
|||
2003-05-25 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* sparc-tdep.c (SPARC_F0_REGNUM, SPARC_F1_REGNUM, SPARC_O0_REGNUM,
|
||||
SPARC_O1_REGNUM): New defines.
|
||||
(sparc32_extract_return_value): Rewrite to operate on a regcache.
|
||||
(sparc32_store_return_value): New function.
|
||||
(sparc_extract_struct_value_address): Rewrite to operate on a
|
||||
regcache.
|
||||
(sparc_gdbarch_init): Don't set
|
||||
deprecated_extract_struct_value_address. Set
|
||||
extract_struct_value_address instead. Don't set
|
||||
deprecated_extract_return_value and deprecated_store_return_value
|
||||
for 32-bit targets. Set extract_return_value and
|
||||
store_return_value instead.
|
||||
* config/sparc/tm-sparc.h (DEPRECATED_STORE_RETURN_VALUE,
|
||||
DEPRECTAED_EXTRACT_RETURN_VALUE,
|
||||
DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS): Don't define these.
|
||||
(STORE_RETURN_VALUE, EXTRACT_RETURN_VALUE,
|
||||
EXTRACT_STRUCT_VALUE_ADDRESS): Define these instead.
|
||||
(sparc_store_return_value): Remove prototype.
|
||||
(sparc32_store_return_value): New prototype.
|
||||
(sparc32_extract_return_value, sparc_extract_struct_value_address):
|
||||
Adjust prototypes.
|
||||
|
||||
2003-05-24 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* sparcnbsd-tdep.c: Include "gdb_string.h".
|
||||
|
|
|
@ -267,17 +267,16 @@ extern CORE_ADDR sparc_skip_prologue (CORE_ADDR);
|
|||
/* Write into appropriate registers a function return value of type
|
||||
TYPE, given in virtual format. */
|
||||
|
||||
#define DEPRECATED_STORE_RETURN_VALUE(TYPE, VALBUF) \
|
||||
sparc_store_return_value (TYPE, VALBUF)
|
||||
extern void sparc_store_return_value (struct type *, char *);
|
||||
#define STORE_RETURN_VALUE(TYPE, REGCACHE, VALBUF) \
|
||||
sparc32_store_return_value (TYPE, REGCACHE, VALBUF)
|
||||
extern void sparc32_store_return_value (struct type *, struct regcache *,
|
||||
const void *);
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
the address in which a function should return its structure value,
|
||||
as a CORE_ADDR (or an expression that can be used as one). */
|
||||
|
||||
#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
|
||||
sparc_extract_struct_value_address (REGBUF)
|
||||
/* Extract from REGCACHE the address in which a function should return
|
||||
its structure value. */
|
||||
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGCACHE) \
|
||||
sparc_extract_struct_value_address (REGCACHE)
|
||||
extern CORE_ADDR sparc_extract_struct_value_address (char *);
|
||||
|
||||
/* Stack must be aligned on 64-bit boundaries when synthesizing
|
||||
|
@ -668,9 +667,10 @@ extern CORE_ADDR sparc32_push_arguments (int, struct value **, CORE_ADDR, int,
|
|||
function return value of type TYPE, and copy that, in virtual
|
||||
format, into VALBUF. */
|
||||
|
||||
#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE, REGBUF, VALBUF) \
|
||||
sparc32_extract_return_value (TYPE, REGBUF, VALBUF)
|
||||
extern void sparc32_extract_return_value (struct type *, char[], char *);
|
||||
#define EXTRACT_RETURN_VALUE(TYPE, REGCACHE, VALBUF) \
|
||||
sparc32_extract_return_value (TYPE, REGCACHE, VALBUF)
|
||||
extern void sparc32_extract_return_value (struct type *, struct regcache *,
|
||||
void *valbuf);
|
||||
|
||||
#endif /* GDB_MULTI_ARCH */
|
||||
|
||||
|
|
140
gdb/sparc-tdep.c
140
gdb/sparc-tdep.c
|
@ -466,13 +466,6 @@ sparc_frame_chain (struct frame_info *frame)
|
|||
return ~ (CORE_ADDR) 0;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
sparc_extract_struct_value_address (char *regbuf)
|
||||
{
|
||||
return extract_address (regbuf + REGISTER_BYTE (O0_REGNUM),
|
||||
REGISTER_RAW_SIZE (O0_REGNUM));
|
||||
}
|
||||
|
||||
/* Find the pc saved in frame FRAME. */
|
||||
|
||||
CORE_ADDR
|
||||
|
@ -2282,33 +2275,117 @@ sparc32_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
|||
return sp;
|
||||
}
|
||||
|
||||
#define SPARC_F0_REGNUM FP0_REGNUM /* %f0 */
|
||||
#define SPARC_F1_REGNUM (FP0_REGNUM + 1)/* %f1 */
|
||||
#define SPARC_O0_REGNUM O0_REGNUM /* %o0 */
|
||||
#define SPARC_O1_REGNUM O1_REGNUM /* %o1 */
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
into VALBUF. */
|
||||
/* Extract from REGCACHE a function return value of type TYPE and copy
|
||||
that into VALBUF.
|
||||
|
||||
Note that REGCACHE specifies the register values for the frame of
|
||||
the calling function. This means that we need to fetch the value
|
||||
form %o0 and %o1, which correspond to %i0 and %i1 in the frame of
|
||||
the called function. */
|
||||
|
||||
void
|
||||
sparc32_extract_return_value (struct type *type, char *regbuf, char *valbuf)
|
||||
sparc32_extract_return_value (struct type *type, struct regcache *regcache,
|
||||
void *valbuf)
|
||||
{
|
||||
int typelen = TYPE_LENGTH (type);
|
||||
int regsize = REGISTER_RAW_SIZE (O0_REGNUM);
|
||||
int len = TYPE_LENGTH (type);
|
||||
char buf[8];
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
|
||||
memcpy (valbuf, ®buf[REGISTER_BYTE (FP0_REGNUM)], typelen);
|
||||
{
|
||||
if (len == 4 || len == 8)
|
||||
{
|
||||
regcache_cooked_read (regcache, SPARC_F0_REGNUM, buf);
|
||||
regcache_cooked_read (regcache, SPARC_F1_REGNUM, buf + 4);
|
||||
memcpy (valbuf, buf, len);
|
||||
return;
|
||||
}
|
||||
else
|
||||
memcpy (valbuf,
|
||||
®buf[O0_REGNUM * regsize +
|
||||
(typelen >= regsize
|
||||
|| TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE ? 0
|
||||
: regsize - typelen)],
|
||||
typelen);
|
||||
internal_error (__FILE__, __LINE__, "\
|
||||
Cannot extract floating-point return value of %d bytes long.", len);
|
||||
}
|
||||
|
||||
if (len <= 4)
|
||||
{
|
||||
regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
|
||||
memcpy (valbuf, buf + 4 - len, len);
|
||||
}
|
||||
else if (len <= 8)
|
||||
{
|
||||
regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
|
||||
regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
|
||||
memcpy (valbuf, buf + 8 - len, len);
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"Cannot extract return value of %d bytes long.", len);
|
||||
}
|
||||
|
||||
/* Write into REGBUF a function return value VALBUF of type TYPE. */
|
||||
|
||||
/* Write into appropriate registers a function return value
|
||||
of type TYPE, given in virtual format. On SPARCs with FPUs,
|
||||
float values are returned in %f0 (and %f1). In all other cases,
|
||||
values are returned in register %o0. */
|
||||
void
|
||||
sparc32_store_return_value (struct type *type, struct regcache *regcache,
|
||||
const void *valbuf)
|
||||
{
|
||||
int len = TYPE_LENGTH (type);
|
||||
char buf[8];
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT && SPARC_HAS_FPU)
|
||||
{
|
||||
const char *buf = valbuf;
|
||||
|
||||
if (len == 4)
|
||||
{
|
||||
regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
|
||||
return;
|
||||
}
|
||||
else if (len == 8)
|
||||
{
|
||||
regcache_cooked_write (regcache, SPARC_F0_REGNUM, buf);
|
||||
regcache_cooked_write (regcache, SPARC_F1_REGNUM, buf + 4);
|
||||
return;
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__, "\
|
||||
Cannot extract floating-point return value of %d bytes long.", len);
|
||||
}
|
||||
|
||||
/* Add leading zeros to the value. */
|
||||
memset (buf, 0, sizeof buf);
|
||||
|
||||
if (len <= 4)
|
||||
{
|
||||
memcpy (buf + 4 - len, valbuf, len);
|
||||
regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
|
||||
}
|
||||
else if (len <= 8)
|
||||
{
|
||||
memcpy (buf + 8 - len, valbuf, len);
|
||||
regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
|
||||
regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf);
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"Cannot extract return value of %d bytes long.", len);
|
||||
}
|
||||
|
||||
/* Extract from REGCACHE the address in which a function should return
|
||||
its structure value. */
|
||||
|
||||
CORE_ADDR
|
||||
sparc_extract_struct_value_address (struct regcache *regcache)
|
||||
{
|
||||
ULONGEST addr;
|
||||
|
||||
regcache_cooked_read_unsigned (regcache, SPARC_O0_REGNUM, &addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* FIXME: kettenis/2003/05/24: Still used for sparc64. */
|
||||
|
||||
void
|
||||
sparc_store_return_value (struct type *type, char *valbuf)
|
||||
|
@ -3164,7 +3241,8 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc);
|
||||
set_gdbarch_decr_pc_after_break (gdbarch, 0);
|
||||
set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
|
||||
set_gdbarch_deprecated_extract_struct_value_address (gdbarch, sparc_extract_struct_value_address);
|
||||
set_gdbarch_extract_struct_value_address (gdbarch,
|
||||
sparc_extract_struct_value_address);
|
||||
set_gdbarch_deprecated_fix_call_dummy (gdbarch, sparc_gdbarch_fix_call_dummy);
|
||||
set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
|
||||
set_gdbarch_deprecated_fp_regnum (gdbarch, SPARC_FP_REGNUM);
|
||||
|
@ -3379,11 +3457,11 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
switch (info.bfd_arch_info->mach)
|
||||
{
|
||||
case bfd_mach_sparc:
|
||||
set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
|
||||
set_gdbarch_num_regs (gdbarch, 72);
|
||||
set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
|
||||
set_gdbarch_register_name (gdbarch, sparc32_register_name);
|
||||
set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
|
||||
#if 0
|
||||
// OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
|
||||
#endif
|
||||
|
@ -3415,11 +3493,11 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
// OBSOLETE break;
|
||||
#endif
|
||||
case bfd_mach_sparc_v8plus:
|
||||
set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
|
||||
set_gdbarch_num_regs (gdbarch, 72);
|
||||
set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
|
||||
set_gdbarch_register_name (gdbarch, sparc32_register_name);
|
||||
set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
|
||||
tdep->print_insn_mach = bfd_mach_sparc;
|
||||
tdep->fp_register_bytes = 32 * 4;
|
||||
#if 0
|
||||
|
@ -3427,11 +3505,11 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
#endif
|
||||
break;
|
||||
case bfd_mach_sparc_v8plusa:
|
||||
set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
|
||||
set_gdbarch_num_regs (gdbarch, 72);
|
||||
set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
|
||||
set_gdbarch_register_name (gdbarch, sparc32_register_name);
|
||||
set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
|
||||
#if 0
|
||||
// OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue