[MIPS, committed] Fix mips_class_max_nregs

Richard Sandiford rdsandiford@googlemail.com
Sat Aug 20 20:40:00 GMT 2011


Richard Sandiford <rdsandiford@googlemail.com> writes:
> In this case it's a MIPS backend bug.  The single pressure class
> for MIPS is ALL_REGS, and CLASS_MAX_NREGS (ALL_REGS, TImode)
> is returning 4, based on the fact that ALL_REGS includes the
> floating-point condition codes.  (CCmode is hard-wired to 4 bytes,
> so for CCV2 and CCV4, the correct number of registers is the size
> of the mode divided by 4.)  Since floating-point condition codes
> can't store TImode, the backend should be ignoring them and
> returning 2 instead.  I'm testing a fix for that now.

Here's what I applied after testing mips64-linux-gnu.  As well as fixing
the wrong value for valid combinations, it has the side-effect of
returning an over-the-top value for more invalid combinations than
before.  That's semi- intentional though.  I don't think this macro is
required to detect invalid modes, or return a specific value for them.

Richard


gcc/
	* config/mips/mips.c (mips_class_max_nregs): Check that the mode is
	OK for ST_REGS and FP_REGS before taking those classes into account.

Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2011-08-20 19:44:44.000000000 +0100
+++ gcc/config/mips/mips.c	2011-08-20 19:49:06.000000000 +0100
@@ -10630,12 +10630,14 @@ mips_class_max_nregs (enum reg_class rcl
   COPY_HARD_REG_SET (left, reg_class_contents[(int) rclass]);
   if (hard_reg_set_intersect_p (left, reg_class_contents[(int) ST_REGS]))
     {
-      size = MIN (size, 4);
+      if (HARD_REGNO_MODE_OK (ST_REG_FIRST, mode))
+	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);
+      if (HARD_REGNO_MODE_OK (FP_REG_FIRST, mode))
+	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))



More information about the Gcc-patches mailing list