When FP registers are full, store FP arguments on stack and not in
authorAndrew Cagney <cagney@redhat.com>
Fri, 23 Jun 2000 07:44:00 +0000 (07:44 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 23 Jun 2000 07:44:00 +0000 (07:44 +0000)
integer registers.

gdb/ChangeLog
gdb/mips-tdep.c

index c00074329c9044d2c4a77d79786b0a03a30175ab..6338d11196d44efab5a4f877174513ee8bbbfcac 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2000-06-21  Pierre Muller  <muller@ics.u-strasbg.fr>
        * symfile.c (init_filename_language_table): add ".pas", ".p" and ".pp"
        as pascal source file extensions.
index 0922ceed2cacc2dafa801fd59db4f2e0c2edf12f..6ba42a281c3990dcde46e0157789dc03742338eb 100644 (file)
@@ -2062,6 +2062,23 @@ setup_arbitrary_frame (argc, argv)
   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;
@@ -2165,13 +2182,8 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
       /* 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_arg_p (typecode, arg_type)
+         && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
        {
          if (!FP_REGISTER_DOUBLE && len == 8)
            {
@@ -2241,14 +2253,17 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
             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)
+             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
@@ -2291,9 +2306,11 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                  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)
+             /* 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);