]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
expr.h (enum block_op_methods): New.
authorRichard Henderson <rth@redhat.com>
Thu, 29 Aug 2002 19:20:01 +0000 (12:20 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 29 Aug 2002 19:20:01 +0000 (12:20 -0700)
        * expr.h (enum block_op_methods): New.
        (emit_block_move): Update prototype.
        * expr.c (block_move_libcall_safe_for_call_parm): New.
        (emit_block_move_via_loop): New.
        (emit_block_move): Use them.  New argument METHOD.
        (emit_push_insn): Always respect the given alignment.
        (expand_assignment): Update call to emit_block_move.
        (store_expr, store_field, expand_expr): Likewise.
        * builtins.c (expand_builtin_apply): Likewise.
        (expand_builtin_memcpy, expand_builtin_va_copy): Likewise.
        * function.c (expand_function_end): Likewise.
        * config/sh/sh.c (sh_initialize_trampoline): Likewise.
        * config/sparc/sparc.c (sparc_va_arg): Likewise.
        * calls.c (expand_call, emit_library_call_value_1): Likewise.
        (save_fixed_argument_area): Use emit_block_move with
        BLOCK_OP_CALL_PARM instead of move_by_pieces.
        (restore_fixed_argument_area): Likewise.
        (store_one_arg): Fix alignment parameter to emit_push_insn.

From-SVN: r56661

gcc/ChangeLog
gcc/builtins.c
gcc/calls.c
gcc/config/sh/sh.c
gcc/config/sparc/sparc.c
gcc/expr.c
gcc/expr.h
gcc/function.c

index 1c9311fa473aa441c0be5d5a9975e3be31f63884..b2dcdf12dc5d0d6bcb5f95e9e9dfd34abfddba20 100644 (file)
@@ -1,3 +1,24 @@
+2002-08-29  Richard Henderson  <rth@redhat.com>
+
+       * expr.h (enum block_op_methods): New.
+       (emit_block_move): Update prototype.
+       * expr.c (block_move_libcall_safe_for_call_parm): New.
+       (emit_block_move_via_loop): New.
+       (emit_block_move): Use them.  New argument METHOD.
+       (emit_push_insn): Always respect the given alignment.
+       (expand_assignment): Update call to emit_block_move.
+       (store_expr, store_field, expand_expr): Likewise.
+       * builtins.c (expand_builtin_apply): Likewise.
+       (expand_builtin_memcpy, expand_builtin_va_copy): Likewise.
+       * function.c (expand_function_end): Likewise.
+       * config/sh/sh.c (sh_initialize_trampoline): Likewise.
+       * config/sparc/sparc.c (sparc_va_arg): Likewise.
+       * calls.c (expand_call, emit_library_call_value_1): Likewise.
+       (save_fixed_argument_area): Use emit_block_move with
+       BLOCK_OP_CALL_PARM instead of move_by_pieces.
+       (restore_fixed_argument_area): Likewise.
+       (store_one_arg): Fix alignment parameter to emit_push_insn.
+
 2002-08-29  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
        * install.texi (hppa64-hp-hpux11*): Document installation procedure.
index a295a9aab346d0b0c3d6c96a35b31c9d8052d19b..b2ad5375b77101c08b84e79bed813801dc45ab35 100644 (file)
@@ -1225,7 +1225,7 @@ expand_builtin_apply (function, arguments, argsize)
   set_mem_align (dest, PARM_BOUNDARY);
   src = gen_rtx_MEM (BLKmode, incoming_args);
   set_mem_align (src, PARM_BOUNDARY);
-  emit_block_move (dest, src, argsize);
+  emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
 
   /* Refer to the argument block.  */
   apply_args_size ();
@@ -2000,7 +2000,8 @@ expand_builtin_memcpy (arglist, target, mode)
       set_mem_align (src_mem, src_align);
 
       /* Copy word part most expediently.  */
-      dest_addr = emit_block_move (dest_mem, src_mem, len_rtx);
+      dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
+                                  BLOCK_OP_NORMAL);
 
       if (dest_addr == 0)
        {
@@ -3298,7 +3299,7 @@ expand_builtin_va_copy (arglist)
       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
 
       /* Copy.  */
-      emit_block_move (dstb, srcb, size);
+      emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
     }
 
   return const0_rtx;
index 5979747a68bdb7bf76b08358a1cdda6c90753e04..2e238094ffbb21ce75088ddd50053bd375566ac3 100644 (file)
@@ -967,11 +967,8 @@ save_fixed_argument_area (reg_parm_stack_space, argblock,
       if (save_mode == BLKmode)
        {
          save_area = assign_stack_temp (BLKmode, num_to_save, 0);
-         /* Cannot use emit_block_move here because it can be done by a
-            library call which in turn gets into this place again and deadly
-            infinite recursion happens.  */
-         move_by_pieces (validize_mem (save_area), stack_area, num_to_save,
-                         PARM_BOUNDARY);
+         emit_block_move (validize_mem (save_area), stack_area,
+                          GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
        }
       else
        {
@@ -1008,11 +1005,9 @@ restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
   if (save_mode != BLKmode)
     emit_move_insn (stack_area, save_area);
   else
-    /* Cannot use emit_block_move here because it can be done by a library
-       call which in turn gets into this place again and deadly infinite
-       recursion happens.  */
-    move_by_pieces (stack_area, validize_mem (save_area),
-                   high_to_save - low_to_save + 1, PARM_BOUNDARY);
+    emit_block_move (stack_area, validize_mem (save_area),
+                    GEN_INT (high_to_save - low_to_save + 1),
+                    BLOCK_OP_CALL_PARM);
 }
 #endif /* REG_PARM_STACK_SPACE */
 
@@ -3317,9 +3312,9 @@ expand_call (exp, target, ignore)
                if (save_mode != BLKmode)
                  emit_move_insn (stack_area, args[i].save_area);
                else
-                 emit_block_move (stack_area,
-                                  validize_mem (args[i].save_area),
-                                  GEN_INT (args[i].size.constant));
+                 emit_block_move (stack_area, args[i].save_area,
+                                  GEN_INT (args[i].size.constant),
+                                  BLOCK_OP_CALL_PARM);
              }
 
          highest_outgoing_arg_in_use = initial_highest_arg_in_use;
@@ -3909,8 +3904,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
            {
              save_area = assign_stack_temp (BLKmode, num_to_save, 0);
              set_mem_align (save_area, PARM_BOUNDARY);
-             emit_block_move (validize_mem (save_area), stack_area,
-                              GEN_INT (num_to_save));
+             emit_block_move (save_area, stack_area, GEN_INT (num_to_save),
+                              BLOCK_OP_CALL_PARM);
            }
          else
            {
@@ -3978,8 +3973,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
                }
            }
 
-         emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
-                         argblock, GEN_INT (argvec[argnum].offset.constant),
+         emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
+                         partial, reg, 0, argblock,
+                         GEN_INT (argvec[argnum].offset.constant),
                          reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
 
          /* Now mark the segment we just used.  */
@@ -4180,8 +4176,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
          if (save_mode != BLKmode)
            emit_move_insn (stack_area, save_area);
          else
-           emit_block_move (stack_area, validize_mem (save_area),
-                            GEN_INT (high_to_save - low_to_save + 1));
+           emit_block_move (stack_area, save_area,
+                            GEN_INT (high_to_save - low_to_save + 1),
+                            BLOCK_OP_CALL_PARM);
        }
 #endif
 
@@ -4358,7 +4355,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
                  arg->save_area = assign_temp (nt, 0, 1, 1);
                  preserve_temp_slots (arg->save_area);
                  emit_block_move (validize_mem (arg->save_area), stack_area,
-                                  expr_size (arg->tree_value));
+                                  expr_size (arg->tree_value),
+                                  BLOCK_OP_CALL_PARM);
                }
              else
                {
@@ -4479,8 +4477,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
 
       /* This isn't already where we want it on the stack, so put it there.
         This can either be done with push or copy insns.  */
-      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
-                     partial, reg, used - size, argblock,
+      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 
+                     PARM_BOUNDARY, partial, reg, used - size, argblock,
                      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                      ARGS_SIZE_RTX (arg->alignment_pad));
 
@@ -4574,18 +4572,18 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
           {
            rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
            emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
-                           TYPE_ALIGN (TREE_TYPE (pval)), partial, reg,
-                           excess, argblock, ARGS_SIZE_RTX (arg->offset),
-                           reg_parm_stack_space,
+                           MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval))),
+                           partial, reg, excess, argblock,
+                           ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                            ARGS_SIZE_RTX (arg->alignment_pad));
          }
        }
        
 
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
-                     TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
-                     argblock, ARGS_SIZE_RTX (arg->offset),
-                     reg_parm_stack_space,
+                     MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval))),
+                     partial, reg, excess, argblock,
+                     ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                      ARGS_SIZE_RTX (arg->alignment_pad));
 
       /* Unless this is a partially-in-register argument, the argument is now
index e49881ba866b3c1e9ad68315f5eb4b7e226b06c9..a6ce2be9d17d5ba3de3ee7fe8d37471d81f8d919 100644 (file)
@@ -7301,7 +7301,7 @@ sh_initialize_trampoline (tramp, fnaddr, cxt)
       src = gen_rtx_MEM (BLKmode, tramp_templ);
       set_mem_align (dst, 256);
       set_mem_align (src, 64);
-      emit_block_move (dst, src, GEN_INT (fixed_len));
+      emit_block_move (dst, src, GEN_INT (fixed_len), BLOCK_OP_NORMAL);
 
       emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (tramp,        fixed_len)),
                      fnaddr);
index 971b6f2e5f7b15c7132347f07c16eb876a58b79e..4a83b8a56128cbfd9b5ec0909f33864b2be58562 100644 (file)
@@ -5347,7 +5347,8 @@ sparc_va_arg (valist, type)
       PUT_MODE (tmp, BLKmode);
       set_mem_alias_set (tmp, 0);
       
-      dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize));
+      dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize),
+                                  BLOCK_OP_NORMAL);
       if (dest_addr != NULL_RTX)
        addr_rtx = dest_addr;
       else
index b95de65fb274d28da2acc1ce7a5c4feed908e57a..700b84084dac1ddb5e5124aa77f86017b6aa2c11 100644 (file)
@@ -132,9 +132,11 @@ static unsigned HOST_WIDE_INT move_by_pieces_ninsns
                                         unsigned int));
 static void move_by_pieces_1   PARAMS ((rtx (*) (rtx, ...), enum machine_mode,
                                         struct move_by_pieces *));
+static bool block_move_libcall_safe_for_call_parm PARAMS ((void));
 static bool emit_block_move_via_movstr PARAMS ((rtx, rtx, rtx, unsigned));
 static rtx emit_block_move_via_libcall PARAMS ((rtx, rtx, rtx));
 static tree emit_block_move_libcall_fn PARAMS ((int));
+static void emit_block_move_via_loop PARAMS ((rtx, rtx, rtx, unsigned));
 static rtx clear_by_pieces_1   PARAMS ((PTR, HOST_WIDE_INT,
                                         enum machine_mode));
 static void clear_by_pieces    PARAMS ((rtx, unsigned HOST_WIDE_INT,
@@ -1677,16 +1679,43 @@ move_by_pieces_1 (genfun, mode, data)
    Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
    SIZE is an rtx that says how long they are.
    ALIGN is the maximum alignment we can assume they have.
+   METHOD describes what kind of copy this is, and what mechanisms may be used.
 
    Return the address of the new block, if memcpy is called and returns it,
    0 otherwise.  */
 
 rtx
-emit_block_move (x, y, size)
+emit_block_move (x, y, size, method)
      rtx x, y, size;
+     enum block_op_methods method;
 {
+  bool may_use_call;
   rtx retval = 0;
-  unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
+  unsigned int align;
+
+  switch (method)
+    {
+    case BLOCK_OP_NORMAL:
+      may_use_call = true;
+      break;
+
+    case BLOCK_OP_CALL_PARM:
+      may_use_call = block_move_libcall_safe_for_call_parm ();
+
+      /* Make inhibit_defer_pop nonzero around the library call
+        to force it to pop the arguments right away.  */
+      NO_DEFER_POP;
+      break;
+
+    case BLOCK_OP_NO_LIBCALL:
+      may_use_call = false;
+      break;
+
+    default:
+      abort ();
+    }
+
+  align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
 
   if (GET_MODE (x) != BLKmode)
     abort ();
@@ -1708,12 +1737,77 @@ emit_block_move (x, y, size)
     move_by_pieces (x, y, INTVAL (size), align);
   else if (emit_block_move_via_movstr (x, y, size, align))
     ;
-  else
+  else if (may_use_call)
     retval = emit_block_move_via_libcall (x, y, size);
+  else
+    emit_block_move_via_loop (x, y, size, align);
+
+  if (method == BLOCK_OP_CALL_PARM)
+    OK_DEFER_POP;
 
   return retval;
 }
 
