]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mips.c (mips_hard_regno_nregs): Put the UNITS_PER_WORD case last.
authorRichard Sandiford <rsandifo@nildram.co.uk>
Fri, 19 Oct 2007 08:55:02 +0000 (08:55 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 19 Oct 2007 08:55:02 +0000 (08:55 +0000)
gcc/
* config/mips/mips.c (mips_hard_regno_nregs): Put the UNITS_PER_WORD
case last.
(mips_class_max_nregs): Calculate the smallest consituent register
size and use that to determine an upper bound on the number of
registers.

From-SVN: r129478

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

index 8655afab779a307b12dd9fa09d69159a89d94a66..41e12373090b09a5ad76b2505d585e79458e9dd1 100644 (file)
@@ -1,3 +1,11 @@
+2007-10-19  Richard Sandiford  <rsandifo@nildram.co.uk>
+
+       * config/mips/mips.c (mips_hard_regno_nregs): Put the UNITS_PER_WORD
+       case last.
+       (mips_class_max_nregs): Calculate the smallest consituent register
+       size and use that to determine an upper bound on the number of
+       registers.
+
 2007-10-19  Richard Sandiford  <rsandifo@nildram.co.uk>
 
        * config/mips/mips.c (mips16_copy_fpr_return_value): New function,
index da9448e3c7a60bfeb3aac340f9b2d1122e11baf6..1abee68e82b140f15b80cd664f70eda3122b8f79 100644 (file)
@@ -8805,46 +8805,47 @@ mips_hard_regno_mode_ok_p (unsigned int regno, enum machine_mode mode)
   return false;
 }
 
-/* Implement HARD_REGNO_NREGS.  The size of FP registers is controlled
-   by UNITS_PER_FPREG.  The size of FP status registers is always 4, because
-   they only hold condition code modes, and CCmode is always considered to
-   be 4 bytes wide.  All other registers are word sized.  */
+/* Implement HARD_REGNO_NREGS.  */
 
 unsigned int
 mips_hard_regno_nregs (int regno, enum machine_mode mode)
 {
   if (ST_REG_P (regno))
-    return ((GET_MODE_SIZE (mode) + 3) / 4);
-  else if (! FP_REG_P (regno))
-    return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
-  else
-    return ((GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG);
-}
-
-/* Implement CLASS_MAX_NREGS.
+    /* The size of FP status registers is always 4, because they only hold
+       CCmode values, and CCmode is always considered to be 4 bytes wide.  */
+    return (GET_MODE_SIZE (mode) + 3) / 4;
 
-   - UNITS_PER_FPREG controls the number of registers needed by FP_REGS.
+  if (FP_REG_P (regno))
+    return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
 
-   - ST_REGS are always hold CCmode values, and CCmode values are
-     considered to be 4 bytes wide.
+  /* All other registers are word-sized.  */
+  return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+}
 
-   All other register classes are covered by UNITS_PER_WORD.  Note that
-   this is true even for unions of integer and float registers when the
-   latter are smaller than the former.  The only supported combination
-   in which case this occurs is -mgp64 -msingle-float, which has 64-bit
-   words but 32-bit float registers.  A word-based calculation is correct
-   in that case since -msingle-float disallows multi-FPR values.  */
+/* Implement CLASS_MAX_NREGS, taking the maximum of the cases
+   in mips_hard_regno_nregs.  */
 
 int
-mips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
-                     enum machine_mode mode)
+mips_class_max_nregs (enum reg_class class, enum machine_mode mode)
 {
-  if (class == ST_REGS)
-    return (GET_MODE_SIZE (mode) + 3) / 4;
-  else if (class == FP_REGS)
-    return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
-  else
-    return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+  int size;
+  HARD_REG_SET left;
+
+  size = 0x8000;
+  COPY_HARD_REG_SET (left, reg_class_contents[(int) class]);
+  if (hard_reg_set_intersect_p (left, reg_class_contents[(int) ST_REGS]))
+    {
+      size = MIN (size, 4);
+      AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) ST_REGS]);
+    }
+  if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS]))
+    {
+      size = MIN (size, UNITS_PER_FPREG);
+      AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]);
+    }
+  if (!hard_reg_set_empty_p (left))
+    size = MIN (size, UNITS_PER_WORD);
+  return (GET_MODE_SIZE (mode) + size - 1) / size;
 }
 
 /* Return true if registers of class CLASS cannot change from mode FROM