rs6000.c (legitimate_offset_address_p): Make global, rename rs6000_legitimate_offset_...
authorDale Johannesen <dalej@apple.com>
Tue, 22 Jun 2004 18:12:37 +0000 (18:12 +0000)
committerDale Johannesen <dalej@gcc.gnu.org>
Tue, 22 Jun 2004 18:12:37 +0000 (18:12 +0000)
2004-06-22  Dale Johannesen  <dalej@apple.com>

* config/rs6000/rs6000.c (legitimate_offset_address_p): Make
global, rename rs6000_legitimate_offset_address_p.
(rs6000_legitimate_address_p): Adjust calls to it.
(lmw_operation): Ditto.
(stmw_operation): Ditto.
* config/rs6000/rs6000-protos.h: Declare it.
* config/rs6000/rs6000.md (*movdf_hardfloat32): Use it
instead of offsettable_memref_p.

2004-06-22  Dale Johannesen  <dalej@apple.com>

* config/rs6000/rs6000.c (rs6000_legitimate_address): Disallow
[reg+reg] mode for TFmode memory accesses.
(rs6000_eliminate_indexed_memrefs): New.
(rs6000_emit_move): Call preceding for TImode and TFmode.

From-SVN: r83504

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

index 52e182c9c828e12e188bf530f70a6e2fa563dda0..21f780efba6d09e7f3819dee322489844d276a85 100644 (file)
@@ -1,3 +1,21 @@
+2004-06-22  Dale Johannesen  <dalej@apple.com>
+
+       * config/rs6000/rs6000.c (legitimate_offset_address_p): Make
+       global, rename rs6000_legitimate_offset_address_p.
+       (rs6000_legitimate_address_p): Adjust calls to it.
+       (lmw_operation): Ditto.
+       (stmw_operation): Ditto.
+       * config/rs6000/rs6000-protos.h: Declare it.
+       * config/rs6000/rs6000.md (*movdf_hardfloat32): Use it
+       instead of offsettable_memref_p.
+
+2004-06-22  Dale Johannesen  <dalej@apple.com>
+
+       * config/rs6000/rs6000.c (rs6000_legitimate_address): Disallow
+       [reg+reg] mode for TFmode memory accesses.
+       (rs6000_eliminate_indexed_memrefs): New.
+       (rs6000_emit_move): Call preceding for TImode and TFmode.
+
 2004-06-22  Paolo Bonzini  <bonzini@gnu.org>
 
        * tree-cfg.c (pass_warn_function_return): It needs
index 7078c16e084a832ed3f5779063f242c922bcc908..d626d682f328f5babd7fa4da2d91397648f2818d 100644 (file)
@@ -139,6 +139,7 @@ extern bool rs6000_mode_dependent_address (rtx);
 extern rtx rs6000_return_addr (int, rtx);
 extern void rs6000_output_symbol_ref (FILE*, rtx);
 extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
+extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
 
 extern rtx rs6000_machopic_legitimize_pic_address (rtx orig, 
                             enum machine_mode mode, rtx reg);
index 861b00ad514aaa36d4e99b18559454ba19b92438..391ef27b485345f041c9eb9b6ed4c031ea925007 100644 (file)
@@ -303,7 +303,6 @@ static int constant_pool_expr_1 (rtx, int *, int *);
 static bool constant_pool_expr_p (rtx);
 static bool toc_relative_expr_p (rtx);
 static bool legitimate_small_data_p (enum machine_mode, rtx);
-static bool legitimate_offset_address_p (enum machine_mode, rtx, int);
 static bool legitimate_indexed_address_p (rtx, int);
 static bool legitimate_indirect_address_p (rtx, int);
 static bool macho_lo_sum_memory_operand (rtx x, enum machine_mode mode);
@@ -316,6 +315,7 @@ static void rs6000_assemble_visibility (tree, int);
 static int rs6000_ra_ever_killed (void);
 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
+static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
 static const char *rs6000_mangle_fundamental_type (tree);
 extern const struct attribute_spec rs6000_attribute_table[];
 static void rs6000_set_default_type_attributes (tree);
@@ -2648,8 +2648,8 @@ legitimate_small_data_p (enum machine_mode mode, rtx x)
          && small_data_operand (x, mode));
 }
 
-static bool
-legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
+bool
+rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
 {
   unsigned HOST_WIDE_INT offset, extra;
 
@@ -3328,7 +3328,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
    word aligned.
 
    For modes spanning multiple registers (DFmode in 32-bit GPRs,
-   32-bit DImode, TImode), indexed addressing cannot be used because
+   32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
    adjacent memory cells are accessed by adding word-sized offsets
    during assembly output.  */
 int
@@ -3356,9 +3356,10 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
          || XEXP (x, 0) == arg_pointer_rtx)
       && GET_CODE (XEXP (x, 1)) == CONST_INT)
     return 1;
-  if (legitimate_offset_address_p (mode, x, reg_ok_strict))
+  if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
     return 1;
   if (mode != TImode
+      && mode != TFmode
       && ((TARGET_HARD_FLOAT && TARGET_FPRS)
          || TARGET_POWERPC64
          || (mode != DFmode && mode != TFmode))
@@ -3653,6 +3654,27 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
   return dest;
 }
 
