emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp));
else
{
- lab = copy_to_reg (lab);
-
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
+ lab = copy_to_reg (lab);
+
/* Restore the frame pointer and stack pointer. We must use a
temporary since the setjmp buffer may be a local. */
fp = copy_to_reg (fp);
emit_stack_restore (SAVE_NONLOCAL, stack);
+
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_use (hard_frame_pointer_rtx);
emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
else
{
- r_label = copy_to_reg (r_label);
-
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
+ r_label = copy_to_reg (r_label);
+
/* Restore the frame pointer and stack pointer. We must use a
temporary since the setjmp buffer may be a local. */
r_fp = copy_to_reg (r_fp);
emit_stack_restore (SAVE_NONLOCAL, r_sp);
+
+ /* Ensure the frame pointer move is not optimized. */
+ emit_insn (gen_blockage ());
+ emit_clobber (hard_frame_pointer_rtx);
+ emit_clobber (frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, r_fp);
/* USE of hard_frame_pointer_rtx added for consistency;
unsigned HOST_WIDE_INT max_size;
unsigned HOST_WIDE_INT probable_max_size;
+ bool is_move_done;
+
/* If DEST is not a pointer type, call the normal function. */
if (dest_align == 0)
return NULL_RTX;
if (CALL_EXPR_TAILCALL (exp)
&& (retmode == RETURN_BEGIN || target == const0_rtx))
method = BLOCK_OP_TAILCALL;
- if (retmode == RETURN_END && target != const0_rtx)
+ bool use_mempcpy_call = (targetm.libc_has_fast_function (BUILT_IN_MEMPCPY)
+ && retmode == RETURN_END
+ && target != const0_rtx);
+ if (use_mempcpy_call)
method = BLOCK_OP_NO_LIBCALL_RET;
dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx, method,
expected_align, expected_size,
- min_size, max_size, probable_max_size);
+ min_size, max_size, probable_max_size,
+ use_mempcpy_call, &is_move_done);
+
+ /* Bail out when a mempcpy call would be expanded as libcall and when
+ we have a target that provides a fast implementation
+ of mempcpy routine. */
+ if (!is_move_done)
+ return NULL_RTX;
+
if (dest_addr == pc_rtx)
return NULL_RTX;
if (TREE_CODE (arg0) != INTEGER_CST)
{
- error ("non-constant argument 1 to __atomic_always_lock_free");
+ error ("non-constant argument 1 to %qs", "__atomic_always_lock_free");
return const0_rtx;
}
if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
{
- error ("non-integer argument 1 to __atomic_is_lock_free");
+ error ("non-integer argument 1 to %qs", "__atomic_is_lock_free");
return NULL_RTX;
}
if (!stdarg_p (fntype))
{
- error ("%<va_start%> used in function with fixed args");
+ error ("%<va_start%> used in function with fixed arguments");
return true;
}