]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/21616 ([3.4 only] ICE: unable to find a register to spill in class ...
authorAlan Modra <amodra@bigpond.net.au>
Wed, 1 Mar 2006 01:04:29 +0000 (01:04 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 1 Mar 2006 01:04:29 +0000 (11:34 +1030)
PR target/21616
Revert most of 2004-03-10 changes, apply mainline 2005-01-07.
* config/rs6000/rs6000.c (invalid_gpr_mem): Delete.
(base_reg_operand): Delete.
(legitimate_offset_address_p): Revert 2004-03-10 changes.
(secondary_reload_class): Likewise.
(rs6000_legitimize_reload_address): Convert non-word aligned
offset address using ld/std into indirect address.
* config/rs6000/rs6000.h (SECONDARY_RELOAD_CLASS): Define.
(SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Delete.
(PREDICATE_CODES): Delete invalid_gpr_mem and base_reg_operand.
* config/rs6000/rs6000-protos.h (secondary_reload_class): Update.
* config/rs6000/rs6000.md (movdf_hardfloat64): Remove m->b
alternative and split.
(movdi_internal64): Likewise.
(reload_outdf, reload_indf, reload_outdi, reload_indi): Delete.

From-SVN: r111592

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md

index 53e0e661c111a6633375807f5a579975fed795f0..822d6a98dbe43f3901b12ee112f27328de7b2290 100644 (file)
@@ -1,3 +1,22 @@
+2006-03-01  Alan Modra  <amodra@bigpond.net.au>
+
+       PR target/21616
+       Revert most of 2004-03-10 changes, apply mainline 2005-01-07.
+       * config/rs6000/rs6000.c (invalid_gpr_mem): Delete.
+       (base_reg_operand): Delete.
+       (legitimate_offset_address_p): Revert 2004-03-10 changes.
+       (secondary_reload_class): Likewise.
+       (rs6000_legitimize_reload_address): Convert non-word aligned
+       offset address using ld/std into indirect address.
+       * config/rs6000/rs6000.h (SECONDARY_RELOAD_CLASS): Define.
+       (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Delete.
+       (PREDICATE_CODES): Delete invalid_gpr_mem and base_reg_operand.
+       * config/rs6000/rs6000-protos.h (secondary_reload_class): Update.
+       * config/rs6000/rs6000.md (movdf_hardfloat64): Remove m->b
+       alternative and split.
+       (movdi_internal64): Likewise.
+       (reload_outdf, reload_indf, reload_outdi, reload_indi): Delete.
+
 2006-02-28  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * Backport
index 3d17162e6472ea2fd9b03e51399325d7472c58e7..3303ecd4eb14fdbee5d618ac25cc6a723ab62d1a 100644 (file)
@@ -105,7 +105,7 @@ extern int registers_ok_for_quad_peep (rtx, rtx);
 extern int addrs_ok_for_quad_peep (rtx, rtx);
 extern bool gpr_or_gpr_p (rtx, rtx);
 extern enum reg_class secondary_reload_class (enum reg_class,
-                                             enum machine_mode, rtx, int);
+                                             enum machine_mode, rtx);
 extern int ccr_bit (rtx, int);
 extern int extract_MB (rtx);
 extern int extract_ME (rtx);
index 7a0ca184a72abe8511aaa0818c80be1d311ef92a..ea35843341f67b7b9fb3271f074476b6cb7eeb35 100644 (file)
@@ -2497,43 +2497,6 @@ word_offset_memref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   return (off % 4) == 0;
 }
 
-/* Return true if operand is a (MEM (PLUS (REG) (offset))) where offset
-   is not divisible by four.  */
-
-int
-invalid_gpr_mem (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  rtx addr;
-  long off;
-
-  if (GET_CODE (op) != MEM)
-    return 0;
-
-  addr = XEXP (op, 0);
-  if (GET_CODE (addr) != PLUS
-      || GET_CODE (XEXP (addr, 0)) != REG
-      || GET_CODE (XEXP (addr, 1)) != CONST_INT)
-    return 0;
-
-  off = INTVAL (XEXP (addr, 1));
-  return (off & 3) != 0;
-}
-
-/* Return true if operand is a hard register that can be used as a base
-   register.  */
-
-int
-base_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  unsigned int regno;
-
-  if (!REG_P (op))
-    return 0;
-
-  regno = REGNO (op);
-  return regno != 0 && regno <= 31;
-}
-
 /* Return true if either operand is a general purpose register.  */
 
 bool
@@ -2658,16 +2621,18 @@ legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
 
     case DFmode:
     case DImode:
-      /* Both DFmode and DImode may end up in gprs.  If gprs are 32-bit,
-        then we need to load/store at both offset and offset+4.  */
-      if (!TARGET_POWERPC64)
+      if (mode == DFmode || !TARGET_POWERPC64)
        extra = 4;
+      else if (offset & 3)
+       return false;
       break;
 
     case TFmode:
     case TImode:
-      if (!TARGET_POWERPC64)
+      if (mode == TFmode || !TARGET_POWERPC64)
        extra = 12;
+      else if (offset & 3)
+       return false;
       else
        extra = 8;
       break;
@@ -3206,6 +3171,26 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       return x;
     }
 #endif
