aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-10-31 21:13:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-10-31 21:13:35 +0000
commit29b4addfbca3fe3b5ee2cb88bc8f00ca48e4607f (patch)
tree1f3ae1c3d3d5de48967c70edb75b39570ae8de6a /gcc
parent3292fb426e5f41ca8d3e134e28a5f9ba04538e88 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/config/mips/mips.c51
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;
}