builtins.c: (expand_builtin_memset): Rewrite to support 'set_storage_via_setmem'.

2006-06-28  Adrian Straetling  <straetling@de.ibm.com>

	* builtins.c: (expand_builtin_memset): Rewrite to support
	'set_storage_via_setmem'.
	* expr.c: (enum insn_code setmem_optab): Define.
	(enum insn_code clrmem_optab): Remove.
	(set_storage_via_setmem): New function.
	(clear_storage_via_setmem): Remove.
	(clear_storage): Replace call to "clear_storage_via_clrmem" with
	"set_storage_via_setmem".
	* expr.h: (set_storage_via_setmem): Declare.
	(CLEAR_RATIO): Redefine using HAVE_setmemM.
	* optabs.h: (enum insn_code setmem_optab): Declare.
	(enum insn_code clrmem_optab): Remove.
	* optabs.c: (init_optabs): Initialize setmem_optab.
	(enum insn_code clrmem_optab): Remove.
	* genopinit.c: (otabs): Likewise.
	* doc/md.texi: Document new standard pattern 'setmem'. Remove
	  'clrmem'.
	* config/alpha/alpha.c: (alpha_expand_block_clear): Adjust
	'operands' ordering.
	* config/frv/frv.c: (frv_expand_block_clear): Likewise.
	* config/rs6000/rs6000.c: (expand_block_clear): Likewise.
	* config/alpha/alpha.md: ("clrmemqi", "clrmemdi"): Rename to "setmemM".
	FAIL on operands[2]!=const0_rtx. Adjust 'operands' ordering.
	* config/avr/avr.md: ("clrmemhi"): Likewise.
	* config/frv/frv.md: ("clrmemsi"): Likewise.
	* config/i386/i386.md: ("clrmemsi", "clrmemdi"): Likewise.
	* config/pa/pa.md: ("clrmemsi", "clrmemdi"): Likewise.
	* config/rs6000/rs6000.md: ("clrmemsi"): Likewise.
	* config/s390/s390.md: ("clrmem<mode>"): Likewise.

From-SVN: r101386
This commit is contained in:
Adrian Straetling 2005-06-28 19:56:23 +00:00 committed by Ulrich Weigand
parent 617a1b7144
commit 57e84f1840
18 changed files with 237 additions and 153 deletions

View File

@ -1,3 +1,35 @@
2006-06-28 Adrian Straetling <straetling@de.ibm.com>
* builtins.c: (expand_builtin_memset): Rewrite to support
'set_storage_via_setmem'.
* expr.c: (enum insn_code setmem_optab): Define.
(enum insn_code clrmem_optab): Remove.
(set_storage_via_setmem): New function.
(clear_storage_via_setmem): Remove.
(clear_storage): Replace call to "clear_storage_via_clrmem" with
"set_storage_via_setmem".
* expr.h: (set_storage_via_setmem): Declare.
(CLEAR_RATIO): Redefine using HAVE_setmemM.
* optabs.h: (enum insn_code setmem_optab): Declare.
(enum insn_code clrmem_optab): Remove.
* optabs.c: (init_optabs): Initialize setmem_optab.
(enum insn_code clrmem_optab): Remove.
* genopinit.c: (otabs): Likewise.
* doc/md.texi: Document new standard pattern 'setmem'. Remove
'clrmem'.
* config/alpha/alpha.c: (alpha_expand_block_clear): Adjust
'operands' ordering.
* config/frv/frv.c: (frv_expand_block_clear): Likewise.
* config/rs6000/rs6000.c: (expand_block_clear): Likewise.
* config/alpha/alpha.md: ("clrmemqi", "clrmemdi"): Rename to "setmemM".
FAIL on operands[2]!=const0_rtx. Adjust 'operands' ordering.
* config/avr/avr.md: ("clrmemhi"): Likewise.
* config/frv/frv.md: ("clrmemsi"): Likewise.
* config/i386/i386.md: ("clrmemsi", "clrmemdi"): Likewise.
* config/pa/pa.md: ("clrmemsi", "clrmemdi"): Likewise.
* config/rs6000/rs6000.md: ("clrmemsi"): Likewise.
* config/s390/s390.md: ("clrmem<mode>"): Likewise.
2005-06-28 Paul Brook <paul@codesourcery.com>
* Makefile.in: Set and use UNWIND_H. Install as unwind.h.

View File

