aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-08-07 08:53:02 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-08-07 08:53:02 -0400
commit486d850940b886d03a7be2c525a9cc80f90c669c (patch)
tree903441655ed218697ad636a94cc908323442e2b7
parentcc33944ac1fb05cc2db7e3ba31a1de8fead581ad (diff)
downloadgcc-486d850940b886d03a7be2c525a9cc80f90c669c.zip
gcc-486d850940b886d03a7be2c525a9cc80f90c669c.tar.gz
gcc-486d850940b886d03a7be2c525a9cc80f90c669c.tar.bz2
(push_reload): Make test in LOAD_EXTEND_OP case more precise; handle CLASS_CANNOT_CHANGE_SIZE.
(push_reload): Make test in LOAD_EXTEND_OP case more precise; handle CLASS_CANNOT_CHANGE_SIZE. (find_relods): When setting force_reloads, make LOAD_EXTEND_OP case more precise. From-SVN: r7868
-rw-r--r--gcc/reload.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index b9a1c27..b1727c8 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -777,8 +777,8 @@ push_reload (in, out, inloc, outloc, class,
a pseudo and hence will become a MEM) with M1 wider than M2 and the
register is a pseudo, also reload the inside expression.
For machines that extend byte loads, do this for any SUBREG of a pseudo
- where both M1 and M2 are a word or smaller unless they are the same
- size.
+ where both M1 and M2 are a word or smaller, M1 is wider than M2, and
+ M2 is an integral mode that gets extended when loaded.
Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
either M1 is not valid for R or M2 is wider than a word but we only
need one word to store an M2-sized quantity in R.
@@ -792,7 +792,11 @@ push_reload (in, out, inloc, outloc, class,
STRICT_LOW_PART (presumably, in == out in the cas).
Also reload the inner expression if it does not require a secondary
- reload but the SUBREG does. */
+ reload but the SUBREG does.
+
+ Finally, reload the inner expression if it is a register that is in
+ the class whose registers cannot be referenced in a different size
+ and M1 is not the same size as M2. */
if (in != 0 && GET_CODE (in) == SUBREG
&& (CONSTANT_P (SUBREG_REG (in))
@@ -808,7 +812,9 @@ push_reload (in, out, inloc, outloc, class,
&& (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
<= UNITS_PER_WORD)
&& (GET_MODE_SIZE (inmode)
- != GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))))
+ > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+ && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
+ && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != NIL)
#endif
))
|| (GET_CODE (SUBREG_REG (in)) == REG
@@ -833,6 +839,15 @@ push_reload (in, out, inloc, outloc, class,
SUBREG_REG (in))
== NO_REGS))
#endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ || (GET_CODE (SUBREG_REG (in)) == REG
+ && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
+ && (TEST_HARD_REG_BIT
+ (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
+ REGNO (SUBREG_REG (in))))
+ && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
+ != GET_MODE_SIZE (inmode)))
+#endif
))
{
in_subreg_loc = inloc;
@@ -885,15 +900,7 @@ push_reload (in, out, inloc, outloc, class,
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|| GET_CODE (SUBREG_REG (out)) == MEM)
&& ((GET_MODE_SIZE (outmode)
- > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
-#ifdef LOAD_EXTEND_OP
- || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
- <= UNITS_PER_WORD)
- && (GET_MODE_SIZE (outmode)
- != GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))))
-#endif
- ))
+ > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
@@ -913,6 +920,15 @@ push_reload (in, out, inloc, outloc, class,
SUBREG_REG (out))
== NO_REGS))
#endif
+#ifdef CLASS_CANNOT_CHANGE_SIZE
+ || (GET_CODE (SUBREG_REG (out)) == REG
+ && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
+ && (TEST_HARD_REG_BIT
+ (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
+ REGNO (SUBREG_REG (out))))
+ && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
+ != GET_MODE_SIZE (outmode)))
+#endif
))
{
out_subreg_loc = outloc;
@@ -2553,9 +2569,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
may not be enough to do the outer reference.
On machines that extend byte operations and we have a
- SUBREG where both the inner and outer modes are different
- size but no wider than a word, combine.c has made
- assumptions about the behavior of the machine in such
+ SUBREG where both the inner and outer modes are no wider
+ than a word and the inner mode is narrower, is integral,
+ and gets extended when loaded from memory, combine.c has
+ made assumptions about the behavior of the machine in such
register access. If the data is, in fact, in memory we
must always load using the size assumed to be in the
register and let the insn do the different-sized
@@ -2572,7 +2589,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
&& (GET_MODE_SIZE (GET_MODE (operand))
<= UNITS_PER_WORD)
&& (GET_MODE_SIZE (operand_mode[i])
- != GET_MODE_SIZE (GET_MODE (operand))))
+ > GET_MODE_SIZE (GET_MODE (operand)))
+ && INTEGRAL_MODE_P (GET_MODE (operand))
+ && LOAD_EXTEND_OP (GET_MODE (operand)) != NIL)
#endif
))
/* Subreg of a hard reg which can't handle the subreg's mode