mn10300.c (mn10300_secondary_reload_class): We need secondary reloads for AM33-2...
authorJeff Law <law@gcc.gnu.org>
Fri, 29 Aug 2008 21:35:55 +0000 (15:35 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 29 Aug 2008 21:35:55 +0000 (15:35 -0600)
* 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

gcc/ChangeLog
gcc/config/mn10300/mn10300.c

index 13e5916cd49f8e92dfd057b45db90651b3a5cac2..bec1f6a0591f807f803804526e440968defd839f 100644 (file)
@@ -1,6 +1,13 @@
+2008-08-29  Jeff Law  <law@redhat.com>
+
+       * 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.
+
 2008-08-29  Jan Hubicka  <jh@suse.cz>
 
-       * see.c (see_merge_one_def_extension): Silence used uninitialized warning.
+       * see.c (see_merge_one_def_extension): Silence used uninitialized
+       warning.
        * matrix-reorg.c (check_allocation_function): Likewise.
        * config/i386/driver-i386.c (detect_caches_amd): Likewise.
 
index 6f172fc0b26e0f077ed466d071fdef6c3d044835..13c0ff72f2ed9d0f47acb06fb8f2a409b24ef05b 100644 (file)
@@ -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.  */