@ -3335,33 +3335,34 @@ expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
dest_mem = get_memory_rtx (dest);
if (TREE_CODE (val) != INTEGER_CST)
{
rtx val_rtx;
if (!host_integerp (len, 1))
return 0;
if (optimize_size && tree_low_cst (len, 1) > 1)
return 0;
val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
/* Assume that we can memset by pieces if we can store the
* the coefficients by pieces (in the required modes).
* We can't pass builtin_memset_gen_str as that emits RTL. */
c = 1;
if (!can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str,
&c, dest_align))
if (host_integerp (len, 1)
&& !(optimize_size && tree_low_cst (len, 1) > 1)
&& can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str, &c, dest_align))
{
val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
val_rtx);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_gen_str, val_rtx, dest_align, 0);
}
else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx,
dest_align))
return 0;
val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
val_rtx);
dest_mem = get_memory_rtx (dest);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_gen_str,
val_rtx, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
@ -3372,25 +3373,21 @@ expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
if (c)
{
if (!host_integerp (len, 1))
return 0;
if (!can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str, &c,
dest_align))
if (host_integerp (len, 1)
&& !(optimize_size && tree_low_cst (len, 1) > 1)
&& can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str, &c, dest_align))
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_read_str, &c, dest_align, 0);
else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
dest_align))
return 0;
dest_mem = get_memory_rtx (dest);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_read_str,
&c, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
}
len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
dest_mem = get_memory_rtx (dest);
set_mem_align (dest_mem, dest_align);
dest_addr = clear_storage (dest_mem, len_rtx,
CALL_EXPR_TAILCALL (orig_exp)

View File

@ -4069,7 +4069,7 @@ int
alpha_expand_block_clear (rtx operands[])
{
rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2];
rtx align_rtx = operands[3];
HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
HOST_WIDE_INT bytes = orig_bytes;
HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;

View File

@ -6552,25 +6552,29 @@
[(set_attr "type" "multi")
(set_attr "length" "28")])
(define_expand "clrmemqi"
(define_expand "setmemqi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(match_operand 2 "const_int_operand" ""))
(use (match_operand:DI 1 "immediate_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))])]
(use (match_operand:DI 3 "immediate_operand" ""))])]
""
{
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
if (alpha_expand_block_clear (operands))
DONE;
else
FAIL;
})
(define_expand "clrmemdi"
(define_expand "setmemdi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(match_operand 2 "const_int_operand" ""))
(use (match_operand:DI 1 "immediate_operand" ""))
(use (match_operand:DI 2 "immediate_operand" ""))
(use (match_dup 3))
(use (match_operand:DI 3 "immediate_operand" ""))
(use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
(clobber (reg:DI 17))
@ -6578,8 +6582,12 @@
(clobber (reg:DI 27))])]
"TARGET_ABI_OPEN_VMS"
{
operands[3] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
alpha_need_linkage (XSTR (operands[3], 0), 0);
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
alpha_need_linkage (XSTR (operands[4], 0), 0);
})
(define_insn "*clrmemdi_1"

View File

@ -410,28 +410,32 @@
DONE;
}")
;; =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0 =0
;; memset (%0, 0, %1)
;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
;; memset (%0, %2, %1)
(define_expand "clrmemhi"
(define_expand "setmemhi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(match_operand 2 "const_int_operand" ""))
(use (match_operand:HI 1 "const_int_operand" ""))
(use (match_operand:HI 2 "const_int_operand" "n"))
(clobber (match_scratch:HI 3 ""))
(clobber (match_dup 4))])]
(use (match_operand:HI 3 "const_int_operand" "n"))
(clobber (match_scratch:HI 4 ""))
(clobber (match_dup 5))])]
""
"{
rtx addr0;
int cnt8;
enum machine_mode mode;
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
mode = cnt8 ? QImode : HImode;
operands[4] = gen_rtx_SCRATCH (mode);
operands[5] = gen_rtx_SCRATCH (mode);
operands[1] = copy_to_mode_reg (mode,
gen_int_mode (INTVAL (operands[1]), mode));
addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));

View File

@ -2298,14 +2298,14 @@ frv_expand_block_move (rtx operands[])
operands[0] is the destination
operands[1] is the length
operands[2] is the alignment */
operands[3] is the alignment */
int
frv_expand_block_clear (rtx operands[])
{
rtx orig_dest = operands[0];
rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2];
rtx align_rtx = operands[3];
int constp = (GET_CODE (bytes_rtx) == CONST_INT);
int align;
int bytes;

View File

