aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Fish <fnf@specifix.com>2006-05-05 17:50:33 +0000
committerFred Fish <fnf@specifix.com>2006-05-05 17:50:33 +0000
commit7a076fd259bad195b86f1acc207993d342997cf1 (patch)
treebd3f322edc11e9c0f1506617f250ba88a123c0ab
parent731608473ad5f49c490c51ced17213db5ffddcef (diff)
downloadgdb-7a076fd259bad195b86f1acc207993d342997cf1.zip
gdb-7a076fd259bad195b86f1acc207993d342997cf1.tar.gz
gdb-7a076fd259bad195b86f1acc207993d342997cf1.tar.bz2
2006-05-06 Fred Fish <fnf@specifix.com>
* mips-tdep.c (mips_o64_return_value): Replace stub that always returned RETURN_VALUE_STRUCT_CONVENTION with a real function.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/mips-tdep.c40
2 files changed, 44 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 620d157..8ede9c9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-06 Fred Fish <fnf@specifix.com>
+
+ * mips-tdep.c (mips_o64_return_value): Replace stub that always
+ returned RETURN_VALUE_STRUCT_CONVENTION with a real function.
+
2006-05-05 Daniel Jacobowitz <dan@codesourcery.com>
* mi/mi-main.c (captured_mi_execute_command): Check the return
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index dcb4406..48e926f 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -3788,7 +3788,45 @@ mips_o64_return_value (struct gdbarch *gdbarch,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
- return RETURN_VALUE_STRUCT_CONVENTION;
+ 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)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+ else if (fp_register_arg_p (TYPE_CODE (type), type))
+ {
+ /* A floating-point value. It fits in the least significant
+ part of FP0. */
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
+ mips_xfer_register (regcache,
+ NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+ TYPE_LENGTH (type),
+ TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
+ else
+ {
+ /* A scalar extract each part but least-significant-byte
+ justified. */
+ int offset;
+ int regnum;
+ for (offset = 0, regnum = MIPS_V0_REGNUM;
+ offset < TYPE_LENGTH (type);
+ offset += mips_stack_argsize (gdbarch), regnum++)
+ {
+ int xfer = mips_stack_argsize (gdbarch);
+ if (offset + xfer > TYPE_LENGTH (type))
+ xfer = TYPE_LENGTH (type) - offset;
+ if (mips_debug)
+ fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
+ offset, xfer, regnum);
+ mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+ TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+ }
+ return RETURN_VALUE_REGISTER_CONVENTION;
+ }
}
/* Floating point register management.