Re: mips-tdep.c: FP varargs fixes

Maciej W. Rozycki
2007-04-17T15:51:48Z

On Tue, 17 Apr 2007, Daniel Jacobowitz wrote:

> > I think gdb.base/funcargs.exp and gdb.base/varargs.exp should already
> > cover the interesting combinations and I would suggest that only if any
> > new problem pops up, they should get updated to take it into account.
>
> But they didn't fail before your patch - at least I don't have any
> failures on mips-linux. So you must be fixing something they didn't
> test for.

Well, gdb.base/varargs.exp did fail for me before this change. The
failure was:

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)

and I can see in the function prologue it correctly handles the first two
arguments that are passed through registers:

00400ec4 <find_max_double>:

/* Double-float varargs, 2 declared args */

double find_max_double(int num_vals, double first_val, ...) {
400ec4: 3c1c0002 lui gp,0x2
400ec8: 279c850c addiu gp,gp,-31476
400ecc: 0399e021 addu gp,gp,t9
400ed0: 27bdffc0 addiu sp,sp,-64
400ed4: afbf003c sw ra,60(sp)
400ed8: afbe0038 sw s8,56(sp)
400edc: 03a0f021 move s8,sp
400ee0: afbc0010 sw gp,16(sp)
400ee4: afc40040 sw a0,64(s8)
400ee8: afc7004c sw a3,76(s8)
400eec: afc60048 sw a2,72(s8)

Without the patch, when calling this function manually, gdb would
incorrectly put the second argument onto the stack, which would get
overwritten in the prologue above with whatever values would happen to
live in a2 and a3.

Please note that according to the o32 ABI, first four 32-bit words are
always passed in registers, either general or floating-point, with the
usual alignment rules applying -- backing stack space is reserved and the
registers map to their corresponding offsets there. However only leading
floating-point arguments and only up to two of them are passed through
floating-point registers.

In this case the first argument is integer (going through a0), so the
second one, even though floating-point, has to go through general
registers. It is a 64-bit double, so it has to be aligned to a doubleword
boundry and hence a1 drops out.

Maciej