AGMA: fix MIPS argument passing
Andrew Cagney
ac131313@cygnus.com
Wed Jun 6 04:34:00 GMT 2001
> ("Any Guidance Much Appreciated")
>
> The mips_push_arguments function is trying to deal with so many
> processor variants and ABI's at the same time that it's hard to see
> how to change it without breaking somebody. So I'm not at all sure
> the patch below is correct. But it does fix the failure:
mips_push_arguments is a text book example of how to _not_ handle ABI
variants:-) They should have been separate functions so that your FUD
didn't occure.
> gdb.base/varargs.exp: print find_max_double(5,1.0,17.0,2.0,3.0,4.0)
>
> which should be familiar to anyone dealing with MIPS processors
> lacking an FPU.
I wonder how it came to be un-aligned.... Ah, the ``5'' in
``(5,1.0,...) would have done that. The first element had only 4 bytes.
Does the compiler pack adjacent arguments any tighter than a WORD? I
suspect it doesn't. So ``4'' rather than ``1'' is probably better.
Hmm, more digging/thinking. What happens is roughly:
o code allocates sufficent
MIPS_STACK_ARG_SIZE chunks of
stack space to fit the object
o the object's memory start address is
then shuffled so that it is stored in
in those chunks correctly aligned.
o the aligment rules change according to
the ABI
I think all you're code needs to do is check for objects that have an
alignment that is greater than MIPS_STACK_ARG_SIZE and then re-adjust
stack_offset for that case.
BTW, there are other cases in the MIPS where similar heuristics such as
your's are found - see fp_register_arg_p().
Andrew
> 2001-06-04 Jim Blandy <jimb@redhat.com>
>
> * mips-tdep.c (mips_push_arguments): Align arguments properly.
>
> Index: gdb/mips-tdep.c
> ===================================================================
> RCS file: /cvs/cvsfiles/devo/gdb/mips-tdep.c,v
> retrieving revision 1.248.2.2
> diff -c -r1.248.2.2 mips-tdep.c
> *** gdb/mips-tdep.c 2001/04/11 20:37:52 1.248.2.2
> --- gdb/mips-tdep.c 2001/06/05 02:29:47
> ***************
> *** 2263,2268 ****
> --- 2263,2303 ----
> compatibility, we will put them in both places. */
> int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
> (len % MIPS_SAVED_REGSIZE != 0));
> +
> + /* The prologue for a varargs function is going to simply
> + spill the registers out onto the stack. This means that
> + our choice of integer *registers* must respect the type's
> + *memory* alignment rules. So, for example, on a machine
> + with 32-bit integer registers, we should make sure to
> + pass a type requiring 8-byte alignment starting with an
> + even-numbered register.
> +
> + In theory, we should actually figure out the argument's
> + required alignment here, but that's too much of a pain,
> + so we just hard-code certain cases that are annoying us
> + at the moment. */
> + if (! fp_register_arg_p (typecode, arg_type))
> + {
> + int alignment, reg_alignment;
> + int original_argreg;
> +
> + /* Doubles require 8-byte alignment. */
> + if (typecode == TYPE_CODE_FLT
> + && arg_type->length == 8)
> + alignment = 8;
> +
> + /* We're punting on other types for the time being. */
> + else
> + alignment = 1;
> +
> + reg_alignment = (alignment < MIPS_STACK_ARGSIZE
> + ? 1
> + : alignment / MIPS_STACK_ARGSIZE);
Suggest:
if (..)
reg_alignment = ;
else
reg_alignment = ;
> + original_argreg = argreg;
> + argreg = ROUND_UP (argreg, reg_alignment);
> + stack_offset += (argreg - original_argreg) * MIPS_STACK_ARGSIZE;
> + }
> +
> /* Note: Floating-point values that didn't fit into an FP
> register are only written to memory. */
> while (len > 0)
>
>
More information about the Gdb-patches
mailing list