[RFA] sh-tdep.c: Introduce extracting struct value

Corinna Vinschen vinschen@redhat.com
Wed Oct 20 11:25:00 GMT 2004


Hi,

this patch eliminates the superfluous deprecated_extract_struct_value_address
functionality and adds the appropriate functionality to sh_return_value_foo.

In the Renesas ABI, the address where the struct return value has to be
written to is stored on the stack by the caller and not overwritten by
the callee.  This is taken into account by the new function
sh_extract_struct_value which is called by sh_return_value_foo.
In the gcc ABI case the function just returns RETURN_VALUE_STRUCT_CONVENTION.
The code which extracts the struct value in the gcc ABI case is kept in a
comment for documentary purposes.  It shows how to extract the struct return
value if the gcc ABI would guarantee that the struct return address (in R2)
would not be overwritten.


Corinna


	* sh-tdep.c (sh_extract_struct_value_address): Remove.
	(sh_extract_struct_value): New function.
	(sh_return_value_nofpu): Call sh_extract_struct_value in case of
	struct return condition.
	(sh_return_value_fpu): Ditto.
	(sh_gdbarch_init): Drop to set sh_extract_struct_value_address as
	gdbarch_deprecated_extract_struct_value_address function.

--- sh-tdep.c.PRE-USE-CC-2	2004-10-20 12:03:56.000000000 +0200
+++ sh-tdep.c	2004-10-20 12:12:42.000000000 +0200
@@ -847,18 +847,6 @@ sh_use_struct_convention_nofpu (struct t
   return sh_use_struct_convention_fpu (functype, type);
 }
 
-/* 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).  */
-static CORE_ADDR
-sh_extract_struct_value_address (struct regcache *regcache)
-{
-  ULONGEST addr;
-
-  regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
-  return addr;
-}
-
 static CORE_ADDR
 sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
 {
@@ -1333,13 +1321,45 @@ sh_store_return_value_fpu (struct type *
     sh_store_return_value_nofpu (type, regcache, valbuf);
 }
 
+/* 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).  */
+static enum return_value_convention
+sh_extract_struct_value (struct regcache *regcache, struct type *functype,
+			 struct type *type, void *readbuf)
+{
+  ULONGEST addr;
+
+  if (sh_effective_calling_convention (functype) == sh_cc_renesas)
+    {
+      if (readbuf)
+	{
+	  regcache_cooked_read_unsigned (regcache, SP_REGNUM, &addr);
+	  addr = read_memory_unsigned_integer (addr, 4);
+	  read_memory (addr, readbuf, TYPE_LENGTH (type));
+       }
+      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+    }
+  
+#if 0
+  /* In a perfect gcc world: */
+  if (readbuf)
+    {
+      regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
+      read_memory (addr, readbuf, TYPE_LENGTH (type));
+    }
+  return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+#endif
+  return RETURN_VALUE_STRUCT_CONVENTION;
+}
+
 static enum return_value_convention
 sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *functype,
 		       struct type *type, struct regcache *regcache,
 		       void *readbuf, const void *writebuf)
 {
   if (sh_use_struct_convention_nofpu (functype, type))
-    return RETURN_VALUE_STRUCT_CONVENTION;
+    return sh_extract_struct_value (regcache, functype, type, readbuf);
   if (writebuf)
     sh_store_return_value_nofpu (type, regcache, writebuf);
   else if (readbuf)
@@ -1353,7 +1373,7 @@ sh_return_value_fpu (struct gdbarch *gdb
 		     void *readbuf, const void *writebuf)
 {
   if (sh_use_struct_convention_fpu (functype, type))
-    return RETURN_VALUE_STRUCT_CONVENTION;
+    return sh_extract_struct_value (regcache, functype, type, readbuf);
   if (writebuf)
     sh_store_return_value_fpu (type, regcache, writebuf);
   else if (readbuf)
@@ -2671,8 +2691,6 @@ sh_gdbarch_init (struct gdbarch_info inf
   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
 
   set_gdbarch_return_value (gdbarch, sh_return_value_nofpu);
-  set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
-					    sh_extract_struct_value_address);
 
   set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.



More information about the Gdb-patches mailing list