From: "Maciej W. Rozycki" <macro@mips.com>
To: gdb-patches@sourceware.org
Cc: Daniel Jacobowitz <drow@false.org>, David Ung <davidu@mips.com>,
"Maciej W. Rozycki" <macro@linux-mips.org>
Subject: mips-tdep.c: Fix new-ABI handling of composite return values
Date: Tue, 25 Sep 2007 14:50:00 -0000 [thread overview]
Message-ID: <Pine.LNX.4.61.0709251522080.6904@perivale.mips.com> (raw)
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)
{
next reply other threads:[~2007-09-25 14:50 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-25 14:50 Maciej W. Rozycki [this message]
2007-09-25 15:10 ` Daniel Jacobowitz
2007-09-25 15:48 ` Maciej W. Rozycki
2007-09-25 15:56 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.61.0709251522080.6904@perivale.mips.com \
--to=macro@mips.com \
--cc=davidu@mips.com \
--cc=drow@false.org \
--cc=gdb-patches@sourceware.org \
--cc=macro@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox