emit-rtl.c (set_mem_size): New function.
authorAlan Modra <amodra@bigpond.net.au>
Thu, 12 Sep 2002 02:14:26 +0000 (02:14 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Thu, 12 Sep 2002 02:14:26 +0000 (11:44 +0930)
* emit-rtl.c (set_mem_size): New function.
* expr.h (set_mem_size): Declare.
* config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
(expand_block_move): Instead, use adjust_address and
replace_equiv_address to generate proper aliasing info.
Move common code out of conditionals.  Localize vars.

From-SVN: r57047

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/emit-rtl.c
gcc/expr.h

index 200f20f64fe7e1cb334ab82622ba6419ca423e3d..701bd4c78457601c42a1ea07bffe428268663aac 100644 (file)
@@ -1,3 +1,12 @@
+2002-09-12  Alan Modra  <amodra@bigpond.net.au>
+
+       * emit-rtl.c (set_mem_size): New function.
+       * expr.h (set_mem_size): Declare.
+       * config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
+       (expand_block_move): Instead, use adjust_address and
+       replace_equiv_address to generate proper aliasing info.
+       Move common code out of conditionals.  Localize vars.
+
 2002-09-09  Eric Botcazou  ebotcazou@libertysurf.fr
   
        * optabs.c (expand_binop): Minor cleanup.
index 5974d3bce096f5cda3faf540dbce1e16aae583b5..7195ce9c11b2675df2ae371c80f5711b4cb9b69d 100644 (file)
@@ -167,7 +167,6 @@ struct builtin_description
 
 static void rs6000_add_gc_roots PARAMS ((void));
 static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
-static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
 static void validate_condition_mode 
   PARAMS ((enum rtx_code, enum machine_mode));
 static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
@@ -6044,21 +6043,7 @@ rs6000_common_init_builtins ()
     }
 }
 
-/* Generate a memory reference for expand_block_move, copying volatile,
-   and other bits from an original memory reference.  */
-
-static rtx
-expand_block_move_mem (mode, addr, orig_mem)
-     enum machine_mode mode;
-     rtx addr;
-     rtx orig_mem;
-{
-  rtx mem = gen_rtx_MEM (mode, addr);
-
-  MEM_COPY_ATTRIBUTES (mem, orig_mem);
-  return mem;
-}
-
+\f
 /* Expand a block move operation, and return 1 if successful.  Return 0
    if we should let the compiler generate normal code.
 
@@ -6081,14 +6066,6 @@ expand_block_move (operands)
   int align;
   int bytes;
   int offset;
-  int num_reg;
-  int i;
-  rtx src_reg;
-  rtx dest_reg;
-  rtx src_addr;
-  rtx dest_addr;
-  rtx tmp_reg;
-  rtx stores[MAX_MOVE_REG];
   int move_bytes;
 
   /* If this is not a fixed size move, just call memcpy */
@@ -6110,14 +6087,17 @@ expand_block_move (operands)
   if (bytes > (TARGET_POWERPC64 ? 64 : 32))
     return 0;
 
