Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* mips-tdep.c: Fix new-ABI handling of composite return values
@ 2007-09-25 14:50 Maciej W. Rozycki
  2007-09-25 15:10 ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Maciej W. Rozycki @ 2007-09-25 14:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Daniel Jacobowitz, David Ung, Maciej W. Rozycki

Hello,

 Our current MIPS new-ABI code assumes the return convention for structs 
and unions is the same as for the old ABI, that is the value is returned 
via a reference.  This is incorrect.  Structs that consist of at most two 
floating point fields are returned in $f0 (and $f2 as required).  Any 
other struct or union of at most 128 bits in size is returned in $2 (and 
$3 as required).  Other composite types are returned via a reference.  A 
longer quotation from the original spec is included with the patch itself.

 Tested for n32 using the mipsisa32-sde-elf target, with the 
mips-sim-sde64/-mips64/-EB and mips-sim-sde64/-mips64/-EL boards, fixing 
104 regressions (of 189).

2007-09-25  David Ung  <davidu@mips.com>
            Maciej W. Rozycki  <macro@mips.com>

	* mips-tdep.c (mips_n32n64_return_value): Per N32/N64 ABI
	rules return composite types in registers as appropriate.

 Thanks, Daniel, for your recent fix for C++ pass/return by reference, 
BTW.  With that in place the change below does not trigger a regression in 
gdb.cp/bs15503.exp that would otherwise start happening.

 OK to apply?

  Maciej

12438.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2007-09-25 15:16:29.000000000 +0100
+++ binutils-quilt/src/gdb/mips-tdep.c	2007-09-25 15:17:38.000000000 +0100
@@ -3076,9 +3076,30 @@
 			  gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION
-      || TYPE_CODE (type) == TYPE_CODE_ARRAY
+
+  /* From MIPSpro N32 ABI Handbook, Document Number: 007-2816-004
+
+     Function results are returned in $2 (and $3 if needed), or $f0 (and $f2
+     if needed), as appropriate for the type.  Composite results (struct,
+     union, or array) are returned in $2/$f0 and $3/$f2 according to the
+     following rules:
+
+     * A struct with only one or two floating point fields is returned in $f0
+     (and $f2 if necessary).  This is a generalization of the Fortran COMPLEX
+     case.
+
+     * Any other struct or union results of at most 128 bits are returned in
+     $2 (first 64 bits) and $3 (remainder, if necessary).
+
+     * Larger composite results are handled by converting the function to a
+     procedure with an implicit first parameter, which is a pointer to an area
+     reserved by the caller to receive the result.  [The o32-bit ABI requires
+     that all composite results be handled by conversion to implicit first
+     parameters.  The MIPS/SGI Fortran implementation has always made a
+     specific exception to return COMPLEX results in the floating point
+     registers.]  */
+
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
       || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
     return RETURN_VALUE_STRUCT_CONVENTION;
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
@@ -3104,10 +3125,10 @@
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
+	   && TYPE_LENGTH (type) <= 8
 	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
-      /* A floating-point value belongs in the least significant part
-         of FP0.  */
+      /* Single or double floating-point value that fits in FP0.  */
       if (mips_debug)
 	fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
       mips_xfer_register (regcache,
@@ -3118,16 +3139,55 @@
 			  readbuf, writebuf, 0);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
