This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

AGMA: fix MIPS argument passing



("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:

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.

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);
+               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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]