[MIPS 15/30] Fix CLASS_MAX_NREGS

Richard Sandiford rsandifo@nildram.co.uk
Fri Oct 19 09:05:00 GMT 2007


CLASS_MAX_NREGS isn't quite right: for example, the CCV2 value for ALL_REGS
should be the same as for ST_REGS, rather than be based on UNITS_PER_WORD.
This patch fixes it by using the maximum of the individual
mips_hard_regno_nregs cases.  It also rewrites mips_hard_regno_nregs
so that the cases are in the same order for both functions.

Richard


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.

Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	2007-10-18 11:07:10.000000000 +0100
--- gcc/config/mips/mips.c	2007-10-18 11:07:10.000000000 +0100
*************** mips_hard_regno_mode_ok_p (unsigned int 
*** 8843,8888 ****
    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.  */
  
  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.
  
!    - UNITS_PER_FPREG controls the number of registers needed by FP_REGS.
  
!    - ST_REGS are always hold CCmode values, and CCmode values are
!      considered to be 4 bytes wide.
  
!    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.  */
  
  int
! mips_class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,
! 		      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;
  }
  
  /* Return true if registers of class CLASS cannot change from mode FROM
--- 8843,8889 ----
    return false;
  }
  
! /* Implement HARD_REGNO_NREGS.  */
  
  unsigned int
  mips_hard_regno_nregs (int regno, enum machine_mode mode)
  {
    if (ST_REG_P (regno))
!     /* 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;
  
!   if (FP_REG_P (regno))
!     return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
  
!   /* All other registers are word-sized.  */
!   return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
! }
  
! /* Implement CLASS_MAX_NREGS, taking the maximum of the cases
!    in mips_hard_regno_nregs.  */
  
  int
! mips_class_max_nregs (enum reg_class class, enum machine_mode mode)
  {
!   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



More information about the Gcc-patches mailing list