+/* Helper for the following.  Get rid of [r+r] memory refs
+   in cases where it won't work (TImode, TFmode).  */
+
+static void
+rs6000_eliminate_indexed_memrefs (rtx operands[2])
+{
+  if (GET_CODE (operands[0]) == MEM
+      && GET_CODE (XEXP (operands[0], 0)) != REG
+      && ! reload_in_progress)
+    operands[0]
+      = replace_equiv_address (operands[0],
+                              copy_addr_to_reg (XEXP (operands[0], 0)));
+
+  if (GET_CODE (operands[1]) == MEM
+      && GET_CODE (XEXP (operands[1], 0)) != REG
+      && ! reload_in_progress)
+    operands[1]
+      = replace_equiv_address (operands[1],
+                              copy_addr_to_reg (XEXP (operands[1], 0)));
+}
+
 /* Emit a move from SOURCE to DEST in mode MODE.  */
 void
 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
@@ -3790,6 +3812,9 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
       break;
 
     case TFmode:
+      rs6000_eliminate_indexed_memrefs (operands);
+      /* fall through */
+
     case DFmode:
     case SFmode:
       if (CONSTANT_P (operands[1]) 
@@ -3972,19 +3997,8 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
       break;
 
     case TImode:
-      if (GET_CODE (operands[0]) == MEM
-         && GET_CODE (XEXP (operands[0], 0)) != REG
-         && ! reload_in_progress)
-       operands[0]
-         = replace_equiv_address (operands[0],
-                                  copy_addr_to_reg (XEXP (operands[0], 0)));
-
-      if (GET_CODE (operands[1]) == MEM
-         && GET_CODE (XEXP (operands[1], 0)) != REG
-         && ! reload_in_progress)
-       operands[1]
-         = replace_equiv_address (operands[1],
-                                  copy_addr_to_reg (XEXP (operands[1], 0)));
+      rs6000_eliminate_indexed_memrefs (operands);
+
       if (TARGET_POWER)
        {
          emit_insn (gen_rtx_PARALLEL (VOIDmode,
@@ -8383,7 +8397,7 @@ lmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
       if (base_regno == 0)
        return 0;
     }
-  else if (legitimate_offset_address_p (SImode, src_addr, 0))
+  else if (rs6000_legitimate_offset_address_p (SImode, src_addr, 0))
     {
       offset = INTVAL (XEXP (src_addr, 1));
       base_regno = REGNO (XEXP (src_addr, 0));
@@ -8411,7 +8425,7 @@ lmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
          newoffset = 0;
          addr_reg = newaddr;
        }
-      else if (legitimate_offset_address_p (SImode, newaddr, 0))
+      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
        {
          addr_reg = XEXP (newaddr, 0);
          newoffset = INTVAL (XEXP (newaddr, 1));
@@ -8459,7 +8473,7 @@ stmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
       if (base_regno == 0)
        return 0;
     }
-  else if (legitimate_offset_address_p (SImode, dest_addr, 0))
+  else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, 0))
     {
       offset = INTVAL (XEXP (dest_addr, 1));
       base_regno = REGNO (XEXP (dest_addr, 0));
@@ -8487,7 +8501,7 @@ stmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
          newoffset = 0;
          addr_reg = newaddr;
        }
-      else if (legitimate_offset_address_p (SImode, newaddr, 0))
+      else if (rs6000_legitimate_offset_address_p (SImode, newaddr, 0))
        {
          addr_reg = XEXP (newaddr, 0);
          newoffset = INTVAL (XEXP (newaddr, 1));
index 29d70e9df109d24efdf56f4403d8d1b673873d29..86b93d3dbd09a7c09a87fbbeb4c5efc948bd9f04 100644 (file)
       else
        return \"mr %0,%1\;mr %L0,%L1\";
     case 1:
-      if (offsettable_memref_p (operands[1])
-         || (GET_CODE (operands[1]) == MEM
-             && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
+      if (GET_CODE (operands[1]) == MEM
+         && (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[1], 0),
+                       reload_completed || reload_in_progress)
+             || GET_CODE (XEXP (operands[1], 0)) == REG
+             || GET_CODE (XEXP (operands[1], 0)) == LO_SUM
                  || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
-                 || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)))
+             || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
        {
          /* If the low-address word is used in the address, we must load
             it last.  Otherwise, load it first.  Note that we cannot have
            }
        }
     case 2:
-      if (offsettable_memref_p (operands[0])
-         || (GET_CODE (operands[0]) == MEM
-             && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
+      if (GET_CODE (operands[0]) == MEM
+          && (rs6000_legitimate_offset_address_p (DFmode, XEXP (operands[0], 0),
+                   reload_completed || reload_in_progress)
+             || GET_CODE (XEXP (operands[0], 0)) == REG
+             || GET_CODE (XEXP (operands[0], 0)) == LO_SUM
                  || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
-                 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)))
+             || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))
        return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
       else
        {