-  /* Move the address into scratch registers.  */
-  dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
-  src_reg  = copy_addr_to_reg (XEXP (orig_src,  0));
-
   if (TARGET_STRING)   /* string instructions are available */
     {
-      for ( ; bytes > 0; bytes -= move_bytes)
+      for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
        {
+         union {
+           rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
+           rtx (*mov) PARAMS ((rtx, rtx));
+         } gen_func;
+         enum machine_mode mode = BLKmode;
+         rtx src, dest;
+
          if (bytes > 24                /* move up to 32 bytes at a time */
              && ! fixed_regs[5]
              && ! fixed_regs[6]
@@ -6129,15 +6109,7 @@ expand_block_move (operands)
              && ! fixed_regs[12])
            {
              move_bytes = (bytes > 32) ? 32 : bytes;
-             emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode,
-                                                                  dest_reg,
-                                                                  orig_dest),
-                                           expand_block_move_mem (BLKmode,
-                                                                  src_reg,
-                                                                  orig_src),
-                                           GEN_INT ((move_bytes == 32)
-                                                    ? 0 : move_bytes),
-                                           align_rtx));
+             gen_func.movstrsi = gen_movstrsi_8reg;
            }
          else if (bytes > 16   /* move up to 24 bytes at a time */
                   && ! fixed_regs[5]
@@ -6148,14 +6120,7 @@ expand_block_move (operands)
                   && ! fixed_regs[10])
            {
              move_bytes = (bytes > 24) ? 24 : bytes;
-             emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
-                                                                  dest_reg,
-                                                                  orig_dest),
-                                           expand_block_move_mem (BLKmode,
-                                                                  src_reg,
-                                                                  orig_src),
-                                           GEN_INT (move_bytes),
-                                           align_rtx));
+             gen_func.movstrsi = gen_movstrsi_6reg;
            }
          else if (bytes > 8    /* move up to 16 bytes at a time */
                   && ! fixed_regs[5]
@@ -6164,14 +6129,7 @@ expand_block_move (operands)
                   && ! fixed_regs[8])
            {
              move_bytes = (bytes > 16) ? 16 : bytes;
-             emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
-                                                                  dest_reg,
-                                                                  orig_dest),
-                                           expand_block_move_mem (BLKmode,
-                                                                  src_reg,
-                                                                  orig_src),
-                                           GEN_INT (move_bytes),
-                                           align_rtx));
+             gen_func.movstrsi = gen_movstrsi_4reg;
            }
          else if (bytes >= 8 && TARGET_POWERPC64
                   /* 64-bit loads and stores require word-aligned
@@ -6179,108 +6137,84 @@ expand_block_move (operands)
                   && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
            {
              move_bytes = 8;
-             tmp_reg = gen_reg_rtx (DImode);
-             emit_move_insn (tmp_reg,
-                             expand_block_move_mem (DImode,
-                                                    src_reg, orig_src));
-             emit_move_insn (expand_block_move_mem (DImode,
-                                                    dest_reg, orig_dest),
-                             tmp_reg);
+             mode = DImode;
+             gen_func.mov = gen_movdi;
            }
          else if (bytes > 4 && !TARGET_POWERPC64)
            {                   /* move up to 8 bytes at a time */
              move_bytes = (bytes > 8) ? 8 : bytes;
-             emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode,
-                                                                  dest_reg,
-                                                                  orig_dest),
-                                           expand_block_move_mem (BLKmode,
-                                                                  src_reg,
-                                                                  orig_src),
-                                           GEN_INT (move_bytes),
-                                           align_rtx));
+             gen_func.movstrsi = gen_movstrsi_2reg;
            }
          else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
            {                   /* move 4 bytes */
              move_bytes = 4;
-             tmp_reg = gen_reg_rtx (SImode);
-             emit_move_insn (tmp_reg,
-                             expand_block_move_mem (SImode,
-                                                    src_reg, orig_src));
-             emit_move_insn (expand_block_move_mem (SImode,
-                                                    dest_reg, orig_dest),
-                             tmp_reg);
+             mode = SImode;
+             gen_func.mov = gen_movsi;
            }
          else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
            {                   /* move 2 bytes */
              move_bytes = 2;
-             tmp_reg = gen_reg_rtx (HImode);
-             emit_move_insn (tmp_reg,
-                             expand_block_move_mem (HImode,
-                                                    src_reg, orig_src));
-             emit_move_insn (expand_block_move_mem (HImode,
-                                                    dest_reg, orig_dest),
-                             tmp_reg);
+             mode = HImode;
+             gen_func.mov = gen_movhi;
            }
          else if (bytes == 1)  /* move 1 byte */
            {
              move_bytes = 1;
-             tmp_reg = gen_reg_rtx (QImode);
-             emit_move_insn (tmp_reg,
-                             expand_block_move_mem (QImode,
-                                                    src_reg, orig_src));
-             emit_move_insn (expand_block_move_mem (QImode,
-                                                    dest_reg, orig_dest),
-                             tmp_reg);
+             mode = QImode;
+             gen_func.mov = gen_movqi;
            }
          else
            {                   /* move up to 4 bytes at a time */
              move_bytes = (bytes > 4) ? 4 : bytes;
-             emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode,
-                                                                  dest_reg,
-                                                                  orig_dest),
-                                           expand_block_move_mem (BLKmode,
-                                                                  src_reg,
-                                                                  orig_src),
-                                           GEN_INT (move_bytes),
-                                           align_rtx));
+             gen_func.movstrsi = gen_movstrsi_1reg;
            }
 