@ -2139,19 +2139,24 @@
FAIL;
}")
;; String/block clear insn.
;; String/block set insn.
;; Argument 0 is the destination
;; Argument 1 is the length
;; Argument 2 is the alignment
;; Argument 2 is the byte value -- ignore any value but zero
;; Argument 3 is the alignment
(define_expand "clrmemsi"
(define_expand "setmemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0))
(match_operand 2 "" ""))
(use (match_operand:SI 1 "" ""))
(use (match_operand:SI 2 "" ""))])]
(use (match_operand:SI 3 "" ""))])]
""
"
{
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
if (frv_expand_block_clear (operands))
DONE;
else

View File

@ -17182,25 +17182,35 @@
(set_attr "memory" "both")
(set_attr "mode" "SI")])
(define_expand "clrmemsi"
(define_expand "setmemsi"
[(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:SI 1 "nonmemory_operand" ""))
(use (match_operand 2 "const_int_operand" ""))]
(use (match_operand 2 "const_int_operand" ""))
(use (match_operand 3 "const_int_operand" ""))]
""
{
if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
DONE;
else
FAIL;
})
(define_expand "clrmemdi"
(define_expand "setmemdi"
[(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:DI 1 "nonmemory_operand" ""))
(use (match_operand 2 "const_int_operand" ""))]
(use (match_operand 2 "const_int_operand" ""))
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_64BIT"
{
if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
DONE;
else
FAIL;

View File

@ -3518,24 +3518,28 @@
"* return output_block_move (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
(define_expand "clrmemsi"
(define_expand "setmemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0))
(clobber (match_dup 3))
(match_operand 2 "const_int_operand" ""))
(clobber (match_dup 4))
(clobber (match_dup 5))
(use (match_operand:SI 1 "arith_operand" ""))
(use (match_operand:SI 2 "const_int_operand" ""))])]
(use (match_operand:SI 3 "const_int_operand" ""))])]
"!TARGET_64BIT && optimize > 0"
"
{
int size, align;
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
/* Undetermined size, use the library routine. */
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
size = INTVAL (operands[1]);
align = INTVAL (operands[2]);
align = INTVAL (operands[3]);
align = align > 4 ? 4 : align;
/* If size/alignment is large, then use the library routines. */
@ -3550,8 +3554,8 @@
operands[0]
= replace_equiv_address (operands[0],
copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
operands[3] = gen_reg_rtx (SImode);
operands[4] = gen_reg_rtx (SImode);
operands[5] = gen_reg_rtx (SImode);
}")
(define_insn "clrmemsi_prereload"
@ -3628,24 +3632,28 @@
"* return output_block_clear (operands, !which_alternative);"
[(set_attr "type" "multi,multi")])
(define_expand "clrmemdi"
(define_expand "setmemdi"
[(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0))
(clobber (match_dup 3))
(match_operand 2 "const_int_operand" ""))
(clobber (match_dup 4))
(clobber (match_dup 5))
(use (match_operand:DI 1 "arith_operand" ""))
(use (match_operand:DI 2 "const_int_operand" ""))])]
(use (match_operand:DI 3 "const_int_operand" ""))])]
"TARGET_64BIT && optimize > 0"
"
{
int size, align;
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
/* Undetermined size, use the library routine. */
if (GET_CODE (operands[1]) != CONST_INT)
FAIL;
size = INTVAL (operands[1]);
align = INTVAL (operands[2]);
align = INTVAL (operands[3]);
align = align > 8 ? 8 : align;
/* If size/alignment is large, then use the library routines. */
@ -3660,8 +3668,8 @@
operands[0]
= replace_equiv_address (operands[0],
copy_to_mode_reg (DImode, XEXP (operands[0], 0)));
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_reg_rtx (DImode);
operands[5] = gen_reg_rtx (DImode);
}")
(define_insn "clrmemdi_prereload"

View File

@ -8588,14 +8588,14 @@ rs6000_init_libfuncs (void)
operands[0] is the destination
operands[1] is the length
operands[2] is the alignment */
operands[3] is the alignment */
int
expand_block_clear (rtx operands[])
{
rtx orig_dest = operands[0];
rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2];
rtx align_rtx = operands[3];
bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
HOST_WIDE_INT align;
HOST_WIDE_INT bytes;

View File

@ -8613,14 +8613,18 @@
"{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")])
(define_expand "clrmemsi"
(define_expand "setmemsi"
[(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0))
(match_operand 2 "const_int_operand" "" ""))
(use (match_operand:SI 1 "" ""))
(use (match_operand:SI 2 "" ""))])]
(use (match_operand:SI 3 "" ""))])]
""
"
{
/* If value to set is not zero, use the library routine. */
if (operand[2] != const0_rtx)
FAIL;
if (expand_block_clear (operands))
DONE;
else

View File

@ -1919,16 +1919,23 @@
(set_attr "type" "vs")])
;
; clrmemM instruction pattern(s).
; setmemM instruction pattern(s).
;
(define_expand "clrmem<mode>"
(define_expand "setmem<mode>"
[(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
(match_operand 2 "const_int_operand" ""))
(use (match_operand:GPR 1 "general_operand" ""))
(match_operand 2 "" "")]
(match_operand 3 "" "")]
""
"s390_expand_clrmem (operands[0], operands[1]); DONE;")
{
/* If value to set is not zero, use the library routine. */
if (operands[2] != const0_rtx)
FAIL;
s390_expand_clrmem (operands[0], operands[1]);
DONE;
})
; Clear a block that is up to 256 bytes in length.
; The block length is taken as (operands[1] % 256) + 1.

