diff options
author | Jeff Law <law@gcc.gnu.org> | 2008-08-29 15:35:55 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2008-08-29 15:35:55 -0600 |
commit | 6528281d6b122edf215b53a224ec47b4c4a79f22 (patch) | |
tree | 745b48b331e6dcd4e005c7953b1817e0b3cb0fa3 /gcc/config/mn10300 | |
parent | 041f300d6d7c6fd4e006ca8defee0bcbaca0e6e7 (diff) | |
download | gcc-6528281d6b122edf215b53a224ec47b4c4a79f22.zip gcc-6528281d6b122edf215b53a224ec47b4c4a79f22.tar.gz gcc-6528281d6b122edf215b53a224ec47b4c4a79f22.tar.bz2 |
mn10300.c (mn10300_secondary_reload_class): We need secondary reloads for AM33-2 if IN is a pseudo with an equivalent...
* mn10300.c (mn10300_secondary_reload_class): We need secondary
reloads for AM33-2 if IN is a pseudo with an equivalent memory
location and class is an FP register.
From-SVN: r139789
Diffstat (limited to 'gcc/config/mn10300')
-rw-r--r-- | gcc/config/mn10300/mn10300.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 6f172fc..13c0ff7 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "insn-attr.h" #include "flags.h" #include "recog.h" +#include "reload.h" #include "expr.h" #include "optabs.h" #include "function.h" @@ -1326,15 +1327,20 @@ enum reg_class mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode, rtx in) { + rtx inner = in; + + /* Strip off any SUBREG expressions from IN. Basically we want + to know if IN is a pseudo or (subreg (pseudo)) as those can + turn into MEMs during reload. */ + while (GET_CODE (inner) == SUBREG) + inner = SUBREG_REG (inner); + /* Memory loads less than a full word wide can't have an address or stack pointer destination. They must use a data register as an intermediate register. */ if ((GET_CODE (in) == MEM - || (GET_CODE (in) == REG - && REGNO (in) >= FIRST_PSEUDO_REGISTER) - || (GET_CODE (in) == SUBREG - && GET_CODE (SUBREG_REG (in)) == REG - && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)) + || (GET_CODE (inner) == REG + && REGNO (inner) >= FIRST_PSEUDO_REGISTER)) && (mode == QImode || mode == HImode) && (rclass == ADDRESS_REGS || rclass == SP_REGS || rclass == SP_OR_ADDRESS_REGS)) @@ -1363,13 +1369,22 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode, || XEXP (in, 1) == stack_pointer_rtx)) return GENERAL_REGS; - if (TARGET_AM33_2 && rclass == FP_REGS - && GET_CODE (in) == MEM - && ! (GET_CODE (in) == MEM && !CONSTANT_ADDRESS_P (XEXP (in, 0)))) + if (TARGET_AM33_2 + && rclass == FP_REGS) { - if (TARGET_AM33) - return DATA_OR_EXTENDED_REGS; - return DATA_REGS; + /* We can't load directly into an FP register from a + constant address. */ + if (GET_CODE (in) == MEM + && CONSTANT_ADDRESS_P (XEXP (in, 0))) + return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS); + + /* Handle case were a pseudo may not get a hard register + but has an equivalent memory location defined. */ + if (GET_CODE (inner) == REG + && REGNO (inner) >= FIRST_PSEUDO_REGISTER + && reg_equiv_mem [REGNO (inner)] + && CONSTANT_ADDRESS_P (XEXP (reg_equiv_mem [REGNO (inner)], 0))) + return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS); } /* Otherwise assume no secondary reloads are needed. */ |