summaryrefslogtreecommitdiff
path: root/gdb/sparc-tdep.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2003-05-25 11:58:08 +0000
committerMark Kettenis <kettenis@gnu.org>2003-05-25 11:58:08 +0000
commit4ab8e5d91d97786772b901fdb24133f5c65fff54 (patch)
tree8da06887e81b4a3f4ec93a5aff920976cc55d0cb /gdb/sparc-tdep.c
parent437d5f8e88cf12c4e30af3d6aa0da1e9ac39c1b5 (diff)
downloadgdb-4ab8e5d91d97786772b901fdb24133f5c65fff54.tar.gz
* 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.
Diffstat (limited to 'gdb/sparc-tdep.c')
-rw-r--r--gdb/sparc-tdep.c140
1 files changed, 109 insertions, 31 deletions
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 6735b0814ee..64271128d7b 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)
+ {
+ 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
+ internal_error (__FILE__, __LINE__,
+ "Cannot extract return value of %d bytes long.", len);
+}
+
+/* Write into REGBUF a function return value VALBUF of type TYPE. */
+
+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)
- memcpy (valbuf, &regbuf[REGISTER_BYTE (FP0_REGNUM)], typelen);
+ {
+ 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
- memcpy (valbuf,
- &regbuf[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);
}
+/* Extract from REGCACHE the address in which a function should return
+ its structure value. */
-/* 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. */
+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