+
+  /* Force ld/std non-word aligned offset into base register by wrapping
+     in offset 0.  */
+  if (GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 0)) == REG
+      && REGNO (XEXP (x, 0)) < 32
+      && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && (INTVAL (XEXP (x, 1)) & 3) != 0
+      && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
+      && TARGET_POWERPC64)
+    {
+      x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
+      push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+                  BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                  opnum, (enum reload_type) type);
+      *win = 1;
+      return x;
+    }
+
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 0)) == REG
       && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
@@ -3240,6 +3225,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       *win = 1;
       return x;
     }
+
 #if TARGET_MACHO
   if (GET_CODE (x) == SYMBOL_REF
       && DEFAULT_ABI == ABI_DARWIN
@@ -3269,6 +3255,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       return x;
     }
 #endif
+
   if (TARGET_TOC
       && constant_pool_expr_p (x)
       && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
@@ -8726,14 +8713,12 @@ addrs_ok_for_quad_peep (rtx addr1, rtx addr2)
 \f
 /* Return the register class of a scratch register needed to copy IN into
    or out of a register in CLASS in MODE.  If it can be done directly,
-   NO_REGS is returned.  INP is nonzero if we are loading the reg, zero
-   for storing.  */
+   NO_REGS is returned.  */
 
 enum reg_class
 secondary_reload_class (enum reg_class class,
                        enum machine_mode mode,
-                       rtx in,
-                       int inp)
+                       rtx in)
 {
   int regno;
 
@@ -8758,14 +8743,6 @@ secondary_reload_class (enum reg_class class,
         return BASE_REGS;
     }
 
-  /* A 64-bit gpr load or store using an offset that isn't a multiple of
-     four needs a secondary reload.  */
-  if (TARGET_POWERPC64
-      && GET_MODE_UNIT_SIZE (mode) >= 8
-      && (!inp || class != BASE_REGS)
-      && invalid_gpr_mem (in, mode))
-    return BASE_REGS;
-
   if (GET_CODE (in) == REG)
     {
       regno = REGNO (in);
index f1ad8968755ef13772089036b8ebfa7ff2532193..01a97da4bf61b61448a1b3a835a946217dff853e 100644 (file)
@@ -1492,11 +1492,8 @@ enum reg_class
    or out of a register in CLASS in MODE.  If it can be done directly,
    NO_REGS is returned.  */
 
-#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
-  secondary_reload_class (CLASS, MODE, IN, 1)
-
-#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \
-  secondary_reload_class (CLASS, MODE, IN, 0)
+#define SECONDARY_RELOAD_CLASS(CLASS, MODE, IN) \
+  secondary_reload_class (CLASS, MODE, IN)
 
 /* If we are copying between FP or AltiVec registers and anything
    else, we need a memory location.  */
@@ -2671,8 +2668,6 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"lwa_operand", {SUBREG, MEM, REG}},                                    \
   {"volatile_mem_operand", {MEM}},                                        \
   {"offsettable_mem_operand", {MEM}},                                     \
-  {"invalid_gpr_mem", {MEM}},                                             \
-  {"base_reg_operand", {REG}},                                            \
   {"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}},             \
   {"add_operand", {SUBREG, REG, CONST_INT}},                              \
   {"non_add_cint_operand", {CONST_INT}},                                  \
index e530dd94fee4957a1ce2ec664c88e363321fde55..0e242d4cfa6139611988c839ea5d7ab29acf6d5e 100644 (file)
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
 (define_insn "*movdf_hardfloat64"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!h,!r,!r,!r")
-       (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,0,G,H,F"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,!cl,!r,!h,!r,!r,!r")
+       (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
    && (gpc_reg_operand (operands[0], DFmode)
        || gpc_reg_operand (operands[1], DFmode))"
   "@
    std%U0%X0 %1,%0
    ld%U1%X1 %0,%1
-   #
    mr %0,%1
    fmr %0,%1
    lfd%U1%X1 %0,%1
    #
    #
    #"
-  [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*,*")
-   (set_attr "length" "4,4,8,4,4,4,4,4,4,4,8,12,16")])
-
-(define_split
-  [(set (match_operand:DF 0 "base_reg_operand" "")
-       (match_operand:DF 1 "invalid_gpr_mem" ""))]
-  "TARGET_POWERPC64 && no_new_pseudos"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (match_dup 4))]
-  "
-{
-  operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
-  operands[3] = XEXP (operands[1], 0);
-  operands[4] = replace_equiv_address (operands[1], operands[2]);
-}")
-
-(define_expand "reload_outdf"
-  [(parallel [(match_operand:DF 0 "invalid_gpr_mem" "")
-             (match_operand:DF 1 "register_operand" "")
-             (match_operand:DI 2 "register_operand" "=&b")])]
-  "TARGET_POWERPC64"
-{
-  if (!TARGET_64BIT)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
-  emit_move_insn (operands[2], XEXP (operands[0], 0));
-  operands[0] = replace_equiv_address (operands[0], operands[2]);
-  emit_move_insn (operands[0], operands[1]);
-  DONE;
-})
-
-(define_expand "reload_indf"
-  [(parallel [(match_operand:DF 0 "register_operand" "")
-             (match_operand:DF 1 "invalid_gpr_mem" "")
-             (match_operand:DI 2 "register_operand" "=&b")])]
-  "TARGET_POWERPC64"
-{
-  if (!TARGET_64BIT)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
-  emit_move_insn (operands[2], XEXP (operands[1], 0));
-  operands[1] = replace_equiv_address (operands[1], operands[2]);
-  emit_move_insn (operands[0], operands[1]);
-  DONE;
-})
+  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*,*")
+   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")])
 
 (define_insn "*movdf_softfloat64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
 }")
 
 (define_insn "*movdi_internal64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,b,r,r,r,r,r,??f,f,m,r,*h,*h")
-       (match_operand:DI 1 "input_operand" "r,Y,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,r,??f,f,m,r,*h,*h")
+       (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,R,f,m,f,*h,r,0"))]
   "TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
   "@
    std%U0%X0 %1,%0
    ld%U1%X1 %0,%1
-   #
    mr %0,%1
    li %0,%1
    lis %0,%v1
    mf%1 %0
    mt%0 %1
    {cror 0,0,0|nop}"
-  [(set_attr "type" "store,load,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
-   (set_attr "length" "4,4,8,4,4,4,20,4,4,4,4,4,4,4")])
-
-(define_split
-  [(set (match_operand:DI 0 "base_reg_operand" "")
-       (match_operand:DI 1 "invalid_gpr_mem" ""))]
-  "TARGET_POWERPC64 && no_new_pseudos"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (match_dup 4))]
-  "
-{
-  operands[2] = operands[0];
-  if (!TARGET_64BIT)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
-  operands[3] = XEXP (operands[1], 0);
-  operands[4] = replace_equiv_address (operands[1], operands[2]);
-}")
-
-(define_expand "reload_outdi"
-  [(parallel [(match_operand:DI 0 "invalid_gpr_mem" "")
-              (match_operand:DI 1 "register_operand" "")
-              (match_operand:DI 2 "register_operand" "=&b")])]
-  "TARGET_POWERPC64"
-{
-  if (!TARGET_64BIT)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
-  emit_move_insn (operands[2], XEXP (operands[0], 0));
-  operands[0] = replace_equiv_address (operands[0], operands[2]);
-  emit_move_insn (operands[0], operands[1]);
-  DONE;
-})
-
-(define_expand "reload_indi"
-  [(parallel [(match_operand:DI 0 "register_operand" "")
-             (match_operand:DI 1 "invalid_gpr_mem" "")
-             (match_operand:DI 2 "register_operand" "=&b")])]
-  "TARGET_POWERPC64"
-{
-  if (!TARGET_64BIT)
-    operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
-  emit_move_insn (operands[2], XEXP (operands[1], 0));
-  operands[1] = replace_equiv_address (operands[1], operands[2]);
-  emit_move_insn (operands[0], operands[1]);
-  DONE;
-})
+  [(set_attr "type" "store,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
+   (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
 
 ;; immediate value valid for a single instruction hiding in a const_double
 (define_insn ""