+  else if (TYPE_CODE (type) == TYPE_CODE_FLT
+           && TYPE_LENGTH (type) == 16
+           && tdep->mips_fpu_type != MIPS_FPU_NONE)
+    {
+      /* A quad-precision floating-point value.  The most significant
+         part goes in FP2, and the least significant in FP0.  */
+      if (mips_debug)
+	fprintf_unfiltered (gdb_stderr, "Return float in $fp2/$fp0\n");
+      switch (gdbarch_byte_order (current_gdbarch))
+	{
+	case BFD_ENDIAN_LITTLE:
+	  mips_xfer_register (regcache,
+			      gdbarch_num_regs (current_gdbarch)
+			      + mips_regnum (current_gdbarch)->fp0 + 0,
+			      8, gdbarch_byte_order (current_gdbarch),
+			      readbuf, writebuf, 0);
+	  mips_xfer_register (regcache,
+			      gdbarch_num_regs (current_gdbarch)
+			      + mips_regnum (current_gdbarch)->fp0 + 2,
+			      8, gdbarch_byte_order (current_gdbarch),
+			      readbuf, writebuf, 8);
+	  break;
+	case BFD_ENDIAN_BIG:
+	  mips_xfer_register (regcache,
+			      gdbarch_num_regs (current_gdbarch)
+			      + mips_regnum (current_gdbarch)->fp0 + 2,
+			      8, gdbarch_byte_order (current_gdbarch),
+			      readbuf, writebuf, 0);
+	  mips_xfer_register (regcache,
+			      gdbarch_num_regs (current_gdbarch)
+			      + mips_regnum (current_gdbarch)->fp0 + 0,
+			      8, gdbarch_byte_order (current_gdbarch),
+			      readbuf, writebuf, 8);
+	  break;
+	default:
+	  internal_error (__FILE__, __LINE__, "bad switch");
+	}
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
 	   && TYPE_NFIELDS (type) <= 2
 	   && TYPE_NFIELDS (type) >= 1
 	   && ((TYPE_NFIELDS (type) == 1
-		&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
+     	        && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))
 		    == TYPE_CODE_FLT))
 	       || (TYPE_NFIELDS (type) == 2
-		   && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
+	           && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))
 		       == TYPE_CODE_FLT)
-		   && (TYPE_CODE (TYPE_FIELD_TYPE (type, 1))
+                   && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 1)))
 		       == TYPE_CODE_FLT)))
 	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mips-tdep.c: Fix new-ABI handling of composite return values
  2007-09-25 14:50 mips-tdep.c: Fix new-ABI handling of composite return values Maciej W. Rozycki
@ 2007-09-25 15:10 ` Daniel Jacobowitz
  2007-09-25 15:48   ` Maciej W. Rozycki
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2007-09-25 15:10 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gdb-patches, David Ung, Maciej W. Rozycki

On Tue, Sep 25, 2007 at 03:50:26PM +0100, Maciej W. Rozycki wrote:
> 2007-09-25  David Ung  <davidu@mips.com>
>             Maciej W. Rozycki  <macro@mips.com>
> 
> 	* mips-tdep.c (mips_n32n64_return_value): Per N32/N64 ABI
> 	rules return composite types in registers as appropriate.

128-bit long double is also handled in this patch - that's not a
composite type.  I think that's a merge error, though.  If you look
above the float / double block you'll find another copy of
128-bit long double support in HEAD.

>    else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
>  	   && TYPE_NFIELDS (type) <= 2
>  	   && TYPE_NFIELDS (type) >= 1
>  	   && ((TYPE_NFIELDS (type) == 1
> -		&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
> +     	        && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))

Funny indentation.  Is the only substantive change in this patch the
new calls to check_typedef?

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mips-tdep.c: Fix new-ABI handling of composite return values
  2007-09-25 15:10 ` Daniel Jacobowitz
@ 2007-09-25 15:48   ` Maciej W. Rozycki
  2007-09-25 15:56     ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Maciej W. Rozycki @ 2007-09-25 15:48 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches, David Ung, Maciej W. Rozycki

On Tue, 25 Sep 2007, Daniel Jacobowitz wrote:

> 128-bit long double is also handled in this patch - that's not a
> composite type.  I think that's a merge error, though.  If you look
> above the float / double block you'll find another copy of
> 128-bit long double support in HEAD.

 Oops! -- I have missed this bit indeed.

