[patch/mips] fix foo(f1, f2, ..., f9)

Andrew Cagney ac131313@cygnus.com
Fri Jun 23 00:50:00 GMT 2000


FYI,

The attatched fixes a very very long standing bug where, for the MIPS,
once GDB had run out of FP registers it would try to pass FP values in
integer registers instead of the stack.

	Andrew
Fri Jun 23 16:20:21 2000  Andrew Cagney  <cagney@b1.cygnus.com>

	* mips-tdep.c (fp_register_arg_p): New function.
	(mips_push_arguments): Use.  Do not pass floating point arguments
 	on in an integer register.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.20
diff -p -r1.20 mips-tdep.c
*** mips-tdep.c	2000/06/17 15:18:21	1.20
--- mips-tdep.c	2000/06/23 07:35:20
*************** setup_arbitrary_frame (argc, argv)
*** 2062,2067 ****
--- 2062,2084 ----
    return create_new_frame (argv[0], argv[1]);
  }
  
+ /* According to the current ABI, should the type be passed in a
+    floating-point register (assuming that there is space)?  When there
+    is no FPU, FP are not even considered as possibile candidates for
+    FP registers and, consequently this returns false - forces FP
+    arguments into integer registers. */
+ 
+ static int
+ fp_register_arg_p (enum type_code typecode, struct type *arg_type)
+ {
+   return ((typecode == TYPE_CODE_FLT
+ 	   || (MIPS_EABI
+ 	       && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
+ 	       && TYPE_NFIELDS (arg_type) == 1
+ 	       && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
+ 	   && MIPS_FPU_TYPE != MIPS_FPU_NONE);
+ }
+ 
  CORE_ADDR
  mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
       int nargs;
*************** mips_push_arguments (nargs, args, sp, st
*** 2165,2177 ****
        /* MIPS_EABI squeeses a struct that contains a single floating
           point value into an FP register instead of pusing it onto the
           stack. */
!       if ((typecode == TYPE_CODE_FLT
! 	   || (MIPS_EABI
! 	       && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
! 	       && TYPE_NFIELDS (arg_type) == 1
! 	       && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
! 	  && float_argreg <= MIPS_LAST_FP_ARG_REGNUM
! 	  && MIPS_FPU_TYPE != MIPS_FPU_NONE)
  	{
  	  if (!FP_REGISTER_DOUBLE && len == 8)
  	    {
--- 2182,2189 ----
        /* MIPS_EABI squeeses a struct that contains a single floating
           point value into an FP register instead of pusing it onto the
           stack. */
!       if (fp_register_arg_p (typecode, arg_type)
! 	  && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
  	{
  	  if (!FP_REGISTER_DOUBLE && len == 8)
  	    {
*************** mips_push_arguments (nargs, args, sp, st
*** 2241,2254 ****
  	     are treated specially: Irix cc passes them in registers
  	     where gcc sometimes puts them on the stack.  For maximum
  	     compatibility, we will put them in both places.  */
- 
  	  int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
  				  (len % MIPS_SAVED_REGSIZE != 0));
  	  while (len > 0)
  	    {
  	      int partial_len = len < MIPS_SAVED_REGSIZE ? len : MIPS_SAVED_REGSIZE;
  
! 	      if (argreg > MIPS_LAST_ARG_REGNUM || odd_sized_struct)
  		{
  		  /* Write this portion of the argument to the stack.  */
  		  /* Should shorter than int integer values be
--- 2253,2269 ----
  	     are treated specially: Irix cc passes them in registers
  	     where gcc sometimes puts them on the stack.  For maximum
  	     compatibility, we will put them in both places.  */
  	  int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
  				  (len % MIPS_SAVED_REGSIZE != 0));
+ 	  /* Note: Floating-point values that didn't fit into an FP
+              register are only written to memory. */
  	  while (len > 0)
  	    {
  	      int partial_len = len < MIPS_SAVED_REGSIZE ? len : MIPS_SAVED_REGSIZE;
  
! 	      if (argreg > MIPS_LAST_ARG_REGNUM
! 		  || odd_sized_struct
! 		  || fp_register_arg_p (typecode, arg_type))
  		{
  		  /* Write this portion of the argument to the stack.  */
  		  /* Should shorter than int integer values be
*************** mips_push_arguments (nargs, args, sp, st
*** 2291,2299 ****
  		  write_memory (addr, val, partial_len);
  		}
  
! 	      /* Note!!! This is NOT an else clause.
! 	         Odd sized structs may go thru BOTH paths.  */
! 	      if (argreg <= MIPS_LAST_ARG_REGNUM)
  		{
  		  LONGEST regval = extract_unsigned_integer (val, partial_len);
  
--- 2306,2316 ----
  		  write_memory (addr, val, partial_len);
  		}
  
! 	      /* Note!!! This is NOT an else clause.  Odd sized
! 	         structs may go thru BOTH paths.  Floating point
! 	         arguments will not. */
! 	      if (argreg <= MIPS_LAST_ARG_REGNUM
! 		  && !fp_register_arg_p (typecode, arg_type))
  		{
  		  LONGEST regval = extract_unsigned_integer (val, partial_len);
  


More information about the Gdb-patches mailing list