aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAdrian Straetling <straetling@de.ibm.com>2005-06-28 19:56:23 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2005-06-28 19:56:23 +0000
commit57e84f1840c3da2c5c73d5c2f81a9b922957a27b (patch)
tree1c07634d50dcd55dcccb73af6219e12082ada423 /gcc
parent617a1b714435a270ccf699c4c6e17767088e2242 (diff)
downloadgcc-57e84f1840c3da2c5c73d5c2f81a9b922957a27b.zip
gcc-57e84f1840c3da2c5c73d5c2f81a9b922957a27b.tar.gz
gcc-57e84f1840c3da2c5c73d5c2f81a9b922957a27b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog32
-rw-r--r--gcc/builtins.c53
-rw-r--r--gcc/config/alpha/alpha.c2
-rw-r--r--gcc/config/alpha/alpha.md26
-rw-r--r--gcc/config/avr/avr.md20
-rw-r--r--gcc/config/frv/frv.c4
-rw-r--r--gcc/config/frv/frv.md15
-rw-r--r--gcc/config/i386/i386.md22
-rw-r--r--gcc/config/pa/pa.md32
-rw-r--r--gcc/config/rs6000/rs6000.c4
-rw-r--r--gcc/config/rs6000/rs6000.md10
-rw-r--r--gcc/config/s390/s390.md17
-rw-r--r--gcc/doc/md.texi14
-rw-r--r--gcc/expr.c124
-rw-r--r--gcc/expr.h7
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/optabs.c2
-rw-r--r--gcc/optabs.h4
18 files changed, 237 insertions, 153 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 81a3106..225451d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 313170b..f308f53 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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)
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 8ca3d60..daba49d4 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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;
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 0b32f11..157e8ca 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -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"
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 6632ae9..59d35f0 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -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));
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index a1b71ae..67bb11e 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -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;
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index 4df63c8..b8c37c5 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 7d08873..84be8f9 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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;
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 17ffc08..de5b75b 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -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"
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bd78eca..5bc8ccf 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 92eec48..9cde35a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -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
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 826261d..8a3e1a4 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -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.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index ed07a2f..a44c34c 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -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}}
diff --git a/gcc/expr.c b/gcc/expr.c
index 1f6d8fb..b9bba08 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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. */
@@ -2636,6 +2579,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. */
diff --git a/gcc/expr.h b/gcc/expr.h
index ec6dd80..31c43c0 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -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. */
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 2c74bedd..409ed08 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -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$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 6f5716e..2ed499e 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -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;
diff --git a/gcc/optabs.h b/gcc/optabs.h
index c3644be..bba0a5c 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -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. */