diff options
author | Richard Sandiford <rsandifo@nildram.co.uk> | 2007-10-19 08:55:02 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-10-19 08:55:02 +0000 |
commit | c862c910f6a41f405005037e452fd72736383df7 (patch) | |
tree | 4582c7f788b6c946ad8d2368a65298c416fad322 | |
parent | 5f5fe6d9f7e5680bbf6ebeca21172bc8e3b3454f (diff) | |
download | gcc-c862c910f6a41f405005037e452fd72736383df7.zip gcc-c862c910f6a41f405005037e452fd72736383df7.tar.gz gcc-c862c910f6a41f405005037e452fd72736383df7.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 59 |
2 files changed, 38 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8655afa..41e1237 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 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, split out from... (mips_expand_epilogue): ...here. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index da9448e..1abee68 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 |