mips.h (FP_INC, [...]): New macros.
authorRichard Sandiford <rsandifo@redhat.com>
Thu, 14 Mar 2002 10:17:17 +0000 (10:17 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 14 Mar 2002 10:17:17 +0000 (10:17 +0000)
* config/mips/mips.h (FP_INC, UNITS_PER_FPVALUE): New macros.
* config/mips/mips.c (compute_frame_size): Retrofit them here.
(save_restore_insns, mips_expand_epilogue): And here.
(build_mips16_call_stub): And here.
(mips_function_value): Use the new macros to decide whether a single
or complex float can be returned in floating-point registers.  Return
a parallel rtx in the complex case.

From-SVN: r50766

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h

index ea822d1d952318e80b7a2a38d4fa67bf97026115..84d0956f7e52f58cabd5df1c7d397f545f34da67 100644 (file)
@@ -1,3 +1,13 @@
+2002-03-14  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/mips/mips.h (FP_INC, UNITS_PER_FPVALUE): New macros.
+       * config/mips/mips.c (compute_frame_size): Retrofit them here.
+       (save_restore_insns, mips_expand_epilogue): And here.
+       (build_mips16_call_stub): And here.
+       (mips_function_value): Use the new macros to decide whether a single
+       or complex float can be returned in floating-point registers.  Return
+       a parallel rtx in the complex case.
+
 Thu Mar 14 11:03:12 CET 2002  Jan Hubicka  <jh@suse.cz>
 
        * toplev.c (rest_of_compilation): Add CLEANUP_UPDATE_LIFE to cfg_cleanup
index 467cbca8d599a54e0403c94b356ddbc6e720d183..773462fc7285e18383416984b04305c2304211bd 100644 (file)
@@ -6362,6 +6362,7 @@ compute_frame_size (size)
   long fmask;                  /* mask of saved fp registers */
   int  fp_inc;                 /* 1 or 2 depending on the size of fp regs */
   long fp_bits;                        /* bitmask to use for each fp register */
+  tree return_type;
 
   gp_reg_size = 0;
   fp_reg_size = 0;
@@ -6380,6 +6381,7 @@ compute_frame_size (size)
     args_size = 4 * UNITS_PER_WORD;
 
   total_size = var_size + args_size + extra_size;
+  return_type = DECL_RESULT (current_function_decl);
 
   /* Calculate space needed for gp registers.  */
   for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
@@ -6398,12 +6400,9 @@ compute_frame_size (size)
              && regno == GP_REG_FIRST + 31
              && mips16_hard_float
              && ! mips_entry
-             && ! aggregate_value_p (DECL_RESULT (current_function_decl))
-             && (GET_MODE_CLASS (DECL_MODE (DECL_RESULT (current_function_decl)))
-                 == MODE_FLOAT)
-             && (! TARGET_SINGLE_FLOAT
-                 || (GET_MODE_SIZE (DECL_MODE (DECL_RESULT (current_function_decl)))
-                     <= 4))))
+             && ! aggregate_value_p (return_type)
+             && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
+             && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE))
        {
          gp_reg_size += GET_MODE_SIZE (gpr_mode);
          mask |= 1L << (regno - GP_REG_FIRST);
@@ -6854,12 +6853,10 @@ save_restore_insns (store_p, large_reg, large_offset, file)
   /* Save floating point registers if needed.  */
   if (fmask)
     {
-      int fp_inc = (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) ? 1 : 2;
-      int fp_size = fp_inc * UNITS_PER_FPREG;
-
       /* Pick which pointer to use as a base register.  */
       fp_offset = current_frame_info.fp_sp_offset;
-      end_offset = fp_offset - (current_frame_info.fp_reg_size - fp_size);
+      end_offset = fp_offset - (current_frame_info.fp_reg_size
+                               - UNITS_PER_FPVALUE);
 
       if (fp_offset < 0 || end_offset < 0)
        internal_error
@@ -6905,9 +6902,9 @@ save_restore_insns (store_p, large_reg, large_offset, file)
 
       /* This loop must iterate over the same space as its companion in
         compute_frame_size.  */
-      for (regno = (FP_REG_LAST - fp_inc + 1);
+      for (regno = (FP_REG_LAST - FP_INC + 1);
           regno >= FP_REG_FIRST;
-          regno -= fp_inc)
+          regno -= FP_INC)
        if (BITSET_P (fmask, regno - FP_REG_FIRST))
          {
            if (file == 0)
@@ -6939,7 +6936,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
                fprintf (file, "(%s)\n", reg_names[REGNO(base_reg_rtx)]);
              }
 
-           fp_offset -= fp_size;
+           fp_offset -= UNITS_PER_FPVALUE;
          }
     }
 }
