diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-08-07 08:53:02 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-08-07 08:53:02 -0400 |
commit | 486d850940b886d03a7be2c525a9cc80f90c669c (patch) | |
tree | 903441655ed218697ad636a94cc908323442e2b7 | |
parent | cc33944ac1fb05cc2db7e3ba31a1de8fead581ad (diff) | |
download | gcc-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.c | 53 |
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 |