From c862c910f6a41f405005037e452fd72736383df7 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 19 Oct 2007 08:55:02 +0000 Subject: [PATCH] mips.c (mips_hard_regno_nregs): Put the UNITS_PER_WORD case last. 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 | 8 ++++++ gcc/config/mips/mips.c | 59 +++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8655afab779..41e12373090 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2007-10-19 Richard Sandiford + + * 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 * config/mips/mips.c (mips16_copy_fpr_return_value): New function, diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index da9448e3c7a..1abee68e82b 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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 -- 2.30.2