mips-tdep.c: FP varargs fixes

Maciej W. Rozycki
2007-03-23T14:41:39Z

Hello,

The following changes fix the following test case failure:

print find_max_double(5,1.0,17.0,2.0,3.0,4.0)
find_max(5, -0.000000, 0.000000, 0.000000, 0.000000, 0.000000) returns 0.000000
$5 = 5.3101701311997171e-315
(gdb) FAIL: gdb.base/varargs.exp: print find_max_double(5,1.0,17.0,2.0,3.0,4.0)

This change has been tested natively for mips-unknown-linux-gnu and
remotely for mipsisa32-sde-elf, using mips-sim-sde32/-EB and
mips-sim-sde32/-EL as the targets, removing the failure for all.

2007-03-23 Nigel Stephens <nigel@mips.com>
Maciej W. Rozycki <macro@mips.com>

* mips-tdep.c (mips_o32_push_dummy_call): Take account of
argument alignment requirements when calculating stack space
required. When aligning an arg register to eight bytes
boundary, align stack_offset too. Write floating-point
arguments to the appropriate integer register, if we're not
passing in a floating point register.

OK to apply?

Maciej

12100-0.diff
Index: binutils-quilt/src/gdb/mips-tdep.c
===================================================================
--- binutils-quilt.orig/src/gdb/mips-tdep.c 2007-03-23 14:21:18.000000000 +0000
+++ binutils-quilt/src/gdb/mips-tdep.c 2007-03-23 14:25:57.000000000 +0000
@@ -3071,8 +3071,16 @@

/* Now make space on the stack for the args. */
for (argnum = 0; argnum < nargs; argnum++)
- len += align_up (TYPE_LENGTH (value_type (args[argnum])),
- mips_stack_argsize (gdbarch));
+ {
+ struct type *arg_type = check_typedef (value_type (args[argnum]));
+ int arglen = TYPE_LENGTH (arg_type);
+ /* Align to double-word if necessary. */
+ if (mips_abi_regsize (gdbarch) < 8
+ && mips_type_needs_double_align (arg_type))
+ len = align_up (len, mips_stack_argsize (gdbarch) * 2);
+ /* Allocate space on the stack. */
+ len += align_up (arglen, mips_stack_argsize (gdbarch));
+ }
sp -= align_up (len, 16);

if (mips_debug)
@@ -3208,7 +3216,10 @@
&& mips_type_needs_double_align (arg_type))
{
if ((argreg & 1))
- argreg++;
+ {
+ argreg++;
+ stack_offset += mips_abi_regsize (gdbarch);
+ }
}
/* Note: Floating-point values that didn't fit into an FP
register are only written to memory. */
@@ -3272,7 +3283,7 @@
/* Write this portion of the argument to a general
purpose register. */
if (argreg <= MIPS_LAST_ARG_REGNUM
- && !fp_register_arg_p (typecode, arg_type))
+ /*&& !fp_register_arg_p (typecode, arg_type)*/)
{
LONGEST regval = extract_signed_integer (val, partial_len);
/* Value may need to be sign extended, because