From 44b7b84e5137ca6ce740af768707d2354546ca5e Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 25 May 2003 11:58:08 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 24 +++++++ gdb/config/sparc/tm-sparc.h | 24 +++---- gdb/sparc-tdep.c | 140 ++++++++++++++++++++++++++++-------- 3 files changed, 145 insertions(+), 43 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 058d587304..82f7234f13 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2003-05-25 Mark Kettenis + + * 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 * sparcnbsd-tdep.c: Include "gdb_string.h". diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h index ab18477fab..e51eb63217 100644 --- a/gdb/config/sparc/tm-sparc.h +++ b/gdb/config/sparc/tm-sparc.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 */ diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 6735b0814e..64271128d7 100644 --- a/gdb/sparc-tdep.c +++ b/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 + 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 - memcpy (valbuf, - ®buf[O0_REGNUM * regsize + - (typelen >= regsize - || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE ? 0 - : regsize - typelen)], - typelen); + 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