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