This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips_eabi_return_value patch, updated


At <http://sourceware.org/ml/gdb-patches/2006-05/msg00490.html>,
Michael Snyder posted a patch to improve handling of function returns
for MIPS EABI.  This was in fact approved
<http://sourceware.org/ml/gdb-patches/2006-06/msg00103.html>, but not
committed; there was some discussion of possible further issues that
tailed off.

I've updated this patch for the various changes in GDB interfaces in
the past two years, and tested for mipsisa64-elf where it reduces the
number of test failures (for one multilib) from 501 to 135.  OK to commit?

There may be further issues remaining with EABI function return
handling - Adam Nemet has a further patch on top of this patch of
Michael Snyder's.  But I hope we can start by getting this patch in as
a basis for any further improvements.

2008-05-21  Michael Snyder  <msnyder@redhat.com>
            Joseph Myers  <joseph@codesourcery.com>

	* mips-tdep.c (mips_eabi_return_value): Replace stub that always
	returned RETURN_VALUE_STRUCT_CONVENTION with a real function.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.474
diff -u -r1.474 mips-tdep.c
--- mips-tdep.c	16 May 2008 00:27:23 -0000	1.474
+++ mips-tdep.c	21 May 2008 15:15:56 -0000
@@ -2956,10 +2956,59 @@
 			struct type *type, struct regcache *regcache,
 			gdb_byte *readbuf, const gdb_byte *writebuf)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int fp_return_type = 0;
+  int offset, regnum, xfer;
+
   if (TYPE_LENGTH (type) > 2 * mips_abi_regsize (gdbarch))
     return RETURN_VALUE_STRUCT_CONVENTION;
-  if (readbuf)
-    memset (readbuf, 0, TYPE_LENGTH (type));
+
+  /* Floating point type?  */
+  if (tdep->mips_fpu_type != MIPS_FPU_NONE)
+    {
+      if (TYPE_CODE (type) == TYPE_CODE_FLT)
+	fp_return_type = 1;
+      /* Structs with a single field of float type 
+	 are returned in a floating point register.  */
+      if ((TYPE_CODE (type) == TYPE_CODE_STRUCT
+	   || TYPE_CODE (type) == TYPE_CODE_UNION)
+	  && TYPE_NFIELDS (type) == 1)
+	{
+	  struct type *fieldtype = TYPE_FIELD_TYPE (type, 0);
+
+	  if (TYPE_CODE (check_typedef (fieldtype)) == TYPE_CODE_FLT)
+	    fp_return_type = 1;
+	}
+    }
+
+  if (fp_return_type)      
+    {
+      /* A floating-point value belongs in the least significant part
+	 of FP0/FP1.  */
+      if (mips_debug)
+	fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
+      regnum = mips_regnum (gdbarch)->fp0;
+    }
+  else 
+    {
+      /* An integer value goes in V0/V1.  */
+      if (mips_debug)
+	fprintf_unfiltered (gdb_stderr, "Return scalar in $v0\n");
+      regnum = MIPS_V0_REGNUM;
+    }
+  for (offset = 0;
+       offset < TYPE_LENGTH (type);
+       offset += mips_abi_regsize (gdbarch), regnum++)
+    {
+      xfer = mips_abi_regsize (gdbarch);
+      if (offset + xfer > TYPE_LENGTH (type))
+	xfer = TYPE_LENGTH (type) - offset;
+      mips_xfer_register (gdbarch, regcache,
+			  gdbarch_num_regs (gdbarch) + regnum, xfer,
+			  gdbarch_byte_order (gdbarch), readbuf, writebuf,
+			  offset);
+    }
+
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]