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> 2005-06-28 Paul Brook <paul@codesourcery.com>
* Makefile.in: Set and use UNWIND_H. Install as unwind.h. * 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); 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) if (TREE_CODE (val) != INTEGER_CST)
{ {
rtx val_rtx; rtx val_rtx;
if (!host_integerp (len, 1)) val = fold_build1 (CONVERT_EXPR, unsigned_char_type_node, val);
return 0; val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
if (optimize_size && tree_low_cst (len, 1) > 1)
return 0;
/* Assume that we can memset by pieces if we can store the /* Assume that we can memset by pieces if we can store the
* the coefficients by pieces (in the required modes). * the coefficients by pieces (in the required modes).
* We can't pass builtin_memset_gen_str as that emits RTL. */ * We can't pass builtin_memset_gen_str as that emits RTL. */
c = 1; c = 1;
if (!can_store_by_pieces (tree_low_cst (len, 1), if (host_integerp (len, 1)
builtin_memset_read_str, && !(optimize_size && tree_low_cst (len, 1) > 1)
&c, dest_align)) && 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; 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 = force_operand (XEXP (dest_mem, 0), NULL_RTX);
dest_mem = convert_memory_address (ptr_mode, dest_mem); dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem; return dest_mem;
@ -3372,25 +3373,21 @@ expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode,
if (c) if (c)
{ {
if (!host_integerp (len, 1)) if (host_integerp (len, 1)
return 0; && !(optimize_size && tree_low_cst (len, 1) > 1)
if (!can_store_by_pieces (tree_low_cst (len, 1), && can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str, &c, builtin_memset_read_str, &c, dest_align))
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; 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 = force_operand (XEXP (dest_mem, 0), NULL_RTX);
dest_mem = convert_memory_address (ptr_mode, dest_mem); dest_mem = convert_memory_address (ptr_mode, dest_mem);
return 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); set_mem_align (dest_mem, dest_align);
dest_addr = clear_storage (dest_mem, len_rtx, dest_addr = clear_storage (dest_mem, len_rtx,
CALL_EXPR_TAILCALL (orig_exp) CALL_EXPR_TAILCALL (orig_exp)

View File

@ -4069,7 +4069,7 @@ int
alpha_expand_block_clear (rtx operands[]) alpha_expand_block_clear (rtx operands[])
{ {
rtx bytes_rtx = operands[1]; 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 orig_bytes = INTVAL (bytes_rtx);
HOST_WIDE_INT bytes = orig_bytes; HOST_WIDE_INT bytes = orig_bytes;
HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT; HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;

View File

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

View File

@ -410,28 +410,32 @@
DONE; 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 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
;; memset (%0, 0, %1) ;; memset (%0, %2, %1)
(define_expand "clrmemhi" (define_expand "setmemhi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "") [(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 1 "const_int_operand" ""))
(use (match_operand:HI 2 "const_int_operand" "n")) (use (match_operand:HI 3 "const_int_operand" "n"))
(clobber (match_scratch:HI 3 "")) (clobber (match_scratch:HI 4 ""))
(clobber (match_dup 4))])] (clobber (match_dup 5))])]
"" ""
"{ "{
rtx addr0; rtx addr0;
int cnt8; int cnt8;
enum machine_mode mode; 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) if (GET_CODE (operands[1]) != CONST_INT)
FAIL; FAIL;
cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1])); cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
mode = cnt8 ? QImode : HImode; mode = cnt8 ? QImode : HImode;
operands[4] = gen_rtx_SCRATCH (mode); operands[5] = gen_rtx_SCRATCH (mode);
operands[1] = copy_to_mode_reg (mode, operands[1] = copy_to_mode_reg (mode,
gen_int_mode (INTVAL (operands[1]), mode)); gen_int_mode (INTVAL (operands[1]), mode));
addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 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[0] is the destination
operands[1] is the length operands[1] is the length
operands[2] is the alignment */ operands[3] is the alignment */
int int
frv_expand_block_clear (rtx operands[]) frv_expand_block_clear (rtx operands[])
{ {
rtx orig_dest = operands[0]; rtx orig_dest = operands[0];
rtx bytes_rtx = operands[1]; rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2]; rtx align_rtx = operands[3];
int constp = (GET_CODE (bytes_rtx) == CONST_INT); int constp = (GET_CODE (bytes_rtx) == CONST_INT);
int align; int align;
int bytes; int bytes;

View File

@ -2139,19 +2139,24 @@
FAIL; FAIL;
}") }")
;; String/block clear insn. ;; String/block set insn.
;; Argument 0 is the destination ;; Argument 0 is the destination
;; Argument 1 is the length ;; 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 "" "") [(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0)) (match_operand 2 "" ""))
(use (match_operand:SI 1 "" "")) (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)) if (frv_expand_block_clear (operands))
DONE; DONE;
else else

View File