View File

@ -3253,19 +3253,21 @@ destination and source strings are operands 1 and 2, and both are
the expansion of this pattern should store in operand 0 the address in
which the @code{NUL} terminator was stored in the destination string.
@cindex @code{clrmem@var{m}} instruction pattern
@item @samp{clrmem@var{m}}
Block clear instruction. The destination string is the first operand,
@cindex @code{setmem@var{m}} instruction pattern
@item @samp{setmem@var{m}}
Block set instruction. The destination string is the first operand,
given as a @code{mem:BLK} whose address is in mode @code{Pmode}. The
number of bytes to clear is the second operand, in mode @var{m}. See
number of bytes to set is the second operand, in mode @var{m}. The value to
initialize the memory with is the third operand. Targets that only support the
clearing of memory should reject any value that is not the constant 0. See
@samp{movmem@var{m}} for a discussion of the choice of mode.
The third operand is the known alignment of the destination, in the form
The fourth operand is the known alignment of the destination, in the form
of a @code{const_int} rtx. Thus, if the compiler knows that the
destination is word-aligned, it may provide the value 4 for this
operand.
The use for multiple @code{clrmem@var{m}} is as for @code{movmem@var{m}}.
The use for multiple @code{setmem@var{m}} is as for @code{movmem@var{m}}.
@cindex @code{cmpstr@var{m}} instruction pattern
@item @samp{cmpstr@var{m}}

View File

@ -134,7 +134,6 @@ static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
static void store_by_pieces_1 (struct store_by_pieces *, unsigned int);
static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
struct store_by_pieces *);
static bool clear_storage_via_clrmem (rtx, rtx, unsigned);
static rtx clear_storage_via_libcall (rtx, rtx, bool);
static tree clear_storage_libcall_fn (int);
static rtx compress_float_constant (rtx, rtx);
@ -200,8 +199,8 @@ static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block moves. */
enum insn_code movmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */
enum insn_code clrmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block sets. */
enum insn_code setmem_optab[NUM_MACHINE_MODES];
/* These arrays record the insn_code of two different kinds of insns
to perform block compares. */
@ -2478,7 +2477,7 @@ clear_storage (rtx object, rtx size, enum block_op_methods method)
if (GET_CODE (size) == CONST_INT
&& CLEAR_BY_PIECES_P (INTVAL (size), align))
clear_by_pieces (object, INTVAL (size), align);
else if (clear_storage_via_clrmem (object, size, align))
else if (set_storage_via_setmem (object, size, const0_rtx, align))
;
else
return clear_storage_via_libcall (object, size,
@ -2487,62 +2486,6 @@ clear_storage (rtx object, rtx size, enum block_op_methods method)
return NULL;
}
/* A subroutine of clear_storage. Expand a clrmem pattern;
return true if successful. */
static bool
clear_storage_via_clrmem (rtx object, rtx size, unsigned int align)
{
/* Try the most limited insn first, because there's no point
including more than one in the machine description unless
the more limited one has some advantage. */
rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
enum insn_code code = clrmem_optab[(int) mode];
insn_operand_predicate_fn pred;
if (code != CODE_FOR_nothing
/* We don't need MODE to be narrower than
BITS_PER_HOST_WIDE_INT here because if SIZE is less than
the mode mask, as it is returned by the macro, it will
definitely be less than the actual mode mask. */
&& ((GET_CODE (size) == CONST_INT
&& ((unsigned HOST_WIDE_INT) INTVAL (size)
<= (GET_MODE_MASK (mode) >> 1)))
|| GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
&& ((pred = insn_data[(int) code].operand[0].predicate) == 0
|| (*pred) (object, BLKmode))
&& ((pred = insn_data[(int) code].operand[2].predicate) == 0
|| (*pred) (opalign, VOIDmode)))
{
rtx op1;
rtx last = get_last_insn ();
rtx pat;
op1 = convert_to_mode (mode, size, 1);
pred = insn_data[(int) code].operand[1].predicate;
if (pred != 0 && ! (*pred) (op1, mode))
op1 = copy_to_mode_reg (mode, op1);
pat = GEN_FCN ((int) code) (object, op1, opalign);
if (pat)
{
emit_insn (pat);
return true;
}
else
delete_insns_since (last);
}
}
return false;
}
/* A subroutine of clear_storage. Expand a call to memset.
Return the return value of memset, 0 otherwise. */
@ -2635,6 +2578,67 @@ clear_storage_libcall_fn (int for_call)
return block_clear_fn;
}
/* Expand a setmem pattern; return true if successful. */
bool
set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align)
{
/* Try the most limited insn first, because there's no point
including more than one in the machine description unless
the more limited one has some advantage. */
rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
enum insn_code code = setmem_optab[(int) mode];
insn_operand_predicate_fn pred;
if (code != CODE_FOR_nothing
/* We don't need MODE to be narrower than
BITS_PER_HOST_WIDE_INT here because if SIZE is less than
the mode mask, as it is returned by the macro, it will
definitely be less than the actual mode mask. */
&& ((GET_CODE (size) == CONST_INT
&& ((unsigned HOST_WIDE_INT) INTVAL (size)
<= (GET_MODE_MASK (mode) >> 1)))
|| GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)
&& ((pred = insn_data[(int) code].operand[0].predicate) == 0
|| (*pred) (object, BLKmode))
&& ((pred = insn_data[(int) code].operand[3].predicate) == 0
|| (*pred) (opalign, VOIDmode)))
{
rtx opsize,opchar;
rtx last = get_last_insn ();
rtx pat;
opsize = convert_to_mode (mode, size, 1);
pred = insn_data[(int) code].operand[1].predicate;
if (pred != 0 && ! (*pred) (opsize, mode))
opsize = copy_to_mode_reg (mode, opsize);
opchar = convert_to_mode (mode, val, 1);
pred = insn_data[(int) code].operand[2].predicate;
if (pred != 0 && ! (*pred) (opchar, mode))
opchar = copy_to_mode_reg (mode, opchar);
pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign);
if (pat)
{
emit_insn (pat);
return true;
}
else
delete_insns_since (last);
}
}
return false;
}
/* Write to one of the components of the complex value CPLX. Write VAL to
the real part if IMAG_P is false, and the imaginary part if its true. */