+/* A subroutine of emit_block_move.  Returns true if calling the 
+   block move libcall will not clobber any parameters which may have
+   already been placed on the stack.  */
+
+static bool
+block_move_libcall_safe_for_call_parm ()
+{
+  if (PUSH_ARGS)
+    return true;
+  else
+    {
+      /* Check to see whether memcpy takes all register arguments.  */
+      static enum {
+       takes_regs_uninit, takes_regs_no, takes_regs_yes
+      } takes_regs = takes_regs_uninit;
+
+      switch (takes_regs)
+       {
+       case takes_regs_uninit:
+         {
+           CUMULATIVE_ARGS args_so_far;
+           tree fn, arg;
+
+           fn = emit_block_move_libcall_fn (false);
+           INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0);
+
+           arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
+           for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
+             {
+               enum machine_mode mode
+                 = TYPE_MODE (TREE_TYPE (TREE_VALUE (arg)));
+               rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
+               if (!tmp || !REG_P (tmp))
+                 goto fail_takes_regs;
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+               if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
+                                               NULL_TREE, 1))
+                 goto fail_takes_regs;
+#endif
+               FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
+             }
+         }
+         takes_regs = takes_regs_yes;
+         /* FALLTHRU */
+
+       case takes_regs_yes:
+         return true;
+
+       fail_takes_regs:
+         takes_regs = takes_regs_no;
+         /* FALLTHRU */
+       case takes_regs_no:
+         return false;
+
+       default:
+         abort ();
+       }
+    }
+}
+
 /* A subroutine of emit_block_move.  Expand a movstr pattern; 
    return true if successful.  */
 
@@ -1919,6 +2013,59 @@ emit_block_move_libcall_fn (for_call)
 
   return fn;
 }
+
+/* A subroutine of emit_block_move.  Copy the data via an explicit
+   loop.  This is used only when libcalls are forbidden.  */
+/* ??? It'd be nice to copy in hunks larger than QImode.  */
+
+static void
+emit_block_move_via_loop (x, y, size, align)
+     rtx x, y, size;
+     unsigned int align ATTRIBUTE_UNUSED;
+{
+  rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
+  enum machine_mode iter_mode;
+
+  iter_mode = GET_MODE (size);
+  if (iter_mode == VOIDmode)
+    iter_mode = word_mode;
+
+  top_label = gen_label_rtx ();
+  cmp_label = gen_label_rtx ();
+  iter = gen_reg_rtx (iter_mode);
+
+  emit_move_insn (iter, const0_rtx);
+
+  x_addr = force_operand (XEXP (x, 0), NULL_RTX);
+  y_addr = force_operand (XEXP (y, 0), NULL_RTX);
+  do_pending_stack_adjust ();
+
+  emit_note (NULL, NOTE_INSN_LOOP_BEG);
+
+  emit_jump (cmp_label);
+  emit_label (top_label);
+
+  tmp = convert_modes (Pmode, iter_mode, iter, true);
+  x_addr = gen_rtx_PLUS (Pmode, x_addr, tmp);
+  y_addr = gen_rtx_PLUS (Pmode, y_addr, tmp);
+  x = change_address (x, QImode, x_addr);
+  y = change_address (y, QImode, y_addr);
+
+  emit_move_insn (x, y);
+
+  tmp = expand_simple_binop (iter_mode, PLUS, iter, const1_rtx, iter,
+                            true, OPTAB_LIB_WIDEN);
+  if (tmp != iter)
+    emit_move_insn (iter, tmp);
+
+  emit_note (NULL, NOTE_INSN_LOOP_CONT);
+  emit_label (cmp_label);
+
+  emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
+                          true, top_label);
+
+  emit_note (NULL, NOTE_INSN_LOOP_END);
+}
 \f
 /* Copy all or part of a value X into registers starting at REGNO.
    The number of registers to be filled is NREGS.  */
@@ -3623,16 +3770,12 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                 of sibling calls.  */
              set_mem_alias_set (target, 0);
            }
-         else
-           set_mem_align (target, align);
-
-         /* Make inhibit_defer_pop nonzero around the library call
-            to force it to pop the bcopy-arguments right away.  */
-         NO_DEFER_POP;
 
-         emit_block_move (target, xinner, size);
+         /* ALIGN may well be better aligned than TYPE, e.g. due to
+            PARM_BOUNDARY.  Assume the caller isn't lying.  */
+         set_mem_align (target, align);
 
-         OK_DEFER_POP;
+         emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
        }
     }
   else if (partial > 0)
@@ -3951,7 +4094,7 @@ expand_assignment (to, from, want_value, suggest_reg)
       if (GET_CODE (to_rtx) == PARALLEL)
        emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
       else if (GET_MODE (to_rtx) == BLKmode)
