aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mn10300
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>2008-08-29 15:35:55 -0600
committerJeff Law <law@gcc.gnu.org>2008-08-29 15:35:55 -0600
commit6528281d6b122edf215b53a224ec47b4c4a79f22 (patch)
tree745b48b331e6dcd4e005c7953b1817e0b3cb0fa3 /gcc/config/mn10300
parent041f300d6d7c6fd4e006ca8defee0bcbaca0e6e7 (diff)
downloadgcc-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.c37
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. */