View File

@ -75,10 +75,10 @@ enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM,
#endif
/* If a clear memory operation would take CLEAR_RATIO or more simple
move-instruction sequences, we will do a clrmem or libcall instead. */
move-instruction sequences, we will do a setmem or libcall instead. */
#ifndef CLEAR_RATIO
#if defined (HAVE_clrmemqi) || defined (HAVE_clrmemhi) || defined (HAVE_clrmemsi) || defined (HAVE_clrmemdi) || defined (HAVE_clrmemti)
#if defined (HAVE_setmemqi) || defined (HAVE_setmemhi) || defined (HAVE_setmemsi) || defined (HAVE_setmemdi) || defined (HAVE_setmemti)
#define CLEAR_RATIO 2
#else
/* If we are optimizing for space, cut down the default clear ratio. */
@ -423,6 +423,9 @@ extern void use_group_regs (rtx *, rtx);
If OBJECT has BLKmode, SIZE is its length in bytes. */
extern rtx clear_storage (rtx, rtx, enum block_op_methods);
/* Expand a setmem pattern; return true if successful. */
extern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int);
/* Determine whether the LEN bytes can be moved by using several move
instructions. Return nonzero if a call to move_by_pieces should
succeed. */

View File

@ -168,9 +168,9 @@ static const char * const optabs[] =
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
"movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
"clrmem_optab[$A] = CODE_FOR_$(clrmem$a$)",
"cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
"cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
"setmem_optab[$A] = CODE_FOR_$(setmem$a$)",
"sync_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
"sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)",
"sync_ior_optab[$A] = CODE_FOR_$(sync_ior$I$a$)",

View File

@ -5162,9 +5162,9 @@ init_optabs (void)
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
movmem_optab[i] = CODE_FOR_nothing;
clrmem_optab[i] = CODE_FOR_nothing;
cmpstr_optab[i] = CODE_FOR_nothing;
cmpmem_optab[i] = CODE_FOR_nothing;
setmem_optab[i] = CODE_FOR_nothing;
sync_add_optab[i] = CODE_FOR_nothing;
sync_sub_optab[i] = CODE_FOR_nothing;

View File

@ -444,8 +444,8 @@ extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block moves. */
extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */
extern enum insn_code clrmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block sets. */
extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
/* These arrays record the insn_code of two different kinds of insns
to perform block compares. */