@@ -7769,23 +7766,24 @@ mips_expand_epilogue ()
 int
 mips_can_use_return_insn ()
 {
+  tree return_type;
+
   if (! reload_completed)
     return 0;
 
   if (regs_ever_live[31] || current_function_profile)
     return 0;
 
+  return_type = DECL_RESULT (current_function_decl);
+
   /* In mips16 mode, a function which returns a floating point value
      needs to arrange to copy the return value into the floating point
      registers.  */
   if (TARGET_MIPS16
       && mips16_hard_float
-      && ! aggregate_value_p (DECL_RESULT (current_function_decl))
-      && (GET_MODE_CLASS (DECL_MODE (DECL_RESULT (current_function_decl)))
-         == MODE_FLOAT)
-      && (! TARGET_SINGLE_FLOAT
-         || (GET_MODE_SIZE (DECL_MODE (DECL_RESULT (current_function_decl)))
-             <= 4)))
+      && ! aggregate_value_p (return_type)
+      && GET_MODE_CLASS (DECL_MODE (return_type)) == MODE_FLOAT
+      && GET_MODE_SIZE (DECL_MODE (return_type)) <= UNITS_PER_FPVALUE)
     return 0;
 
   if (current_frame_info.initialized)
@@ -7951,41 +7949,23 @@ mips_function_value (valtype, func)
      just as PROMOTE_MODE does.  */
   mode = promote_mode (valtype, mode, &unsignedp, 1);
 
-  if (mclass == MODE_FLOAT)
-    {
-      if (TARGET_SINGLE_FLOAT
-         && (mclass == MODE_FLOAT
-             ? GET_MODE_SIZE (mode) > 4 : GET_MODE_SIZE (mode) / 2 > 4))
-       reg = GP_RETURN;
-      else
-       reg = FP_RETURN;
-    }
+  if (mclass == MODE_FLOAT && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE)
+    reg = FP_RETURN;
 
-  else if (mclass == MODE_COMPLEX_FLOAT)
+  else if (mclass == MODE_COMPLEX_FLOAT
+          && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE * 2)
     {
-      if (TARGET_FLOAT64)
-       reg = FP_RETURN;
-      else if (mode == SCmode)
-       {
-         /* When FP registers are 32 bits, we can't directly reference
-            the odd numbered ones, so let's make a pair of evens.  */
-
-         enum machine_mode cmode = TYPE_MODE (TREE_TYPE (valtype));
-
-         return gen_rtx_PARALLEL
-           (VOIDmode,
-            gen_rtvec (2,
-                       gen_rtx_EXPR_LIST (VOIDmode,
-                                          gen_rtx_REG (cmode,
-                                                       FP_RETURN),
-                                          GEN_INT (0)),
-                       gen_rtx_EXPR_LIST (VOIDmode,
-                                          gen_rtx_REG (cmode,
-                                                       FP_RETURN + 2),
-                                          GEN_INT (4))));
-       }
-      else
-       reg = FP_RETURN;
+      enum machine_mode cmode = TYPE_MODE (TREE_TYPE (valtype));
+
+      return gen_rtx_PARALLEL
+       (VOIDmode,
+        gen_rtvec (2,
+                   gen_rtx_EXPR_LIST (VOIDmode,
+                                      gen_rtx_REG (cmode, FP_RETURN),
+                                      GEN_INT (0)),
+                   gen_rtx_EXPR_LIST (VOIDmode,
+                                      gen_rtx_REG (cmode, FP_RETURN + FP_INC),
+                                      GEN_INT (GET_MODE_SIZE (cmode)))));
     }
 
   else if (TREE_CODE (valtype) == RECORD_TYPE
@@ -8680,8 +8660,7 @@ build_mips16_call_stub (retval, fnmem, arg_size, fp_code)
      register.  */
   fpret = (retval != 0
           && GET_MODE_CLASS (GET_MODE (retval)) == MODE_FLOAT
-          && (! TARGET_SINGLE_FLOAT
-              || GET_MODE_SIZE (GET_MODE (retval)) <= 4));
+          && GET_MODE_SIZE (GET_MODE (retval)) <= UNITS_PER_FPVALUE);
 
   /* We don't need to do anything if there were no floating point
      arguments and the value will not be returned in a floating point
index b4e4373637fed50ff94f370f00e9d36f3dd7144f..73d538379e919edc940e746087f62eceb3333a6a 100644 (file)
@@ -1591,6 +1591,13 @@ do {                                                     \
 /* For MIPS, width of a floating point register.  */
 #define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
 
+/* If register $f0 holds a floating-point value, $f(0 + FP_INC) is
+   the next available register.  */
+#define FP_INC (TARGET_FLOAT64 || TARGET_SINGLE_FLOAT ? 1 : 2)
+
+/* The largest size of value that can be held in floating-point registers.  */
+#define UNITS_PER_FPVALUE (FP_INC * UNITS_PER_FPREG)
+
 /* A C expression for the size in bits of the type `int' on the
    target machine.  If you don't define this, the default is one
    word.  */