-       emit_block_move (to_rtx, value, expr_size (from));
+       emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
       else
        {
 #ifdef POINTERS_EXTEND_UNSIGNED
@@ -4312,7 +4455,7 @@ store_expr (exp, target, want_value)
 
          if (GET_CODE (size) == CONST_INT
              && INTVAL (size) < TREE_STRING_LENGTH (exp))
-           emit_block_move (target, temp, size);
+           emit_block_move (target, temp, size, BLOCK_OP_NORMAL);
          else
            {
              /* Compute the size of the data to copy from the string.  */
@@ -4326,7 +4469,7 @@ store_expr (exp, target, want_value)
 
              /* Copy that much.  */
              copy_size_rtx = convert_to_mode (ptr_mode, copy_size_rtx, 0);
-             emit_block_move (target, temp, copy_size_rtx);
+             emit_block_move (target, temp, copy_size_rtx, BLOCK_OP_NORMAL);
 
              /* Figure out how much is left in TARGET that we have to clear.
                 Do all calculations in ptr_mode.  */
@@ -4367,7 +4510,7 @@ store_expr (exp, target, want_value)
       else if (GET_CODE (target) == PARALLEL)
        emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
       else if (GET_MODE (temp) == BLKmode)
-       emit_block_move (target, temp, expr_size (exp));
+       emit_block_move (target, temp, expr_size (exp), BLOCK_OP_NORMAL);
       else
        emit_move_insn (target, temp);
     }
@@ -5295,7 +5438,8 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
          target = adjust_address (target, VOIDmode, bitpos / BITS_PER_UNIT);
          emit_block_move (target, temp,
                           GEN_INT ((bitsize + BITS_PER_UNIT - 1)
-                                   / BITS_PER_UNIT));
+                                   / BITS_PER_UNIT),
+                          BLOCK_OP_NORMAL);
 
          return value_mode == VOIDmode ? const0_rtx : target;
        }
@@ -7218,7 +7362,8 @@ expand_expr (exp, target, tmode, modifier)
 
                emit_block_move (target, op0,
                                 GEN_INT ((bitsize + BITS_PER_UNIT - 1)
-                                         / BITS_PER_UNIT));
+                                         / BITS_PER_UNIT),
+                                BLOCK_OP_NORMAL);
 
                return target;
              }
@@ -7634,7 +7779,8 @@ expand_expr (exp, target, tmode, modifier)
 
              if (GET_MODE (op0) == BLKmode)
                emit_block_move (new_with_op0_mode, op0,
-                                GEN_INT (GET_MODE_SIZE (TYPE_MODE (type))));
+                                GEN_INT (GET_MODE_SIZE (TYPE_MODE (type))),
+                                BLOCK_OP_NORMAL);
              else
                emit_move_insn (new_with_op0_mode, op0);
 
@@ -8856,7 +9002,8 @@ expand_expr (exp, target, tmode, modifier)
              if (TYPE_ALIGN_OK (inner_type))
                abort ();
 
-             emit_block_move (new, op0, expr_size (TREE_OPERAND (exp, 0)));
+             emit_block_move (new, op0, expr_size (TREE_OPERAND (exp, 0)),
+                              BLOCK_OP_NORMAL);
              op0 = new;
            }
 
index 76b5c809e8e93499f726506c52f596a5e3ba4983..c3a1009a12a7be2f27689013c3a55f766574440e 100644 (file)
@@ -394,7 +394,15 @@ extern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode,
                                  rtx, int));
 
 /* Emit code to move a block Y to a block X.  */
-extern rtx emit_block_move PARAMS ((rtx, rtx, rtx));
+
+enum block_op_methods
+{
+  BLOCK_OP_NORMAL,
+  BLOCK_OP_CALL_PARM,
+  BLOCK_OP_NO_LIBCALL
+};
+
+extern rtx emit_block_move PARAMS ((rtx, rtx, rtx, enum block_op_methods));
 
 /* Copy all or part of a value X into registers starting at REGNO.
    The number of registers to be filled is NREGS.  */
index 5d5300192fedbb8d1f951106bcaa141926390bf6..f1381fb935148744f8549618256d21f82f920d9b 100644 (file)
@@ -6807,7 +6807,7 @@ expand_function_end (filename, line, end_bindings)
 #ifdef TRAMPOLINE_TEMPLATE
       blktramp = replace_equiv_address (initial_trampoline, tramp);
       emit_block_move (blktramp, initial_trampoline,
-                      GEN_INT (TRAMPOLINE_SIZE));
+                      GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
 #endif
       INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
       seq = get_insns ();