-         if (bytes > move_bytes)
+         src = adjust_address (orig_src, mode, offset);
+         dest = adjust_address (orig_dest, mode, offset);
+
+         if (mode == BLKmode)
            {
-             if (! TARGET_POWERPC64)
+             /* Move the address into scratch registers.  The movstrsi
+                patterns require zero offset.  */
+             if (!REG_P (XEXP (src, 0)))
                {
-                 emit_insn (gen_addsi3 (src_reg, src_reg,
-                                        GEN_INT (move_bytes)));
-                 emit_insn (gen_addsi3 (dest_reg, dest_reg,
-                                        GEN_INT (move_bytes)));
+                 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
+                 src = replace_equiv_address (src, src_reg);
                }
-             else
+             set_mem_size (src, GEN_INT (move_bytes));
+
+             if (!REG_P (XEXP (dest, 0)))
                {
-                 emit_insn (gen_adddi3 (src_reg, src_reg,
-                                        GEN_INT (move_bytes)));
-                 emit_insn (gen_adddi3 (dest_reg, dest_reg,
-                                        GEN_INT (move_bytes)));
+                 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
+                 dest = replace_equiv_address (dest, dest_reg);
                }
+             set_mem_size (dest, GEN_INT (move_bytes));
+
+             emit_insn ((*gen_func.movstrsi) (dest, src,
+                                              GEN_INT (move_bytes & 31),
+                                              align_rtx));
+           }
+         else
+           {
+             rtx tmp_reg = gen_reg_rtx (mode);
+
+             emit_insn ((*gen_func.mov) (tmp_reg, src));
+             emit_insn ((*gen_func.mov) (dest, tmp_reg));
            }
        }
     }
 
   else                 /* string instructions not available */
     {
-      num_reg = offset = 0;
-      for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
+      rtx stores[MAX_MOVE_REG];
+      int num_reg = 0;
+      int i;
+
+      for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
        {
-         /* Calculate the correct offset for src/dest */
-         if (offset == 0)
-           {
-             src_addr  = src_reg;
-             dest_addr = dest_reg;
-           }
-         else
-           {
-             src_addr = plus_constant (src_reg, offset);
-             dest_addr = plus_constant (dest_reg, offset);
-           }
+         rtx (*gen_mov_func) PARAMS ((rtx, rtx));
+         enum machine_mode mode;
+         rtx src, dest, tmp_reg;
 
          /* Generate the appropriate load and store, saving the stores
             for later.  */
@@ -6290,56 +6224,35 @@ expand_block_move (operands)
              && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
            {
              move_bytes = 8;
-             tmp_reg = gen_reg_rtx (DImode);
-             emit_insn (gen_movdi (tmp_reg,
-                                   expand_block_move_mem (DImode,
-                                                          src_addr,
-                                                          orig_src)));
-             stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode,
-                                                                   dest_addr,
-                                                                   orig_dest),
-                                            tmp_reg);
+             mode = DImode;
+             gen_mov_func = gen_movdi;
            }
          else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
            {
              move_bytes = 4;
-             tmp_reg = gen_reg_rtx (SImode);
-             emit_insn (gen_movsi (tmp_reg,
-                                   expand_block_move_mem (SImode,
-                                                          src_addr,
-                                                          orig_src)));
-             stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode,
-                                                                   dest_addr,
-                                                                   orig_dest),
-                                            tmp_reg);
+             mode = SImode;
+             gen_mov_func = gen_movsi;
            }
          else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
            {
              move_bytes = 2;
-             tmp_reg = gen_reg_rtx (HImode);
-             emit_insn (gen_movhi (tmp_reg,
-                                   expand_block_move_mem (HImode,
-                                                          src_addr,
-                                                          orig_src)));
-             stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode,
-                                                                   dest_addr,
-                                                                   orig_dest),
-                                            tmp_reg);
+             mode = HImode;
+             gen_mov_func = gen_movhi;
            }
          else
            {
              move_bytes = 1;
-             tmp_reg = gen_reg_rtx (QImode);
-             emit_insn (gen_movqi (tmp_reg,
-                                   expand_block_move_mem (QImode,
-                                                          src_addr,
-                                                          orig_src)));
-             stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode,
-                                                                   dest_addr,
-                                                                   orig_dest),
-                                            tmp_reg);
+             mode = QImode;
+             gen_mov_func = gen_movqi;
            }
 
+         src = adjust_address (orig_src, mode, offset);
+         dest = adjust_address (orig_dest, mode, offset);
+         tmp_reg = gen_reg_rtx (mode);
+
+         emit_insn ((*gen_mov_func) (tmp_reg, src));
+         stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
+
          if (num_reg >= MAX_MOVE_REG)
            {
              for (i = 0; i < num_reg; i++)
@@ -13225,4 +13138,3 @@ rs6000_binds_local_p (decl)
 {
   return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
 }
-
index e94fc4ec843090822c1745767d6b7cb3f204f93c..b8297a8808cfb0534be94235f5a01c0cb0e7201e 100644 (file)
@@ -1968,6 +1968,17 @@ set_mem_offset (mem, offset)
                                   offset, MEM_SIZE (mem), MEM_ALIGN (mem),
                                   GET_MODE (mem));
 }
+
+/* Set the size of MEM to SIZE.  */
+
+void
+set_mem_size (mem, size)
+     rtx mem, size;
+{
+  MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
+                                  MEM_OFFSET (mem), size, MEM_ALIGN (mem),
+                                  GET_MODE (mem));
+}
 \f
 /* Return a memory reference like MEMREF, but with its mode changed to MODE
    and its address changed to ADDR.  (VOIDmode means don't change the mode.
index c3a1009a12a7be2f27689013c3a55f766574440e..470ebd49a17933d77f19002df040826a14c9ecae 100644 (file)
@@ -616,6 +616,9 @@ extern void set_mem_expr PARAMS ((rtx, tree));
 /* Set the offset for MEM to OFFSET.  */
 extern void set_mem_offset PARAMS ((rtx, rtx));
 
+/* Set the size for MEM to SIZE.  */
+extern void set_mem_size PARAMS ((rtx, rtx));
+
 /* Return a memory reference like MEMREF, but with its mode changed
    to MODE and its address changed to ADDR.
    (VOIDmode means don't change the mode.