> >    else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
> >  	   && TYPE_NFIELDS (type) <= 2
> >  	   && TYPE_NFIELDS (type) >= 1
> >  	   && ((TYPE_NFIELDS (type) == 1
> > -		&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
> > +     	        && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))
> 
> Funny indentation.  Is the only substantive change in this patch the

 Fixed.

> new calls to check_typedef?

 Of course not.  This bit matters much too:

-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION
-      || TYPE_CODE (type) == TYPE_CODE_ARRAY
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY

 Here's an updated version.

2007-09-25  David Ung  <davidu@mips.com>
            Maciej W. Rozycki  <macro@mips.com>

	* mips-tdep.c (mips_n32n64_return_value): Per N32/N64 ABI
	rules return composite types in registers as appropriate.

 OK to apply?

  Maciej

12438.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c	2007-09-25 16:42:08.000000000 +0100
+++ binutils-quilt/src/gdb/mips-tdep.c	2007-09-25 16:43:43.000000000 +0100
@@ -3076,9 +3076,30 @@
 			  gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
-      || TYPE_CODE (type) == TYPE_CODE_UNION
-      || TYPE_CODE (type) == TYPE_CODE_ARRAY
+
+  /* From MIPSpro N32 ABI Handbook, Document Number: 007-2816-004
+
+     Function results are returned in $2 (and $3 if needed), or $f0 (and $f2
+     if needed), as appropriate for the type.  Composite results (struct,
+     union, or array) are returned in $2/$f0 and $3/$f2 according to the
+     following rules:
+
+     * A struct with only one or two floating point fields is returned in $f0
+     (and $f2 if necessary).  This is a generalization of the Fortran COMPLEX
+     case.
+
+     * Any other struct or union results of at most 128 bits are returned in
+     $2 (first 64 bits) and $3 (remainder, if necessary).
+
+     * Larger composite results are handled by converting the function to a
+     procedure with an implicit first parameter, which is a pointer to an area
+     reserved by the caller to receive the result.  [The o32-bit ABI requires
+     that all composite results be handled by conversion to implicit first
+     parameters.  The MIPS/SGI Fortran implementation has always made a
+     specific exception to return COMPLEX results in the floating point
+     registers.]  */
+
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY
       || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
     return RETURN_VALUE_STRUCT_CONVENTION;
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
@@ -3122,12 +3143,12 @@
 	   && TYPE_NFIELDS (type) <= 2
 	   && TYPE_NFIELDS (type) >= 1
 	   && ((TYPE_NFIELDS (type) == 1
-		&& (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
+		&& (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))
 		    == TYPE_CODE_FLT))
 	       || (TYPE_NFIELDS (type) == 2
-		   && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0))
+		   && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 0)))
 		       == TYPE_CODE_FLT)
-		   && (TYPE_CODE (TYPE_FIELD_TYPE (type, 1))
+		   && (TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type, 1)))
 		       == TYPE_CODE_FLT)))
 	   && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: mips-tdep.c: Fix new-ABI handling of composite return values
  2007-09-25 15:48   ` Maciej W. Rozycki
@ 2007-09-25 15:56     ` Daniel Jacobowitz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2007-09-25 15:56 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: gdb-patches, David Ung, Maciej W. Rozycki

On Tue, Sep 25, 2007 at 04:48:06PM +0100, Maciej W. Rozycki wrote:
>  Of course not.  This bit matters much too:

Oh, of course.

> 2007-09-25  David Ung  <davidu@mips.com>
>             Maciej W. Rozycki  <macro@mips.com>
> 
> 	* mips-tdep.c (mips_n32n64_return_value): Per N32/N64 ABI
> 	rules return composite types in registers as appropriate.
> 
>  OK to apply?

Yes thanks.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-09-25 15:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-25 14:50 mips-tdep.c: Fix new-ABI handling of composite return values Maciej W. Rozycki
2007-09-25 15:10 ` Daniel Jacobowitz
2007-09-25 15:48   ` Maciej W. Rozycki
2007-09-25 15:56     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox