diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2004-10-31 21:13:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2004-10-31 21:13:35 +0000 |
commit | 29b4addfbca3fe3b5ee2cb88bc8f00ca48e4607f (patch) | |
tree | 1f3ae1c3d3d5de48967c70edb75b39570ae8de6a /gcc | |
parent | 3292fb426e5f41ca8d3e134e28a5f9ba04538e88 (diff) | |
download | gcc-29b4addfbca3fe3b5ee2cb88bc8f00ca48e4607f.zip gcc-29b4addfbca3fe3b5ee2cb88bc8f00ca48e4607f.tar.gz gcc-29b4addfbca3fe3b5ee2cb88bc8f00ca48e4607f.tar.bz2 |
mips.c (mips_cannot_change_mode_class): Use a stricter mode check.
* config/mips/mips.c (mips_cannot_change_mode_class): Use a stricter
mode check.
From-SVN: r89917
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 51 |
2 files changed, 35 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee21b6b..b94a3bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2004-10-31 Richard Sandiford <rsandifo@redhat.com> + + * config/mips/mips.c (mips_cannot_change_mode_class): Use a stricter + mode check. + 2004-10-31 Kazu Hirata <kazu@cs.umass.edu> * c-common.c: Fix a comment typo. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 0cc7fac..4aa3b08 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -6837,35 +6837,44 @@ mips_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, return mips_abi == ABI_EABI && named; } -/* Return the class of registers for which a mode change from FROM to TO - is invalid. - - In little-endian mode, the hi-lo registers are numbered backwards, - so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low - word as intended. - - Similarly, when using paired floating-point registers, the first - register holds the low word, regardless of endianness. So in big - endian mode, (subreg:SI (reg:DF $f0) 0) does not get the high word - as intended. - - Also, loading a 32-bit value into a 64-bit floating-point register - will not sign-extend the value, despite what LOAD_EXTEND_OP says. - We can't allow 64-bit float registers to change from a 32-bit - mode to a 64-bit mode. */ +/* Return true if registers of class CLASS cannot change from mode FROM + to mode TO. */ bool mips_cannot_change_mode_class (enum machine_mode from, enum machine_mode to, enum reg_class class) { - if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to)) + if (MIN (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) <= UNITS_PER_WORD + && MAX (GET_MODE_SIZE (from), GET_MODE_SIZE (to)) > UNITS_PER_WORD) { if (TARGET_BIG_ENDIAN) - return reg_classes_intersect_p (FP_REGS, class); - if (TARGET_FLOAT64) - return reg_classes_intersect_p (HI_AND_FP_REGS, class); - return reg_classes_intersect_p (HI_REG, class); + { + /* When a multi-word value is stored in paired floating-point + registers, the first register always holds the low word. + We therefore can't allow FPRs to change between single-word + and multi-word modes. */ + if (FP_INC > 1 && reg_classes_intersect_p (FP_REGS, class)) + return true; + } + else + { + /* LO_REGNO == HI_REGNO + 1, so if a multi-word value is stored + in LO and HI, the high word always comes first. We therefore + can't allow values stored in HI to change between single-word + and multi-word modes. */ + if (reg_classes_intersect_p (HI_REG, class)) + return true; + } } + /* Loading a 32-bit value into a 64-bit floating-point register + will not sign-extend the value, despite what LOAD_EXTEND_OP says. + We can't allow 64-bit float registers to change from SImode to + to a wider mode. */ + if (TARGET_FLOAT64 + && from == SImode + && GET_MODE_SIZE (to) >= UNITS_PER_WORD + && reg_classes_intersect_p (FP_REGS, class)) + return true; return false; } |