@ -17182,25 +17182,35 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_expand "clrmemsi" (define_expand "setmemsi"
[(use (match_operand:BLK 0 "memory_operand" "")) [(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:SI 1 "nonmemory_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; DONE;
else else
FAIL; FAIL;
}) })
(define_expand "clrmemdi" (define_expand "setmemdi"
[(use (match_operand:BLK 0 "memory_operand" "")) [(use (match_operand:BLK 0 "memory_operand" ""))
(use (match_operand:DI 1 "nonmemory_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" "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; DONE;
else else
FAIL; FAIL;

View File

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

View File

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

View File

@ -8613,14 +8613,18 @@
"{stsi|stswi} %2,%1,%O0" "{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")]) [(set_attr "type" "store")])
(define_expand "clrmemsi" (define_expand "setmemsi"
[(parallel [(set (match_operand:BLK 0 "" "") [(parallel [(set (match_operand:BLK 0 "" "")
(const_int 0)) (match_operand 2 "const_int_operand" "" ""))
(use (match_operand:SI 1 "" "")) (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)) if (expand_block_clear (operands))
DONE; DONE;
else else

View File

@ -1919,16 +1919,23 @@
(set_attr "type" "vs")]) (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" "") [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0)) (match_operand 2 "const_int_operand" ""))
(use (match_operand:GPR 1 "general_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. ; Clear a block that is up to 256 bytes in length.
; The block length is taken as (operands[1] % 256) + 1. ; 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 the expansion of this pattern should store in operand 0 the address in
which the @code{NUL} terminator was stored in the destination string. which the @code{NUL} terminator was stored in the destination string.
@cindex @code{clrmem@var{m}} instruction pattern @cindex @code{setmem@var{m}} instruction pattern
@item @samp{clrmem@var{m}} @item @samp{setmem@var{m}}
Block clear instruction. The destination string is the first operand, Block set instruction. The destination string is the first operand,
given as a @code{mem:BLK} whose address is in mode @code{Pmode}. The 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. @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 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 destination is word-aligned, it may provide the value 4 for this
operand. 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 @cindex @code{cmpstr@var{m}} instruction pattern
@item @samp{cmpstr@var{m}} @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_1 (struct store_by_pieces *, unsigned int);
static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode, static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
struct store_by_pieces *); struct store_by_pieces *);
static bool clear_storage_via_clrmem (rtx, rtx, unsigned);
static rtx clear_storage_via_libcall (rtx, rtx, bool); static rtx clear_storage_via_libcall (rtx, rtx, bool);
static tree clear_storage_libcall_fn (int); static tree clear_storage_libcall_fn (int);
static rtx compress_float_constant (rtx, rtx); 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. */ /* This array records the insn_code of insns to perform block moves. */
enum insn_code movmem_optab[NUM_MACHINE_MODES]; enum insn_code movmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */ /* This array records the insn_code of insns to perform block sets. */
enum insn_code clrmem_optab[NUM_MACHINE_MODES]; enum insn_code setmem_optab[NUM_MACHINE_MODES];
/* These arrays record the insn_code of two different kinds of insns /* These arrays record the insn_code of two different kinds of insns
to perform block compares. */ 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 if (GET_CODE (size) == CONST_INT
&& CLEAR_BY_PIECES_P (INTVAL (size), align)) && CLEAR_BY_PIECES_P (INTVAL (size), align))
clear_by_pieces (object, 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 else
return clear_storage_via_libcall (object, size, return clear_storage_via_libcall (object, size,
@ -2487,62 +2486,6 @@ clear_storage (rtx object, rtx size, enum block_op_methods method)
return NULL; 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. /* A subroutine of clear_storage. Expand a call to memset.
Return the return value of memset, 0 otherwise. */ Return the return value of memset, 0 otherwise. */
@ -2635,6 +2578,67 @@ clear_storage_libcall_fn (int for_call)
return block_clear_fn; 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 /* 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. */ 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 #endif
/* If a clear memory operation would take CLEAR_RATIO or more simple /* 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 #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 #define CLEAR_RATIO 2
#else #else
/* If we are optimizing for space, cut down the default clear ratio. */ /* 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. */ If OBJECT has BLKmode, SIZE is its length in bytes. */
extern rtx clear_storage (rtx, rtx, enum block_op_methods); 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 /* Determine whether the LEN bytes can be moved by using several move
instructions. Return nonzero if a call to move_by_pieces should instructions. Return nonzero if a call to move_by_pieces should
succeed. */ succeed. */

View File

@ -168,9 +168,9 @@ static const char * const optabs[] =
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)", "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)", "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
"movmem_optab[$A] = CODE_FOR_$(movmem$a$)", "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
"clrmem_optab[$A] = CODE_FOR_$(clrmem$a$)",
"cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)", "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
"cmpmem_optab[$A] = CODE_FOR_$(cmpmem$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_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
"sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)", "sync_sub_optab[$A] = CODE_FOR_$(sync_sub$I$a$)",
"sync_ior_optab[$A] = CODE_FOR_$(sync_ior$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++) for (i = 0; i < NUM_MACHINE_MODES; i++)
{ {
movmem_optab[i] = CODE_FOR_nothing; movmem_optab[i] = CODE_FOR_nothing;
clrmem_optab[i] = CODE_FOR_nothing;
cmpstr_optab[i] = CODE_FOR_nothing; cmpstr_optab[i] = CODE_FOR_nothing;
cmpmem_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_add_optab[i] = CODE_FOR_nothing;
sync_sub_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. */ /* This array records the insn_code of insns to perform block moves. */
extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */ /* This array records the insn_code of insns to perform block sets. */
extern enum insn_code clrmem_optab[NUM_MACHINE_MODES]; extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
/* These arrays record the insn_code of two different kinds of insns /* These arrays record the insn_code of two different kinds of insns
to perform block compares. */ to perform block compares. */