aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2007-09-25 16:08:17 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2007-09-25 16:08:17 +0000
commitb18bb924a22f7be9eba419397593835fa4439d03 (patch)
tree940507fa4176691c7ec15b4a130dff6186858c4d /gdb
parent2d7b968704e993c5c3a37a997a1a55f630174be3 (diff)
downloadgdb-b18bb924a22f7be9eba419397593835fa4439d03.zip
gdb-b18bb924a22f7be9eba419397593835fa4439d03.tar.gz
gdb-b18bb924a22f7be9eba419397593835fa4439d03.tar.bz2
* mips-tdep.c (mips_n32n64_return_value): Per N32/N64 ABI
rules return composite types in registers as appropriate.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/mips-tdep.c33
2 files changed, 33 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 326694b..322c909 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2007-09-24 Jim Blandy <jimb@codesourcery.com>
* symfile.h (struct symfile_segment_data): Doc fixes.
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 332387a..8392d10 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -3076,9 +3076,30 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
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 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
&& 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)
{